浏览代码

Merge branch 'master' into 会员关联项目

Long 1 天之前
父节点
当前提交
441d7da626

+ 18 - 0
src/api/store/storeOrder.js

@@ -267,3 +267,21 @@ export function auditPayRemain(data) {
     data: data
   })
 }
+
+// 订单维度分页查询接口
+export function orderDimensionStatisticsList(query) {
+  return request({
+    url: '/store/storeOrder/orderDimensionStatisticsList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出订单维度统计接口
+export function orderDimensionStatisticsExport(query) {
+  return request({
+    url: '/store/storeOrder/orderDimensionStatisticsExport',
+    method: 'get',
+    params: query
+  })
+}

二进制
src/assets/images/liuliang.png


二进制
src/assets/images/member.png


二进制
src/assets/images/message.png


二进制
src/assets/images/salesperson.png


二进制
src/assets/images/tab_company.png


二进制
src/assets/images/tab_enterprise.png


二进制
src/assets/images/topbg.png


二进制
src/assets/images/zcgl_bg.png


+ 15 - 8
src/store/modules/settings.js

@@ -1,17 +1,19 @@
-import variables from '@/assets/styles/element-variables.scss'
 import defaultSettings from '@/settings'
 
-const { showSettings, tagsView,topNav, fixedHeader, sidebarLogo } = defaultSettings
+const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
 
+const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
 const state = {
-  theme: variables.theme,
+  title: '',
+  theme: storageSetting.theme || '#006CFF',
+  sideTheme: storageSetting.sideTheme || sideTheme,
   showSettings: showSettings,
-  tagsView: tagsView,
-  topNav: topNav,
-  fixedHeader: fixedHeader,
-  sidebarLogo: sidebarLogo
+  topNav:  storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
+  tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
+  fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
+  sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
+  dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
 }
-
 const mutations = {
   CHANGE_SETTING: (state, { key, value }) => {
     if (state.hasOwnProperty(key)) {
@@ -21,8 +23,13 @@ const mutations = {
 }
 
 const actions = {
+  // 修改布局设置
   changeSetting({ commit }, data) {
     commit('CHANGE_SETTING', data)
+  },
+  // 设置网页标题
+  setTitle({ commit }, title) {
+    state.title = title
   }
 }
 

+ 29 - 8
src/views/company/statistics/voiceLogs.vue

@@ -64,30 +64,51 @@
                         show-summary
                         max-height="500"
                         style="width: 100%;">
+                          <el-table-column
+                            align="center"
+                            prop="userId"
+                            label="序号">
+                          </el-table-column>
                         <el-table-column
+                          align="center"
                           prop="nickName"
                           label="员工姓名">
                         </el-table-column>
                         <el-table-column
-                          prop="callCount"
-                          label="拨打数">
+                          align="center"
+                          prop="callSuccessCount"
+                          label="接听电活数">
                         </el-table-column>
                         <el-table-column
-                          prop="callSuccessCount"
-                          label="接通数">
+                          align="center"
+                          prop="callSuccessItem"
+                          label="接听总时长(秒)">
                         </el-table-column>
+                          <el-table-column
+                            align="center"
+                            prop="callCount"
+                            label="外呼电话数">
+                          </el-table-column>
+                          <el-table-column
+                            align="center"
+                            prop="times"
+                            label="外呼通话时长(秒)">
+                          </el-table-column>
                         <el-table-column
+                          align="center"
                           prop="callRate"
                           label="接通率(%)">
                         </el-table-column>
                         <el-table-column
-                          prop="times"
-                          label="通话时长(秒)">
-                        </el-table-column>
-                        <el-table-column
+                          align="center"
                           prop="billingTime"
                           label="消耗分钟(分)">
                         </el-table-column>
+                          <el-table-column
+                            align="center"
+                            prop="amountItem"
+                            label="合计时长(秒)">
+                          </el-table-column>
                       </el-table>
                   </div>
               </div>

+ 136 - 222
src/views/course/courseTrafficLog/index.vue

@@ -1,313 +1,227 @@
 <template>
   <div class="app-container">
+    <!-- Tab 切换 -->
+    <el-tabs v-model="activeTab" @tab-click="handleTabClick">
+      <el-tab-pane label="公司" name="company"></el-tab-pane>
+      <el-tab-pane label="项目" name="project"></el-tab-pane>
+      <el-tab-pane label="课程" name="course"></el-tab-pane>
+    </el-tabs>
+
+    <!-- 查询条件 -->
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="公司名称" prop="companyId" >
-        <el-select v-model="queryParams.companyId" placeholder="请选择所属公司" filterable clearable size="small">
+      <!-- 公司选择 -->
+      <el-form-item label="公司" v-if="activeTab === 'all' || activeTab === 'company'">
+        <el-select v-model="queryParams.companyId" placeholder="请选择公司" filterable clearable size="small">
           <el-option v-for="(option, index) in companyList" :key="index" :value="option.dictValue" :label="option.dictLabel"></el-option>
         </el-select>
       </el-form-item>
-      <el-form-item label="项目" prop="project">
+
+      <!-- 项目选择 -->
+      <el-form-item label="项目" v-if="activeTab === 'all' || activeTab === 'project'">
         <el-select v-model="queryParams.project" placeholder="请选择项目" filterable clearable size="small">
-          <el-option
-            v-for="dict in projectOptions"
-            :key="dict.dictValue"
-            :label="dict.dictLabel"
-            :value="dict.dictValue"
-          />
+          <el-option v-for="dict in projectOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
         </el-select>
       </el-form-item>
-      <el-form-item label="课程" prop="courseId">
-        <el-select filterable  v-model="queryParams.courseId" placeholder="请选择课程"  clearable size="small" @change="courseChange(queryParams.courseId)">
-          <el-option
-            v-for="dict in courseLists"
-            :key="dict.dictValue"
-            :label="dict.dictLabel"
-            :value="dict.dictValue"
-          />
+
+      <!-- 课程选择 -->
+      <el-form-item label="课程" v-if="activeTab === 'all' || activeTab === 'course'">
+        <el-select v-model="queryParams.courseId" placeholder="请选择课程" filterable clearable size="small">
+          <el-option v-for="dict in courseLists" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
         </el-select>
       </el-form-item>
-      <el-form-item label="年月" prop="time">
+
+      <!-- 时间选择 -->
+      <el-form-item label="年月">
         <el-date-picker
-          v-model="time"
+          v-model="timeRange"
           type="daterange"
           placeholder="选择年月"
-          :picker-options="pickerOptions"
           :value-format="'yyyy-MM-dd'"
+          :picker-options="pickerOptions"
           @change="handleDateData"
         ></el-date-picker>
       </el-form-item>
+
+
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
       </el-form-item>
     </el-form>
 
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="el-icon-download"
-          size="mini"
-          :loading="exportLoading"
-          @click="handleExport"
-          v-hasPermi="['course:courseTrafficLog:export']"
-        >导出</el-button>
-      </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
-    </el-row>
-
+    <!-- 表格 -->
     <el-table border v-loading="loading" :data="courseTrafficLogList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="公司名称" align="center" prop="companyName" />
-      <el-table-column label="项目" align="center" prop="projectName" />
-      <el-table-column label="课程" align="center" prop="courseName" />
+      <!-- 公司列 -->
+      <el-table-column label="公司" align="center" prop="companyName" v-if="activeTab === 'all' || activeTab === 'company'" />
+      <!-- 项目列 -->
+      <el-table-column label="项目" align="center" prop="projectName" v-if="activeTab === 'all' || activeTab === 'project'" />
+      <!-- 课程列 -->
+      <el-table-column label="课程" align="center" prop="courseName" v-if="activeTab === 'all' || activeTab === 'course'" />
       <el-table-column label="日期" align="center" prop="month" />
       <el-table-column label="使用流量" align="center">
         <template slot-scope="scope">
           <span>{{ formatTrafficData(scope.row.totalInternetTraffic) }}</span>
         </template>
       </el-table-column>
-<!--      <el-table-column label="费用" align="center">-->
-<!--        <template slot-scope="scope">-->
-<!--          <span>{{ formatTrafficMoney(scope.row.totalInternetTraffic) }}</span>-->
-<!--        </template>-->
-<!--      </el-table-column>-->
     </el-table>
 
+    <!-- 分页 -->
     <pagination
-      v-show="total>0"
+      v-show="total > 0"
       :total="total"
       :page.sync="queryParams.pageNum"
       :limit.sync="queryParams.pageSize"
       @pagination="getList"
     />
-
   </div>
 </template>
 
 <script>
-import { listCourseTrafficLog, getCourseTrafficLog, delCourseTrafficLog, addCourseTrafficLog, updateCourseTrafficLog, exportCourseTrafficLog } from "@/api/course/courseTrafficLog";
-import {courseList} from "@/api/course/courseRedPacketLog";
-import {allList}from "@/api/company/company";
+import { listCourseTrafficLog, exportCourseTrafficLog } from "@/api/course/courseTrafficLog";
+import { courseList } from "@/api/course/courseRedPacketLog";
+import { allList } from "@/api/company/company";
+
 export default {
-  name: "CourseTrafficLog",
   data() {
     return {
+      activeTab: "company", // 默认 tab
+      timeRange: null, // 时间范围单独绑定
+      companyList: [],
+      projectOptions: [],
       pickerOptions: {
-        shortcuts: [{
-          text: '最近一周',
-          onClick(picker) {
-            const end = new Date();
-            const start = new Date();
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-            picker.$emit('pick', [start, end]);
+        shortcuts: [
+          {
+            text: '今日',
+            onClick(picker) {
+              const start = new Date();
+              const end = new Date();
+              picker.$emit('pick', [start, end]);
+            }
+          },
+          {
+            text: '昨日',
+            onClick(picker) {
+              const start = new Date();
+              start.setDate(start.getDate() - 1);
+              const end = new Date(start);
+              picker.$emit('pick', [start, end]);
+            }
+          },
+          {
+            text: '本周',
+            onClick(picker) {
+              const now = new Date();
+              const day = now.getDay() || 7;
+              const start = new Date(now);
+              start.setDate(now.getDate() - day + 1);
+              const end = new Date();
+              picker.$emit('pick', [start, end]);
+            }
+          },
+          {
+            text: '本月',
+            onClick(picker) {
+              const start = new Date(new Date().setDate(1));
+              const end = new Date();
+              picker.$emit('pick', [start, end]);
+            }
           }
-        }]
+        ]
       },
-      companyList:[],
-      // 遮罩层
+      courseLists: [],
       loading: false,
-      // 导出遮罩层
       exportLoading: false,
-      // 选中数组
-      ids: [],
-      // 非单个禁用
-      single: true,
-      // 非多个禁用
-      multiple: true,
-      // 显示搜索条件
       showSearch: true,
-      // 总条数
       total: 0,
-      // 短链课程流量记录表格数据
       courseTrafficLogList: [],
-      projectOptions:[],
-      courseLists:[],
-      // 弹出层标题
-      title: "",
-      // 是否显示弹出层
-      open: false,
-      time: null,
-      // 查询参数
       queryParams: {
+        tabType: "", // 当前 tab 类型
         startDate: null,
         endDate: null,
         pageNum: 1,
         pageSize: 10,
-        userId: null,
-        videoId: null,
-        qwExternalContactId: null,
-        internetTraffic: null,
-        qwUserId: null,
-        companyUserId: null,
         companyId: null,
-        courseId: null,
-      },
-      // 表单参数
-      form: {},
-      // 表单校验
-      rules: {
+        project: null,
+        courseId: null
       }
     };
   },
   created() {
-    courseList().then(response => {
-      this.courseLists = response.list;
-    });
-    this.getDicts("sys_course_project").then(response => {
-      this.projectOptions = response.data;
-    });
+    courseList().then(res => this.courseLists = res.list);
+    this.getDicts("sys_course_project").then(res => this.projectOptions = res.data);
     this.getAllCompany();
-
+    this.getList();
   },
   methods: {
-    handleDateData(){
-      if (this.time) {
-        this.queryParams.startDate = this.time[0];
-        this.queryParams.endDate = this.time[1];
+    handleTabClick(tab) {
+      this.queryParams.tabType = tab.name;
+      this.queryParams.pageNum = 1;
+
+      // 清理互斥参数
+      if (tab.name !== "project") this.queryParams.project = null;
+      if (tab.name !== "course") this.queryParams.courseId = null;
+      if (tab.name !== "company") this.queryParams.companyId = null;
+
+      this.getList();
+    },
+
+    handleDateData() {
+      if (this.timeRange) {
+        this.queryParams.startDate = this.timeRange[0];
+        this.queryParams.endDate = this.timeRange[1];
       } else {
         this.queryParams.startDate = null;
         this.queryParams.endDate = null;
       }
     },
     getAllCompany() {
-      allList().then(response => {
-        this.companyList = response.rows;
-      });
-    },
-    formatTrafficData(traffic) {
-
-        if (traffic < 1024) { // Less than 1 KB
-          return traffic + ' B';
-        } else if (traffic < 1024 * 1024) { // Less than 1 MB
-          return (traffic / 1024).toFixed(2) + ' KB';
-        } else if (traffic < 1024 * 1024 * 1024) { // Less than 1 GB
-          return (traffic / (1024 * 1024)).toFixed(2) + ' MB';
-        } else { // More than 1 GB
-          return (traffic / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
-        }
-
-    },
-    formatTrafficMoney(traffic){
-      return (traffic / (1024 * 1024 * 1024) * 0.095).toFixed(2) + ' 元'
+      allList().then(res => this.companyList = res.rows);
     },
-
-    handleShortcut() {
-      this.queryParams.time = new Date().toISOString().slice(0, 7);
-    },
-    /** 查询短链课程流量记录列表 */
     getList() {
       this.loading = true;
-      listCourseTrafficLog(this.queryParams).then(response => {
-        this.courseTrafficLogList = response.rows;
-        this.total = response.total;
-
-      }).finally(()=>{
+      listCourseTrafficLog(this.queryParams).then(res => {
+        this.courseTrafficLogList = res.rows;
+        this.total = res.total;
+      }).finally(() => {
         this.loading = false;
-      })
-    },
-    // 取消按钮
-    cancel() {
-      this.open = false;
-      this.reset();
-    },
-    // 表单重置
-    reset() {
-      this.form = {
-        logId: null,
-        userId: null,
-        videoId: null,
-        createTime: null,
-        qwExternalContactId: null,
-        internetTraffic: null,
-        qwUserId: null,
-        companyUserId: null,
-        companyId: null,
-        courseId: null
-      };
-      this.resetForm("form");
+      });
     },
-    /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
       this.getList();
     },
-    /** 重置按钮操作 */
     resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-    // 多选框选中数据
-    handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.logId)
-      this.single = selection.length!==1
-      this.multiple = !selection.length
-    },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加短链课程流量记录";
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      const logId = row.logId || this.ids
-      getCourseTrafficLog(logId).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "修改短链课程流量记录";
-      });
+      this.timeRange = null;
+      this.queryParams = {
+        ...this.queryParams,
+        startDate: null,
+        endDate: null,
+        companyId: null,
+        project: null,
+        courseId: null,
+        pageNum: 1,
+      };
+      this.getList();
     },
-    /** 提交按钮 */
-    submitForm() {
-      this.$refs["form"].validate(valid => {
-        if (valid) {
-          if (this.form.logId != null) {
-            updateCourseTrafficLog(this.form).then(response => {
-              this.msgSuccess("修改成功");
-              this.open = false;
-              this.getList();
-            });
-          } else {
-            addCourseTrafficLog(this.form).then(response => {
-              this.msgSuccess("新增成功");
-              this.open = false;
-              this.getList();
-            });
-          }
-        }
-      });
+    formatTrafficData(traffic) {
+      if (traffic < 1024) return `${traffic} B`;
+      if (traffic < 1024 ** 2) return `${(traffic / 1024).toFixed(2)} KB`;
+      if (traffic < 1024 ** 3) return `${(traffic / 1024 ** 2).toFixed(2)} MB`;
+      return `${(traffic / 1024 ** 3).toFixed(2)} GB`;
     },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const logIds = row.logId || this.ids;
-      this.$confirm('是否确认删除短链课程流量记录编号为"' + logIds + '"的数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(function() {
-          return delCourseTrafficLog(logIds);
-        }).then(() => {
-          this.getList();
-          this.msgSuccess("删除成功");
-        }).catch(() => {});
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.logId);
     },
-    /** 导出按钮操作 */
     handleExport() {
-      const queryParams = this.queryParams;
-      this.$confirm('是否确认导出所有短链课程流量记录数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(() => {
-          this.exportLoading = true;
-          return exportCourseTrafficLog(queryParams);
-        }).then(response => {
-          this.download(response.msg);
-          this.exportLoading = false;
-        }).catch(() => {});
+      this.$confirm("确认导出数据?", "提示").then(() => {
+        this.exportLoading = true;
+        return exportCourseTrafficLog(this.queryParams);
+      }).then(res => {
+        this.download(res.msg);
+      }).finally(() => {
+        this.exportLoading = false;
+      });
     }
   }
 };

+ 25 - 3
src/views/course/userCourseComplaintRecord/index.vue

@@ -1,15 +1,36 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="用户昵称" prop="nickName">
+      <el-form-item label="用户ID" prop="userId">
         <el-input
-          v-model="queryParams.nickName"
-          placeholder="请输入用户昵称"
+          v-model="queryParams.userId"
+          placeholder="请输入用户ID"
           clearable
           size="small"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
+      <el-form-item label="投诉类型" prop="complaintTypeName">
+        <el-input
+          v-model="queryParams.complaintTypeName"
+          placeholder="请输入投诉类型"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="创建时间" prop="dateRange">
+        <el-date-picker
+          v-model="dateRange"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="yyyy-MM-dd"
+          style="width: 260px"
+          @change="handleDateRangeChange"
+        />
+      </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -65,6 +86,7 @@
 
     <el-table border v-loading="loading" :data="userCourseComplaintRecordList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="用户ID" align="center" prop="userId" />
       <el-table-column label="用户昵称" align="center" prop="nickName" />
       <el-table-column label="投诉类型" align="center" prop="complaintTypeName" />
       <el-table-column label="所属课程" align="center" prop="courseName" />

+ 20 - 1
src/views/course/userCoursePeriod/index.vue

@@ -165,6 +165,7 @@
           <el-table-column label="营期名称" align="center" prop="periodName" />
           <el-table-column label="公司名称" align="center" prop="companyName" />
           <el-table-column label="营期状态" align="center" prop="periodStatus" width="100" :formatter="periodStatusFormatter" />
+          <el-table-column label="营期线" align="center" prop="periodLine" width="180" />
           <el-table-column label="开营开始时间" align="center" prop="periodStartingTime" width="180" />
           <el-table-column label="开营结束时间" align="center" prop="periodEndTime" width="180" />
           <el-table-column label="创建时间" align="center" prop="createTime" width="180" />
@@ -291,6 +292,21 @@
           >
           </el-date-picker>
         </el-form-item>
+        <el-form-item prop="periodLine">
+          <span slot="label">
+            营期线
+            <el-tooltip content="营期首次播放课程的日期" placement="top">
+              <i class="el-icon-question" style="margin-left: 5px; color: #909399; cursor: help;"></i>
+            </el-tooltip>
+          </span>
+          <el-date-picker
+            v-model="form.periodLine"
+            type="date"
+            placeholder="请选择营期线"
+            value-format="yyyy-MM-dd"
+            :clearable="true">
+          </el-date-picker>
+        </el-form-item>
       </el-form>
       <div class="drawer-footer">
         <el-button type="primary" @click="submitForm">确 定</el-button>
@@ -714,7 +730,10 @@ export default {
         ],
         periodStartingTime: [
           { required: true, message: '开营日期不能为空', trigger: 'change' }
-        ]
+        ],
+        // periodLine:  [
+        //   { required: true, message: '营期线不能为空', trigger: 'change' }
+        // ]
       },
       // 公司选项
       companyOptions: [],

+ 28 - 2
src/views/course/userCoursePeriod/statistics.vue

@@ -18,6 +18,21 @@
             />
           </el-select>
         </el-form-item>
+        <el-form-item label="公司">
+          <el-select
+            v-model="queryParams.companyId"
+            placeholder="请选择公司"
+            clearable
+            style="width: 400px"
+          >
+            <el-option
+              v-for="item in companyOptions"
+              :key="item.companyId"
+              :label="item.companyName"
+              :value="item.companyId"
+            />
+          </el-select>
+        </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="handleQuery">查询</el-button>
         </el-form-item>
@@ -112,7 +127,7 @@
 </template>
 
 <script>
-import {getDays, periodCountSelect} from "@/api/course/userCoursePeriod";
+import {getDays, periodCountSelect, getPeriodCompanyList} from "@/api/course/userCoursePeriod";
 
 export default {
   name: "CourseStatistics",
@@ -134,6 +149,7 @@ export default {
       total: 0,
       // 课程选项
       courseOptions: [],
+      companyOptions: [],
       // 统计数据
       statistics: {
         courseCompleteNum: 0,
@@ -152,7 +168,8 @@ export default {
         pageSize: 10,
         videoIdList: [],
         // videoId: '',
-        periodId: ''
+        periodId: '',
+        companyId: null,
       },
       // 是否已初始化
       initialized: false
@@ -182,8 +199,17 @@ export default {
     initializeData() {
       this.getCourseOptions();
       this.getCountList();
+      this.getCompanyOptions()
       this.initialized = true;
     },
+    // 获取公司列表
+    getCompanyOptions() {
+      getPeriodCompanyList({
+        periodId: this.periodId
+      }).then(response => {
+        this.companyOptions = response.data || [];
+      });
+    },
     /** 获取课程选项 */
     getCourseOptions() {
       this.loading = true;

+ 4 - 3
src/views/course/userWatchCourseStatistics/index.vue

@@ -11,12 +11,12 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="营期日期" prop="periodStartingTime">
+      <el-form-item label="营期线" prop="periodStartingTime">
         <el-date-picker clearable size="small"
                         v-model="queryParams.periodStartingTime"
                         type="date"
                         value-format="yyyy-MM-dd"
-                        placeholder="选择营期开始日期">
+                        placeholder="选择营期线">
         </el-date-picker>
       </el-form-item>
       <el-form-item label="播出时间" prop="courseStartDateTime">
@@ -81,7 +81,7 @@
     <el-table border v-loading="loading" :data="userWatchCourseStatisticsList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="营期名称" align="center" prop="periodName" />
-      <el-table-column label="营期日期" align="center" prop="periodStartingTime" />
+      <el-table-column label="营期线" align="center" prop="periodStartingTime" />
       <el-table-column label="播出时间" align="center" prop="courseStartDateTime" />
       <el-table-column label="课程名称" align="center" prop="courseName" />
       <el-table-column label="视频小节" align="center" prop="videoTitle" />
@@ -90,6 +90,7 @@
       <el-table-column label="新增会员" align="center" prop="newUserNum" />
       <el-table-column label="会员数量" align="center" prop="userNum" />
       <el-table-column label="观看人数" align="center" prop="watchNum" />
+      <el-table-column label="上线率" align="center" prop="onlineRatePercent" />
       <el-table-column label="完播人数" align="center" prop="completeWatchNum" />
       <el-table-column label="完播率" align="center" prop="completeWatchRatePercent" />
       <el-table-column label="答题人数" align="center" prop="answerNum" />

+ 4 - 3
src/views/course/userWatchCourseTotalStatistics/index.vue

@@ -11,12 +11,12 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="营期日期" prop="periodStartingTime">
+      <el-form-item label="营期线" prop="periodStartingTime">
         <el-date-picker clearable size="small"
                         v-model="queryParams.periodStartingTime"
                         type="date"
                         value-format="yyyy-MM-dd"
-                        placeholder="选择营期开始日期">
+                        placeholder="选择营期线">
         </el-date-picker>
       </el-form-item>
       <el-form-item label="播出时间" prop="courseStartDateTime">
@@ -89,7 +89,7 @@
     <el-table border v-loading="loading" :data="userWatchCourseStatisticsList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="营期名称" align="center" prop="periodName" />
-      <el-table-column label="营期日期" align="center" prop="periodStartingTime" />
+      <el-table-column label="营期线" align="center" prop="periodStartingTime" />
       <el-table-column label="播出时间" align="center" prop="courseStartDateTime" />
       <el-table-column label="课程名称" align="center" prop="courseName" />
       <el-table-column label="视频小节" align="center" prop="videoTitle" />
@@ -98,6 +98,7 @@
       <el-table-column label="新增会员" align="center" prop="newUserNum" />
       <el-table-column label="会员数量" align="center" prop="userNum" />
       <el-table-column label="观看人数" align="center" prop="watchNum" />
+      <el-table-column label="上线率" align="center" prop="onlineRatePercent" />
       <el-table-column label="完播人数" align="center" prop="completeWatchNum" />
       <el-table-column label="完播率" align="center" prop="completeWatchRatePercent" />
       <el-table-column label="红包领取个数" align="center" prop="redPacketNum" />

+ 4 - 3
src/views/course/userWatchStatistics/index.vue

@@ -11,12 +11,12 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="营期日期" prop="periodStartingTime">
+      <el-form-item label="营期线" prop="periodStartingTime">
         <el-date-picker clearable size="small"
           v-model="queryParams.periodStartingTime"
           type="date"
           value-format="yyyy-MM-dd"
-          placeholder="选择营期开始日期">
+          placeholder="选择营期线">
         </el-date-picker>
       </el-form-item>
 
@@ -55,7 +55,7 @@
     <el-table border v-loading="loading" :data="userWatchStatisticsList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="营期名称" align="center" prop="periodName" />
-      <el-table-column label="营期开始日期" align="center" prop="periodStartingTime" width="180">
+      <el-table-column label="营期线" align="center" prop="periodStartingTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.periodStartingTime, '{y}-{m}-{d}') }}</span>
         </template>
@@ -64,6 +64,7 @@
       <el-table-column label="新增会员" align="center" prop="newUserNum" />
       <el-table-column label="会员数量" align="center" prop="userNum" />
       <el-table-column label="观看人数" align="center" prop="watchNum" />
+      <el-table-column label="上线率" align="center" prop="onlineRatePercent" />
       <el-table-column label="完播人数" align="center" prop="completeWatchNum" />
       <el-table-column label="完播率" align="center" prop="completeWatchRatePercent" />
 

+ 531 - 165
src/views/index.vue

@@ -2,174 +2,202 @@
   <div class="statistics-dashboard">
     <!-- 数据概览 (Data Overview) -->
     <el-card class="overview-section" shadow="never">
-      <div slot="header" class="header">
-        <span>数据概览</span>
-      </div>
-
       <el-row :gutter="20">
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-user-solid"></i>
-              分公司数量
-            </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="dealderCount" :duration="3600" class="card-panel-num" /></div>
+        <el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16" class="companybox">
+          <img src="../assets/images/topbg.png" alt="" class="topimg">
+          <img src="../assets/images/topbg.png" alt="" class="bottomimg">
+          <div class="companyboxtitle">
+            企业数据
           </div>
-        </el-col>
+          <div class="companyflex">
+            <div class="topbg companycard cardafter">
+              <div class="card-title1">
+                <img src="../assets/images/tab_company.png" alt="" class="icon-img">
+                分公司数量
+              </div>
 
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-user"></i>
-              销售数量
+              <div class="card-value highlight1">
+                <count-to :start-val="0" :end-val="dealderCount" :duration="3600"
+                          class="card-panel-num companynumber" />
+              </div>
             </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="groupMgrCount" :duration="3600" class="card-panel-num" />
+            <div class="companycard cardafter">
+              <div class="card-title1">
+                <img src="../assets/images/salesperson.png" alt="" class="icon-img">
+                销售数量
+              </div>
+              <div class="card-value highlight1">
+                <count-to :start-val="0" :end-val="groupMgrCount" :duration="3600"
+                          class="card-panel-num companynumber" />
+              </div>
             </div>
-          </div>
-        </el-col>
+            <div class="companycard cardafter">
+              <div class="card-title1">
+                <img src="../assets/images/member.png" alt="" class="icon-img">
+                会员数量
+              </div>
+              <div class="card-value highlight1">
+                <count-to :start-val="0" :end-val="memberCount" :duration="3600" class="card-panel-num companynumber" />
+                <span class="highlight-today-add companyadd">+{{todayIncreaseUserNum}}</span>
+              </div>
 
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-shopping-cart-full"></i>
-              会员数量
-            </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="memberCount" :duration="3600" class="card-panel-num" />
-              <span class="highlight-today-add">+{{todayIncreaseUserNum}}</span>
-            </div>
-            <div class="card-badge">
             </div>
-          </div>
-        </el-col>
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-shopping-cart-full"></i>
-              企微数量
-            </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="memberCount" :duration="3600" class="card-panel-num" /></div>
-            <div class="card-badge">
+            <div class="botttombg companycard">
+              <div class="card-title1">
+                <img src="../assets/images/tab_enterprise.png" alt="" class="icon-img">
+                企微数量
+              </div>
+              <div class="card-value highlight1">
+                <count-to :start-val="0" :end-val="qwMemberNum" :duration="3600" class="card-panel-num companynumber" />
+              </div>
             </div>
           </div>
         </el-col>
 
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-money"></i>
-              可用余额
-            </div>
-            <div class="card-value highlight">
-              {{balance}}
-            </div>
-          </div>
-        </el-col>
 
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <span>今日消耗</span>
-            </div>
-            <div class="card-value highlight">
-              {{todayComsumption?todayComsumption.toFixed(2):'0.00'}}
-            </div>
-            <div class="card-sub">
-              <span>昨日消耗(元)</span>
-              <span class="sub-value">
-                {{yesterdayComsumption?yesterdayComsumption.toFixed(2):'0.00'}}
-              </span>
-            </div>
-            <el-progress :percentage="percentage" :show-text="false" color="#409EFF"></el-progress>
-            <div class="card-desc">{{remainMessage}}</div>
+        <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8" class="propertyboxtitle">
+          <div class="property_title">
+            资产概览
           </div>
-        </el-col>
-
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <span class="cdn-label">CDN</span>
-              今日
-            </div>
-            <div class="card-value highlight">{{formatBytes(this.todayTraffic)}}
+          <div class="propertyboxflex">
+            <div class="property-card propertyline">
+              <div class="property-title">
+                <i class="el-icon-money"></i>
+                企业资产(元)
+              </div>
+              <div class="card-value highlight">
+                <count-to :start-val="0" :end-val="balance" :duration="3600" class="card-panel-num" />
+              </div>
             </div>
-            <div class="card-sub">
-              <span>本月</span>
-              <span class="sub-value">{{formatBytes(this.thisMonthTraffic)}}</span>
+            <div class="property-card">
+              <div class="property-title">
+                <span>今日消耗 (元)</span>
+              </div>
+              <div class="card-value highlight" style="color: rgba(32, 33, 36, 1);margin-top: 10px;">
+                <count-to :start-val="0" :end-val="todayComsumption" :duration="3600" class="card-panel-num" />
+              </div>
+              <div class="card-compare">
+                较昨日 <span>+1</span>
+              </div>
             </div>
           </div>
-        </el-col>
 
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-message"></i>
-              短信剩余条数
-            </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="smsRemainCount" :duration="3600" class="card-panel-num" />
-            </div>
-          </div>
         </el-col>
+      </el-row>
 
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              平台今日看课人数
-            </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="todayWatchUserCount" :duration="3600" class="card-panel-num" />
-            </div>
-            <div class="card-sub">
-              <span>配额上限</span>
-              <span class="sub-value">
-                <count-to :start-val="0" :end-val="todayWatchUserCount" :duration="3600" class="card-panel-num" />/<count-to :start-val="0" :end-val="versionLimit" :duration="3600" class="card-panel-num" /></span>
-            </div>
-            <el-progress :percentage="todayWatchUserCount/versionLimit" :show-text="false" color="#409EFF"></el-progress>
+      <el-row :gutter="20">
+        <el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
+          <div class="operatetitle">
+            经营数据
           </div>
-        </el-col>
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-shopping-cart-full"></i>
-              订单总数
-            </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="orderTotalNum" :duration="3600" class="card-panel-num" />
-              <span class="highlight-today-add">+{{todayOrderNum}}</span>
-            </div>
-            <div class="card-badge">
+          <div class="operatetitle-col">
+            <div class="operatetitle-card">
+              <div class="card-title">
+                <i class="el-icon-shopping-cart-full"></i>
+                收款总数
+              </div>
+              <div class="operate-value highlight">
+                <count-to :start-val="0" :end-val="recvTotalNum" :duration="3600" class="card-panel-num" />
+                <div class="yesterdaybox">
+                  较昨日 <span class="highlight-today-add2">+{{recvTodayNum}}</span>
+                </div>
+              </div>
+              <div class="card-badge">
+              </div>
             </div>
-          </div>
-        </el-col>
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-shopping-cart-full"></i>
-              收款总数
+            <div class="operatetitle-card">
+              <div class="card-title">
+                <i class="el-icon-shopping-cart-full"></i>
+                订单总数
+              </div>
+              <div class="operate-value highlight">
+                <count-to :start-val="0" :end-val="orderTotalNum" :duration="3600" class="card-panel-num" />
+                <div class="yesterdaybox">
+                  较昨日 <span class="highlight-today-add2">+{{todayOrderNum}}</span>
+                </div>
+
+              </div>
+              <div class="card-badge">
+              </div>
+
             </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="recvTotalNum" :duration="3600" class="card-panel-num" />
-              <span class="highlight-today-add">+{{recvTodayNum}}</span>
+            <div class="operatetitle-card">
+              <div class="card-title">
+                平台今日看课人数
+              </div>
+              <div class="operate-value highlight">
+                <count-to :start-val="0" :end-val="todayWatchUserCount" :duration="3600" class="card-panel-num" />
+              </div>
+              <div class="card-sub">
+                <span>配额上限</span>
+                <span class="sub-value">
+                  <count-to :start-val="0" :end-val="todayWatchUserCount" :duration="3600" class="card-panel-num"
+                            style="color: rgba(49, 185, 154, 1);" />
+                  /
+                  <count-to :start-val="0" :end-val="versionLimit" :duration="3600" class="card-panel-num" />
+                </span>
+              </div>
+              <el-progress :percentage="todayWatchUserCount/versionLimit" :show-text="false"
+                           color="#409EFF"></el-progress>
             </div>
-            <div class="card-badge">
+            <div class="operatetitle-card">
+              <div class="card-title">
+                <i class="el-icon-shopping-cart-full"></i>
+                商品总数
+              </div>
+              <div class="operate-value highlight">
+                <count-to :start-val="0" :end-val="goodsTotalNum" :duration="3600" class="card-panel-num" />
+                <div class="yesterdaybox">
+                  较昨日 <span class="highlight-today-add2">+{{todayGoodsNum}}</span>
+                </div>
+
+              </div>
+              <div class="card-badge">
+              </div>
             </div>
           </div>
+
         </el-col>
-        <el-col :span="3">
-          <div class="data-card">
-            <div class="card-title">
-              <i class="el-icon-shopping-cart-full"></i>
-              商品总数
-            </div>
-            <div class="card-value highlight">
-              <count-to :start-val="0" :end-val="goodsTotalNum" :duration="3600" class="card-panel-num" />
-              <span class="highlight-today-add">+{{todayGoodsNum}}</span>
+
+
+        <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8" style="padding-left: 15px;">
+
+          <div class="internetbox">
+            <div class="internet-cardtop">
+              <div class="cardinnerbox">
+                <div class="cardtopimg">
+                  <img src="../assets/images/liuliang.png" alt=""><span>剩余流量</span>
+                </div>
+                <div class="cardtopnumber">
+                  100.00GB
+                </div>
+              </div>
+              <div class="progress">
+                <el-progress :percentage="90" :show-text="false" define-back-color="#000">
+
+                </el-progress>
+              </div>
+              <div class="cardinnerbox2">
+                <div>
+                  今日消耗 <span>{{formatBytes(this.todayTraffic)}}</span>
+                </div>
+                <div>
+                  本月 <span>{{formatBytes(this.thisMonthTraffic)}}</span>
+                </div>
+              </div>
             </div>
-            <div class="card-badge">
+
+            <div class="internetbox-messge">
+              <div class="internet-card">
+                <img src="../assets/images/message.png" alt="">
+
+                <span class="internet-title">
+                  短信剩余条数 (条)
+                </span>
+              </div>
+              <div class="internet-number">
+                0
+              </div>
             </div>
           </div>
         </el-col>
@@ -1401,37 +1429,60 @@ export default {
 </script>
 
 <style scoped>
-.highlight-today-add{
-  color:green;font-size:17px;font-weight: normal;
+.highlight-today-add {
+  color: green;
+  font-size: 17px;
+  font-weight: normal;
+}
+
+.highlight-today-add2 {
+  color: rgba(49, 185, 154, 1);
+  font-size: 14px;
+  font-weight: normal;
+  transform: scale(.9);
 }
-.action-group .el-button + .el-button,
+
+.action-group .el-button+.el-button,
 .action-group .el-dropdown {
   margin-left: 10px;
 }
+
 .is-active {
   color: #409EFF;
   font-weight: bold;
 }
+
 ::v-deep .el-radio-button__inner:hover {
-  color: #409EFF; /* 鼠标悬浮时的文字颜色,可以根据需要调整 */
+  color: #409EFF;
+  /* 鼠标悬浮时的文字颜色,可以根据需要调整 */
 }
+
 ::v-deep .el-radio-button.is-active .el-radio-button__inner {
-  background-color: #409EFF; /* 选中时的背景色 */
-  border-color: #409EFF;     /* 选中时的边框色 */
-  color: #FFFFFF;           /* 选中时的文字颜色 (通常是白色) */
-  box-shadow: -1px 0 0 0 #409EFF; /* 处理按钮间的连接缝隙 */
+  background-color: #409EFF;
+  /* 选中时的背景色 */
+  border-color: #409EFF;
+  /* 选中时的边框色 */
+  color: #FFFFFF;
+  /* 选中时的文字颜色 (通常是白色) */
+  box-shadow: -1px 0 0 0 #409EFF;
+  /* 处理按钮间的连接缝隙 */
 }
+
 /* 如果需要,也可以修改非选中状态下的聚焦(focus)或悬浮(hover)样式 */
 /* 例如,让非选中按钮悬浮时边框和文字也变蓝 */
 ::v-deep .el-radio-button:not(.is-active) .el-radio-button__inner:hover {
   color: #409EFF;
   /* border-color: #b3d8ff;  Element UI 默认悬浮边框色,可以按需修改 */
 }
+
 /* 聚焦时的外框,如果需要的话 */
 ::v-deep .el-radio-button:focus:not(.is-checked) .el-radio-button__inner {
-  /* border-color: #409EFF; */ /* Element UI 默认的 focus 颜色通常关联主题色 */
-  /* box-shadow: 0 0 2px 2px rgba(64, 158, 255, 0.2); */ /* 示例 focus 光晕 */
+  /* border-color: #409EFF; */
+  /* Element UI 默认的 focus 颜色通常关联主题色 */
+  /* box-shadow: 0 0 2px 2px rgba(64, 158, 255, 0.2); */
+  /* 示例 focus 光晕 */
 }
+
 .statistics-dashboard {
   padding: 20px;
   background-color: #f5f7fa;
@@ -1461,7 +1512,8 @@ export default {
   position: relative;
   transition: background-color 0.3s ease-in-out;
 }
-.data-card:hover{
+
+.data-card:hover {
   border: 1px solid #4592ff;
   background-color: #e7f1ff;
 }
@@ -1472,10 +1524,16 @@ export default {
   margin-bottom: 10px;
 }
 
+.card-title1 {
+  color: white;
+  font-size: 14px;
+  margin-bottom: 10px;
+}
+
 .card-value {
   font-size: 24px;
   font-weight: bold;
-  margin-top: auto;
+  margin-top: 20px;
 }
 
 .highlight {
@@ -1555,17 +1613,19 @@ export default {
   justify-items: center;
   flex-direction: column;
   padding: 10px;
-  .highlight{
+
+  .highlight {
     text-align: center;
     margin-top: 1em;
 
     font-family: BebasNeue;
     color: #1677ff;
-    font-size: 26px;
+    font-size: 21px;
     line-height: 42px;
-    font-weight: 400;
+    font-weight: 600;
     margin-top: 8px;
   }
+
   font-size: 15px;
   color: #000;
 
@@ -1615,17 +1675,20 @@ export default {
   height: 350px;
   width: 100%;
 }
-.analysis-card-check{
+
+.analysis-card-check {
   display: flex;
   flex-direction: row;
   border: 1px solid transparent;
   background-color: #fff;
   border-radius: 4px;
 }
-.analysis-card-check:hover{
+
+.analysis-card-check:hover {
   cursor: pointer;
 }
-.analysis-card-check-selected:after{
+
+.analysis-card-check-selected:after {
   content: "";
   display: block;
   border-width: 15px;
@@ -1637,9 +1700,10 @@ export default {
   border-color: #4592FF transparent transparent transparent;
   font-size: 0;
   line-height: 0;
-  z-index:1;
+  z-index: 1;
 }
-.analysis-card-check-selected:before{
+
+.analysis-card-check-selected:before {
   content: "";
   display: block;
   border-width: 15px;
@@ -1651,22 +1715,324 @@ export default {
   border-color: #4592FF transparent transparent transparent;
   font-size: 0;
   line-height: 0;
-  z-index:1;
+  z-index: 1;
 }
-.analysis-card-check-selected{
+
+.analysis-card-check-selected {
   border: 1px solid #4592FF;
   background-color: #e7f1ff;
 }
-.color{
+
+.color {
   position: relative;
   border: 1px solid #4592FF;
   background-color: #e7f1ff;
 }
+
 .color:after {
   bottom: -27px;
   border-color: #E7F1FF transparent transparent transparent;
 }
-.legend-group{
 
+.companybox {
+  color: white;
+  background-color: #006CFF;
+  padding: 10px 10px 40px 10px;
+  box-sizing: border-box;
+  position: relative;
+  border-radius: 6px;
+
+  .topimg {
+    width: 100px;
+    height: 80px;
+    position: absolute;
+    top: 0px;
+    left: 0;
+  }
+
+  .bottomimg {
+    width: 100px;
+    height: 80px;
+    position: absolute;
+    bottom: -10px;
+    right: 0;
+    transform: rotate(180deg);
+  }
+
+  .companyboxtitle {
+    height: 30px;
+    margin-bottom: 20px;
+    font-weight: 600;
+  }
+
+  .companyflex {
+    display: flex;
+    justify-content: space-around;
+  }
+}
+
+
+
+.companynumber {
+  color: white;
+}
+
+.companycard {
+
+  width: 25%;
+}
+
+.companyadd {
+  color: white;
+}
+
+.cardafter {
+  position: relative;
+
+}
+
+.cardafter::after {
+  content: "";
+  height: 60px;
+  border-right: 1px solid rgba(255, 255, 255, 0.20);
+  position: absolute;
+  right: 30px;
+  top: 0px;
+}
+
+.highlight1 {
+  margin-top: 10px;
+  margin-left: 20px;
+}
+
+
+
+
+.propertyboxtitle {
+  background-image: url(../assets/images/zcgl_bg.png);
+  height: 100px;
+}
+
+.propertyboxflex {
+  display: flex;
+  background-color: white;
+  justify-content: space-between;
+}
+
+.property-card {
+  width: 48%;
+  border-radius: 4px;
+  padding: 15px;
+  height: 100px;
+  display: flex;
+  flex-direction: column;
+  position: relative;
+  transition: background-color 0.3s ease-in-out;
+
+}
+
+.property_title {
+  height: 40px;
+  line-height: 40px;
+  color: rgba(32, 33, 36, 1);
+  box-sizing: border-box;
+  padding-left: 10px;
+  font-weight: 600;
+}
+
+.card-compare {
+  margin-top: 5px;
+  font-size: 14px;
+  color: rgba(92, 95, 102, 1);
+
+  span {
+    font-size: 13px;
+    transform: scale(.8);
+    color: rgba(49, 185, 154, 1);
+  }
+}
+
+.propertyline {
+  position: relative;
+}
+
+.propertyline::after {
+  position: absolute;
+  content: "";
+  height: 80px;
+  border-right: 1px solid rgba(237, 239, 242, 1);
+  right: 0;
+}
+
+.operatetitle {
+  font-weight: 600;
+  height: 50px;
+  line-height: 50px;
+}
+
+.operatetitle-col{
+  display: flex;
+  justify-content: space-between;
+  padding-bottom: 20px;
+  padding-right: 5px;
+  .operatetitle-card {
+    width: 24%;
+    border: 1px solid transparent;
+    background-color: rgba(245, 247, 250, 1);
+    border-radius: 4px;
+    padding: 15px;
+    display: flex;
+    flex-direction: column;
+    position: relative;
+    transition: background-color 0.3s ease-in-out;
+
+    .operate-value {
+      font-size: 24px;
+      font-weight: bold;
+    }
+  }
+}
+
+.yesterdaybox {
+  font-size: 14px;
+  color: rgba(92, 95, 102, 1);
+  font-weight: 200;
+  margin-top: 10px;
+}
+
+.internetbox {
+  background: linear-gradient(to right, rgba(255, 99, 0, 1), rgba(255, 159, 1, 1));
+  border-radius: 6px;
+  padding: 2px 5px 15px 5px;
+  width: 100%;
+  .internet-cardtop {
+    background-color: white;
+    border-radius: 3px;
+    margin-top: 5px;
+    justify-content: space-between;
+    padding: 15px;
+    box-sizing: border-box;
+    color: rgba(32, 33, 36, 1);
+
+    .cardinnerbox {
+      display: flex;
+      justify-content: space-between;
+
+      .cardtopimg {
+        display: flex;
+        align-items: center;
+        font-size: 15px;
+
+        img {
+          height: 18px;
+          width: 18px;
+        }
+      }
+
+      .cardtopnumber {
+        font-size: 25px;
+        color: rgba(32, 33, 36, 1);
+        font-weight: bold;
+      }
+
+    }
+
+    .cardinnerbox2 {
+      display: flex;
+      justify-content: space-between;
+      font-size: 14px;
+      color: rgba(92, 95, 102, 1);
+
+
+    }
+
+  }
+
+  .internetbox-messge{
+    color: white;
+    display: flex;
+    justify-content: space-between;
+    padding: 15px 10px 10px 10px;
+    .internet-card{
+      display: flex;
+      font-size: 14px;
+      align-items: center;
+      img{
+        height: 18px;
+        width: 18px;
+      }
+      span{
+        padding-left: 5px;
+      }
+    }
+    .internet-number{
+      font-size: 25px;
+
+    }
+  }
+  .internetbox {
+    display: flex;
+    color: white;
+
+    .internet-card {
+      width: 100%;
+      display: flex;
+      color: white;
+
+    }
+  }
+
+  .internet-title {
+    font-size: 14px;
+  }
+
+}
+
+.company {
+  background-color: 006CFF;
+}
+.highlight-red{
+  text-align: center;
+  margin-top: 1em;
+  font-family: BebasNeue;
+  color: rgba(255, 82, 82, 1);
+  font-size: 21px;
+  line-height: 42px;
+  font-weight: 600;
+  margin-top: 8px;
+}
+.highlight-black{
+  text-align: center;
+  margin-top: 1em;
+  font-family: BebasNeue;
+  color: rgba(32, 33, 36, 1);
+  font-size: 21px;
+  line-height: 42px;
+  font-weight: 600;
+  margin-top: 8px;
+
+}
+.operatetitle-card:hover{
+  border: 1px solid #4592ff;
+  background-color: #e7f1ff;
+}
+.icon-img{
+  height: 14px;
+  width: 14px;
+}
+.progress{
+  transform: rotate(180deg);
+  margin-top: 20px;
+}
+.progress ::v-deep .el-progress-bar__outer{
+  background-color: rgba(247, 152, 11, 0.2);
+}
+::v-deep .el-progress {
+
+  .el-progress-bar {
+    .el-progress-bar__inner {
+      background: linear-gradient(to right, #FF6300,#FF9F01)
+    }
+  }
 }
 </style>

+ 382 - 246
src/views/store/statistics/storeOrder.vue

@@ -1,66 +1,149 @@
 <template>
-        <div class="app-container">
-            <div class="app-content">
-                 <div class="title">
-                    商城订单统计
-                </div>
+  <div class="app-container">
+    <div class="app-content">
+      <div class="title">
+        商城订单统计
+      </div>
                <el-form class="search-form" :inline="true" >
                 <el-form-item >
-                  <el-select v-model="value" placeholder="请选择日期">
-                    <el-option
-                      v-for="item in options"
-                      :key="item.value"
-                      :label="item.label"
-                      :value="item.value">
-                    </el-option>
-                  </el-select>
-                </el-form-item>
-                <el-form-item label="公司名" prop="companyId">
-                    <el-select filterable v-model="companyId" @change="companyChange" placeholder="请选择公司名" clearable size="small">
-                        <el-option
-                          v-for="item in companys"
-                          :key="item.companyId"
-                          :label="item.companyName"
-                          :value="item.companyId"
-                        />
-                  </el-select>
-                </el-form-item>
+          <el-select v-model="value" placeholder="请选择日期">
+            <el-option
+              v-for="item in options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="公司名" prop="companyId">
+          <el-select filterable v-model="companyId" @change="companyChange" placeholder="请选择公司名" clearable size="small">
+            <el-option
+              v-for="item in companys"
+              :key="item.companyId"
+              :label="item.companyName"
+              :value="item.companyId"
+            />
+          </el-select>
+        </el-form-item>
                 <el-form-item >
                   <treeselect :clearable="false"  v-model="deptId"  :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
-                </el-form-item>
-                <el-form-item>
-                   <el-select filterable v-model="userIds" placeholder="请选择员工" clearable size="small">
-                      <el-option
-                        v-for="item in users"
-                        :key="item.userId"
-                        :label="item.nickName"
-                        :value="item.userId">
-                      </el-option>
-                    </el-select>
-                </el-form-item>
+        </el-form-item>
+        <el-form-item>
+          <el-select filterable v-model="userIds" placeholder="请选择员工" clearable size="small">
+            <el-option
+              v-for="item in users"
+              :key="item.userId"
+              :label="item.nickName"
+              :value="item.userId">
+            </el-option>
+          </el-select>
+        </el-form-item>
 
                 
-                <el-form-item label="筛选日期" prop="createTime">
-                  <el-date-picker clearable size="small" style="width: 205.4px"
-                    v-model="dateRange"
-                    type="daterange"
-                    value-format="yyyy-MM-dd"
+        <el-form-item label="筛选日期" prop="createTime">
+          <el-date-picker clearable size="small" style="width: 205.4px"
+            v-model="dateRange"
+            type="daterange"
+            value-format="yyyy-MM-dd"
                     start-placeholder="开始日期" end-placeholder="结束日期"
                     >
-                  </el-date-picker>
-                </el-form-item>
-                <el-form-item>
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item>
                     <el-button type="cyan" icon="el-icon-search"   @click="storeOrder">搜索</el-button>
-                </el-form-item>
-              </el-form>
-               <div class="data-box">
-                  <div class="echart-box">
-                    <div id="echart-customer"></div>
-                  </div>
-              </div>
-            </div>
+        </el-form-item>
+      </el-form>
+      <div class="data-box">
+        <div class="echart-box">
+          <div id="echart-customer"></div>
+        </div>
+        
+        <!-- 新增的数据表格 -->
+        <div class="table-container">
+          <h3 class="table-title">员工下单汇总</h3>
+          <el-table 
+            :data="tableData" 
+            border 
+            stripe 
+            style="width: 100%; margin-top: 20px;"
+            :row-class-name="tableRowClassName"
+            :span-method="objectSpanMethod">
+            <el-table-column prop="name" label="姓名/工号" width="120" fixed="left">
+              <template slot-scope="scope">
+                <span :class="{'group-name': scope.row.isGroup}">{{ scope.row.name }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="totalCalls" label="总单数" width="80" align="center"></el-table-column>
+            <el-table-column prop="totalAmount" label="总金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.totalAmount ? scope.row.totalAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="validAmount" label="成单金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.validAmount ? scope.row.validAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="waitingOrders" label="待付数" width="80" align="center"></el-table-column>
+            <el-table-column prop="waitingAmount" label="待付金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.waitingAmount ? scope.row.waitingAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="unPassedOrders" label="未过数" width="80" align="center"></el-table-column>
+            <el-table-column prop="unPassedAmount" label="未过金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.unpassedAmount ? scope.row.unpassedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="cancelOrders" label="取消数" width="80" align="center"></el-table-column>
+            <el-table-column prop="cancelAmount" label="取消金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.cancelAmount ? scope.row.cancelAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="unshippedOrders" label="成交未发货数" width="120" align="center"></el-table-column>
+            <el-table-column prop="unshippedAmount" label="成交未发货金额" width="130" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.unshippedAmount ? scope.row.unshippedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="shippedOrders" label="发货数" width="80" align="center"></el-table-column>
+            <el-table-column prop="shippedAmount" label="发货金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.shippedAmount ? scope.row.shippedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="transitOrders" label="在途数" width="80" align="center"></el-table-column>
+            <el-table-column prop="transitAmount" label="在途金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.transitAmount ? scope.row.transitAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="receivedOrders" label="签收数" width="80" align="center"></el-table-column>
+            <el-table-column prop="receivedAmount" label="签收金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.receivedAmount ? scope.row.receivedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="returnOrders" label="退货数" width="80" align="center"></el-table-column>
+            <el-table-column prop="returnAmount" label="退货金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.returnAmount ? scope.row.returnAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="paybackOrders" label="回款数" width="80" align="center"></el-table-column>
+            <el-table-column prop="paybackAmount" label="回款金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.paybackAmount ? scope.row.paybackAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+    </div>
 
-          </div>
+  </div>
 </template>
 
 <script>
@@ -82,241 +165,294 @@ export default {
   },
   data() {
     return {
-       companys:[],
-       deptOptions:[],
-       companyId:undefined,
-       deptId:undefined,
-       userIds:undefined,
-       users:[],
-       dateRange:[],
-       chart: null,
-       options: [{
-          value: '1',
-          label: '今天'
-        }, {
-          value: '2',
-          label: '昨天'
-        }, {
-          value: '3',
-          label: '本周'
-        }, {
-          value: '4',
-          label: '上周'
-        }, {
-          value: '5',
-          label: '本月'
-        }
-        , {
-          value: '6',
-          label: '上月'
-        }
-        , {
-          value: '7',
-          label: '本季度'
-        }
-        , {
-          value: '8',
-          label: '上季度'
-        }
-        , {
-          value: '9',
-          label: '本年'
-        }
-        , {
-          value: '10',
-          label: '上年'
-        }],
+      companys: [],
+      deptOptions: [],
+      companyId: undefined,
+      deptId: undefined,
+      userIds: undefined,
+      users: [],
+      dateRange: [],
+      chart: null,
+      options: [{
+        value: '1',
+        label: '今天'
+      }, {
+        value: '2',
+        label: '昨天'
+      }, {
+        value: '3',
+        label: '本周'
+      }, {
+        value: '4',
+        label: '上周'
+      }, {
         value: '5',
-        list:[],
-        dates:[],
-        orderCount:[],
-        payPrice:[]
-
-
+        label: '本月'
+      }, {
+        value: '6',
+        label: '上月'
+      }, {
+        value: '7',
+        label: '本季度'
+      }, {
+        value: '8',
+        label: '上季度'
+      }, {
+        value: '9',
+        label: '本年'
+      }, {
+        value: '10',
+        label: '上年'
+      }],
+      value: '5',
+      list: [],
+      dates: [],
+      orderCount: [],
+      payPrice: [],
+      // 新增表格数据
+      tableData: []
     }
   },
-   created() {
-       getCompanyList().then(response => {
-        this.companys = response.data;
-        if(this.companys!=null&&this.companys.length>0){
-          this.companyId=this.companys[0].companyId;
-          this.getTreeselect();
-        }
-      });
+  created() {
+    getCompanyList().then(response => {
+      this.companys = response.data;
+      if (this.companys != null && this.companys.length > 0) {
+        this.companyId = this.companys[0].companyId;
+        this.getTreeselect();
+      }
+    });
   },
   methods: {
-    companyChange(val){
+    companyChange(val) {
       console.log(val);
-      this.companyId=val;
+      this.companyId = val;
       this.getTreeselect();
     },
-    currDeptChange(val){
+    currDeptChange(val) {
       console.log(val)
-      this.deptId=val;
-       this.getUserListByDeptId();
+      this.deptId = val;
+      this.getUserListByDeptId();
     },
-     /** 查询部门下拉树结构 */
+    /** 查询部门下拉树结构 */
     getTreeselect() {
-      var that=this;
-      var param={companyId:this.companyId}
+      var that = this;
+      var param = { companyId: this.companyId }
       treeselect(param).then((response) => {
         this.deptOptions = response.data;
         console.log(this.deptOptions)
-        if(response.data!=null&&response.data.length>0){
-          this.deptId=response.data[0].id;
+        if (response.data != null && response.data.length > 0) {
+          this.deptId = response.data[0].id;
           that.storeOrder()
         }
       });
     },
-    handleExport(){
-        var data;
-        if(this.userIds!=undefined){
-            data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
-        }
-        else{
-            data={type:this.value,deptId:this.deptId}
-        }
-        exportVoiceLogs(data).then((response) => {
-            console.log(response)
-           this.download(response.msg);
-        });
-
+    handleExport() {
+      var data;
+      if (this.userIds != undefined) {
+        data = { type: this.value, userIds: this.userIds + "", deptId: this.deptId }
+      }
+      else {
+        data = { type: this.value, deptId: this.deptId }
+      }
+      exportVoiceLogs(data).then((response) => {
+        console.log(response)
+        this.download(response.msg);
+      });
     },
     getUserListByDeptId() {
-        this.userIds=undefined;
-        var data={deptId:this.deptId};
-        getUserListByDeptId(data).then(response => {
-          this.users = response.data;
-
-        });
+      this.userIds = undefined;
+      var data = { deptId: this.deptId };
+      getUserListByDeptId(data).then(response => {
+        this.users = response.data;
+      });
+    },
+    storeOrder() {
+      var data;
+      if (this.userIds != undefined) {
+        data = { type: this.value, userIds: this.userIds + "", deptId: this.deptId }
+      }
+      else {
+        data = { type: this.value, deptId: this.deptId }
+      }
+      if(this.dateRange && this.dateRange.length>0){
+        data.type = null
+        data.startTime = this.dateRange[0]
+        data.endTime = this.dateRange[1]
+      }
+      storeOrder(data).then((response) => {
+        this.dates = response.dates;
+        this.orderCount = response.orderCount;
+        this.payPrice = response.payPrice;
+        //表格数据
+        this.tableData = response.tableData || this.tableData;
+        
+        setTimeout(() => {
+          this.initEchart();
+        }, 500);
+      });
     },
-    storeOrder(){
-          var data;
-          if(this.userIds!=undefined){
-              data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
+    initEchart() {
+      var option = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            // 坐标轴指示器,坐标轴触发有效
+            type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
           }
-          else{
-              data={type:this.value,deptId:this.deptId}
+        },
+        legend: {
+          data: ['订单数', '订单金额']
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data: this.dates
           }
-          storeOrder(data).then((response) => {
-            this.dates=response.dates;
-            this.orderCount=response.orderCount;
-            this.payPrice=response.payPrice;
-            setTimeout(() => {
-                this.initEchart();
-            }, 500);
-        });
-      },
-      initEchart(){
-        var option = {
-          tooltip: {
-              trigger: 'axis',
-              axisPointer: {            // 坐标轴指示器,坐标轴触发有效
-                  type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
-              }
-          },
-          legend: {
-              data: ['订单数', '订单金额']
-          },
-          grid: {
-              left: '3%',
-              right: '4%',
-              bottom: '3%',
-              containLabel: true
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            axisLabel: {
+              formatter: '{value}个'
+            }
+          }
+        ],
+        series: [
+          {
+            name: '订单数',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.orderCount
           },
-          xAxis: [
-              {
-                  type: 'category',
-                  data: this.dates
-              }
-          ],
-          yAxis: [
-              {
-                  type: 'value',
-                  axisLabel:{
-                    formatter:'{value}个'
-                  }
-              }
-          ],
-          series: [
-              {
-
-                  name: '订单数',
-                  type: 'bar',
-                  emphasis: {
-                      focus: 'series'
-                  },
-                  data: this.orderCount
-              },
-              {
-
-                  name: '订单金额',
-                  type: 'bar',
-                  emphasis: {
-                      focus: 'series'
-                  },
-                  data: this.payPrice
-              }
-          ]
-        };
-        this.chart=echarts.init(document.getElementById("echart-customer"));
-        this.chart.setOption(option,true);
-      },
+          {
+            name: '订单金额',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.payPrice
+          }
+        ]
+      };
+      this.chart = echarts.init(document.getElementById("echart-customer"));
+      this.chart.setOption(option, true);
+    },
+    // 表格行样式
+    tableRowClassName({ row, rowIndex }) {
+      if (row.isGroup) {
+        return 'group-row';
+      }
+      return '';
+    },
+    // 表格合并方法(如果需要的话)
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      // 可以在这里实现单元格合并逻辑
+      return {
+        rowspan: 1,
+        colspan: 1
+      };
+    }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-.app-container{
-    border: 1px solid #e6e6e6;
-    padding: 12px;
-
-    .app-content{
-      background-color: white;
-      .title{
-        padding: 20px 30px 0px 30px;
-        font-size: 18px;
-        font-weight: bold;
-        color: black;
-
+.app-container {
+  border: 1px solid #e6e6e6;
+  padding: 12px;
+  .app-content {
+    background-color: white;
+    .title {
+      padding: 20px 30px 0px 30px;
+      font-size: 18px;
+      font-weight: bold;
+      color: black;
+    }
+    .search-form {
+      margin: 20px 30px 0px 30px;
+    }
+    .data-box {
+      padding: 30px;
+      background-color: rgb(255, 255, 255);
+      height: 100%;
+      .echart-box {
+        margin: 0 auto;
+        text-align: center;
       }
-      .search-form{
-        margin: 20px 30px 0px 30px;
+      .el-select {
+        margin: 5px 10px;
       }
-      .data-box{
-        padding: 30px;
-        background-color:  rgb(255, 255, 255);
-        height: 100%;
-
-        .echart-box{
-          margin: 0 auto;
-          text-align: center;
+      .table-box {
+        margin-top: 15px;
+        .export {
+          float: right;
+          margin: 10px 0px;
         }
-        .el-select{
-          margin: 5px 10px;
-        }
-        .table-box{
-          margin-top: 15px;
-          .export{
-            float: right;
-            margin: 10px 0px;
-          }
+      }
+      // 新增表格样式
+      .table-container {
+        margin-top: 30px;
+        .table-title {
+          font-size: 16px;
+          font-weight: bold;
+          color: #333;
+          margin-bottom: 10px;
         }
       }
     }
-}
-  #echart-customer{
-    width:100%;
-    height:320px
   }
-.vue-treeselect{
+}
+
+#echart-customer {
+  width: 100%;
+  height: 320px
+}
+
+.vue-treeselect {
   width: 217px;
   height: 36px;
 }
 
+// 表格相关样式
+::v-deep .group-row {
+  background-color: #e8f5e8 !important;
+  font-weight: bold;
+}
+
+::v-deep .group-name {
+  font-weight: bold;
+  color: #333;
+}
+
+::v-deep .el-table {
+  font-size: 12px;
+  
+  .el-table__header-wrapper {
+    th {
+      background-color: #f5f7fa;
+      font-weight: bold;
+      color: #333;
+    }
+  }
+  
+  .el-table__body-wrapper {
+    td {
+      padding: 8px 0;
+    }
+  }
+}
 </style>
+
 <style>
-.vue-treeselect__control{
+.vue-treeselect__control {
   display: block;
 }
-</style>
+</style>

+ 454 - 0
src/views/store/storeOrder/dimensionStatistics/index.vue

@@ -0,0 +1,454 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="销售公司" prop="companyId">
+        <el-select filterable v-model="queryParams.companyId" clearable placeholder="请选择公司名" size="small">
+          <el-option
+            v-for="item in companyList"
+            :key="item.companyId"
+            :label="item.companyName"
+            :value="item.companyId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="员工账号" prop="userName">
+        <el-input
+          v-model="queryParams.userName"
+          placeholder="请输入员工账号"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="员工名称" prop="companyUser">
+        <el-input
+          v-model="queryParams.companyUser"
+          placeholder="请输入员工名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+      <el-form-item label="商品标签" prop="cateIds">
+        <el-cascader
+          v-model="cateIds"
+          placeholder="请选择商品标签"
+          :options="categoryOptions"
+          :props="{ checkStrictly: true }"
+          :normalizer="normalizer"
+          clearable
+          filterable
+        ></el-cascader>
+      </el-form-item>
+
+      <el-form-item label="商品" prop="productId">
+        <el-select v-model="queryParams.productId" clearable filterable placeholder="请选择商品">
+          <el-option
+            v-for="item in productList"
+            :key="item.productId"
+            :label="item.productName"
+            :value="item.productId"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="订单日期">
+        <el-date-picker
+          v-model="queryDate"
+          type="monthrange"
+          align="right"
+          unlink-panels
+          range-separator="至"
+          start-placeholder="开始月份"
+          end-placeholder="结束月份"
+          :picker-options="pickerOptions"
+          value-format="yyyy-MM-dd"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <!--    <el-tabs v-model="activeName" @tab-click="handleClick">-->
+    <!--      <el-tab-pane label="员工统计" name="1"></el-tab-pane>-->
+    <!--      <el-tab-pane label="标签统计" name="2"></el-tab-pane>-->
+    <!--      <el-tab-pane label="商品统计" name="3"></el-tab-pane>-->
+    <!--    </el-tabs>-->
+
+    <!--    <el-table border v-loading="loading" :data="pageList" @selection-change="handleSelectionChange" v-show="queryParams.groupType !== '1'">-->
+    <!--      <el-table-column label="员工编码" align="center" prop="userId" "/>-->
+    <!--      <el-table-column label="标签编码" align="center" prop="cateId" v-else-if="queryParams.groupType === '2'"/>-->
+    <!--      <el-table-column label="商品编码" align="center" prop="productId" v-else/>-->
+    <!--      <el-table-column label="企业名称" align="center" prop="companyName" "/>-->
+    <!--      <el-table-column label="员工账号" align="center" prop="userName" "/>-->
+    <!--      <el-table-column label="员工名称" align="center" prop="nickName" "/>-->
+    <!--      <el-table-column label="标签名称" align="center" prop="cateName" v-if="queryParams.groupType === '2'"/>-->
+    <!--      <el-table-column label="商品名称" align="center" prop="productName" v-if="queryParams.groupType === '3'"/>-->
+    <!--      <el-table-column label="销售订单数量" align="center" prop="orderNum"/>-->
+    <!--      &lt;!&ndash;      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">&ndash;&gt;-->
+    <!--      &lt;!&ndash;        <template v-slot="scope">&ndash;&gt;-->
+    <!--      &lt;!&ndash;          <el-button&ndash;&gt;-->
+    <!--      &lt;!&ndash;            size="mini"&ndash;&gt;-->
+    <!--      &lt;!&ndash;            type="text"&ndash;&gt;-->
+    <!--      &lt;!&ndash;            icon="el-icon-edit"&ndash;&gt;-->
+    <!--      &lt;!&ndash;          >修改&ndash;&gt;-->
+    <!--      &lt;!&ndash;          </el-button>&ndash;&gt;-->
+    <!--      &lt;!&ndash;          <el-button&ndash;&gt;-->
+    <!--      &lt;!&ndash;            size="mini"&ndash;&gt;-->
+    <!--      &lt;!&ndash;            type="text"&ndash;&gt;-->
+    <!--      &lt;!&ndash;            icon="el-icon-delete"&ndash;&gt;-->
+    <!--      &lt;!&ndash;          >删除&ndash;&gt;-->
+    <!--      &lt;!&ndash;          </el-button>&ndash;&gt;-->
+    <!--      &lt;!&ndash;        </template>&ndash;&gt;-->
+    <!--      &lt;!&ndash;      </el-table-column>&ndash;&gt;-->
+    <!--    </el-table>-->
+
+    <el-table border v-loading="loading" :data="pageList" @selection-change="handleSelectionChange"
+              :span-method="objectSpanMethod" v-show="queryParams.groupType === '1'"
+              style="width: 100%; margin-top: 20px"
+    >
+      <el-table-column prop="companyName" align="center" label="企业名称" width="180"></el-table-column>
+      <el-table-column label="员工编码" align="center" prop="userId"/>
+      <el-table-column label="员工账号" align="center" prop="userName"/>
+      <el-table-column label="员工名称" align="center" prop="nickName"/>
+      <el-table-column label="总单数" align="center" prop="totalNum"/>
+      <el-table-column label="总金额" align="center" prop="totalPrice"/>
+      <el-table-column label="成交单数" align="center" prop="dealNum"/>
+      <el-table-column label="成交金额" align="center" prop="dealPrice"/>
+      <el-table-column label="取消单数" align="center" prop="cancelNum"/>
+      <el-table-column label="取消金额" align="center" prop="cancelPrice"/>
+      <el-table-column label="待发货单数" align="center" prop="pendingNum"/>
+      <el-table-column label="待发货金额" align="center" prop="pendingPrice"/>
+      <el-table-column label="发货单数" align="center" prop="invoiceNum"/>
+      <el-table-column label="发货金额" align="center" prop="invoicePrice"/>
+      <el-table-column label="签收单数" align="center" prop="signForNum"/>
+      <el-table-column label="签收金额" align="center" prop="signFPrice"/>
+      <el-table-column label="退单数" align="center" prop="chargebackNum"/>
+      <el-table-column label="退单金额" align="center" prop="chargebackPrice"/>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </div>
+</template>
+
+<script>
+import { orderDimensionStatisticsList, orderDimensionStatisticsExport } from '@/api/store/storeOrder'
+import { getCompanyList } from '@/api/company/company'
+import { getAllStoreProductCategory } from '@/api/store/storeProductCategory'
+import { listStoreProduct } from '@/api/store/storeProduct'
+import product from '@/views/oms/product/index.vue'
+
+export default {
+  name: 'CompanyBindUser',
+  data() {
+    return {
+      activeName: '1',
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 分页List
+      pageList: [],
+      // 弹出层标题
+      title: '',
+      // 是否显示弹出层
+      open: false,
+      //选中的公司
+      companyList: [],
+      spanArr: [],
+      queryDate: null,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        companyId: null,
+        userName: null,
+        companyUser: null,
+        productName: null,
+        productId: null,
+        cateName: null,
+        startDate: null,
+        endDate: null,
+        cateId: null,
+        groupType: '1'
+      },
+      //商品查询参数
+      productQueryParams: {},
+      productList: [],
+      cateIds: [],
+      categoryOptions: [],
+      // 表单参数
+      form: {},
+      pickerOptions: {
+        shortcuts: [{
+          text: '本月',
+          onClick(picker) {
+            picker.$emit('pick', [new Date(), new Date()])
+          }
+        }, {
+          text: '今年至今',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date(new Date().getFullYear(), 0)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setMonth(start.getMonth() - 2)
+            picker.$emit('pick', [start, end])
+          }
+        }]
+      }
+    }
+  },
+  created() {
+    /**
+     * 赋值默认日期
+     * **/
+    this.queryDate = this.getDefaultDateRange()
+
+    /**
+     * 查询
+     * **/
+    this.getList()
+
+    /**
+     * 销售企业下拉列表
+     * **/
+    getCompanyList().then(response => {
+      this.companyList = response.data
+    })
+
+    /**
+     * 商品标签
+     * **/
+    this.getTreeselect()
+
+    /**
+     * 获取商品
+     * **/
+    this.getProductList();
+  },
+  watch: {
+    pageList: {
+      handler() {
+        if (this.queryParams.groupType === '1') {
+          this.getSpanArr()
+        }
+      },
+      deep: true
+    },
+    'queryParams.groupType'(newVal) {
+      if (newVal === '1') {
+        this.getSpanArr()
+      }
+    }
+  },
+  methods: {
+    /** 查询企业域名分配中间表列表 */
+    getList() {
+      this.loading = true
+
+      this.queryParams.startDate = this.queryDate ? this.queryDate[0] : null
+      this.queryParams.endDate = this.queryDate ? this.queryDate[1] : null
+      this.queryParams.cateId = this.cateIds ? this.cateIds[this.cateIds.length - 1] : null
+
+      orderDimensionStatisticsList(this.queryParams).then(response => {
+        this.pageList = response.rows
+        this.total = response.total
+        this.loading = false
+      })
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        companyUserId: null,
+        bindId: null,
+        createTime: null,
+        createBy: null,
+        updateBy: null
+      }
+      this.resetForm('form')
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm('queryForm')
+      /**
+       * 赋值默认日期
+       * **/
+      this.queryDate = this.getDefaultDateRange()
+      this.cateIds = []
+      this.handleQuery()
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams
+      this.$confirm('是否确认导出所有企业域名分配中间表数据项?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.exportLoading = true
+        return orderDimensionStatisticsExport(queryParams)
+      }).then(response => {
+        this.download(response.msg)
+        this.exportLoading = false
+      }).catch(() => {
+      })
+    },
+    handleClick(tab, event) {
+      this.queryParams.groupType = tab.name
+      this.getList()
+    },
+
+    /**
+     * 赋值时间组件默认日期
+     * **/
+    getDefaultDateRange() {
+      const end = new Date()
+      const start = new Date()
+      start.setMonth(start.getMonth() - 2)
+
+      const formatDate = (date) => {
+        const year = date.getFullYear()
+        const month = String(date.getMonth() + 1).padStart(2, '0')
+        return `${year}-${month}-01`
+      }
+
+      return [formatDate(start), formatDate(end)]
+    },
+
+    getSpanArr() {
+      this.spanArr = []
+      if (this.pageList.length === 0) return
+
+      let pos = 0
+      this.spanArr.push(1)
+
+      for (let i = 1; i < this.pageList.length; i++) {
+        const currentRow = this.pageList[i]
+        const prevRow = this.pageList[i - 1]
+
+        if (currentRow.companyId === prevRow.companyId) {
+          this.spanArr[pos] += 1
+          this.spanArr.push(0)
+        } else {
+          this.spanArr.push(1)
+          pos = i
+        }
+      }
+    },
+
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (columnIndex === 0) {
+        const rowspan = this.spanArr[rowIndex]
+        return {
+          rowspan: rowspan,
+          colspan: 1
+        }
+      }
+    },
+
+    normalizer(node) {
+      const normalized = {
+        value: node.cateId,
+        label: node.cateName
+      }
+      if (node.children && node.children.length > 0) {
+        normalized.children = node.children.map(child => this.normalizer(child))
+      }
+      return normalized
+    },
+    handleTree(data, idKey, parentKey, rootId = 0) {
+      return data
+        .filter(item => item[parentKey] === rootId)
+        .map(item => {
+          const children = this.handleTree(data, idKey, parentKey, item[idKey])
+          return {
+            ...item,
+            ...(children.length > 0 ? { children } : {})
+          }
+        })
+    },
+
+    getTreeselect() {
+      getAllStoreProductCategory()
+        .then(response => {
+          if (!response.data || !Array.isArray(response.data)) {
+            console.error('分类数据格式不正确:', response.data)
+            return
+          }
+          const data = this.handleTree(response.data, 'cateId', 'pid')
+          this.categoryOptions = data.map(node => this.normalizer(node))
+          console.log('分类选项加载成功:', this.categoryOptions)
+        })
+        .catch(error => {
+          console.error('获取分类数据失败:', error)
+        })
+    },
+    /**
+     * 查询商品
+     * **/
+    getProductList() {
+      listStoreProduct(this.productQueryParams).then(response => {
+        this.productList = response.rows;
+      })
+    }
+  }
+}
+</script>

+ 18 - 18
src/views/user/darkRoom/index.vue

@@ -46,25 +46,25 @@
       </el-table-column>
       <el-table-column label="手机号码" align="center" prop="phone" width="160px"/>
       <el-table-column label="注册时间" align="center" prop="createTime" width="160px"/>
-      <el-table-column label="看课数量" align="center" prop="watchCourseCount" />
-      <el-table-column label="缺课数量" align="center" prop="missCourseCount" />
-      <el-table-column label="缺课状态" align="center" prop="missCourseStatus">
-        <template slot-scope="scope">
-          <el-tag effect="dark" type="danger"  v-if="scope.row.missCourseStatus === 1">已缺课</el-tag>
-          <el-tag effect="dark" type="success" v-else>未缺课</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column label="参与营期数量" align="center" prop="partCourseCount" width="100px"/>
+<!--      <el-table-column label="看课数量" align="center" prop="watchCourseCount" />-->
+<!--      <el-table-column label="缺课数量" align="center" prop="missCourseCount" />-->
+<!--      <el-table-column label="缺课状态" align="center" prop="missCourseStatus">-->
+<!--        <template slot-scope="scope">-->
+<!--          <el-tag effect="dark" type="danger"  v-if="scope.row.missCourseStatus === 1">已缺课</el-tag>-->
+<!--          <el-tag effect="dark" type="success" v-else>未缺课</el-tag>-->
+<!--        </template>-->
+<!--      </el-table-column>-->
+<!--      <el-table-column label="参与营期数量" align="center" prop="partCourseCount" width="100px"/>-->
       <el-table-column label="最后一次看课时间" align="center" prop="lastWatchDate"  width="160px"/>
-      <el-table-column label="看课状态" align="center" prop="courseCountStatus">
-        <template slot-scope="scope">
-          <el-tag effect="dark" type="success" v-if="scope.row.courseCountStatus === 1">正常</el-tag>
-          <el-tag effect="dark" type="info"    v-else-if="scope.row.courseCountStatus === 2">停止</el-tag>
-          <el-tag effect="dark" type="danger"  v-else>未看</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column label="停课天数" align="center" prop="stopWatchDays" />
-      <el-table-column label="完播时间" align="center" prop="completeWatchDate" width="160px"/>
+<!--      <el-table-column label="看课状态" align="center" prop="courseCountStatus">-->
+<!--        <template slot-scope="scope">-->
+<!--          <el-tag effect="dark" type="success" v-if="scope.row.courseCountStatus === 1">正常</el-tag>-->
+<!--          <el-tag effect="dark" type="info"    v-else-if="scope.row.courseCountStatus === 2">停止</el-tag>-->
+<!--          <el-tag effect="dark" type="danger"  v-else>未看</el-tag>-->
+<!--        </template>-->
+<!--      </el-table-column>-->
+<!--      <el-table-column label="停课天数" align="center" prop="stopWatchDays" />-->
+<!--      <el-table-column label="完播时间" align="center" prop="completeWatchDate" width="160px"/>-->
       <el-table-column label="标签名称" align="center" prop="tag" />
       <el-table-column label="所属销售名称" align="center" prop="companyUserNickName" width="120px"/>
       <el-table-column label="是否重粉" align="center" prop="isRepeatFans" width="120px">