Bladeren bron

统计页面

Guos 1 week geleden
bovenliggende
commit
c1ba852468
2 gewijzigde bestanden met toevoegingen van 473 en 0 verwijderingen
  1. 53 0
      src/api/statistics/statistics.js
  2. 420 0
      src/views/his/statistics/comprehensiveStatistics.vue

+ 53 - 0
src/api/statistics/statistics.js

@@ -323,3 +323,56 @@ export function thisMonthRecvCount(param){
     params: param
   })
 }
+
+/**
+ * 综合统计
+ * @returns {*}
+ */
+export function getStatisticsData(data) {
+  return request({
+    url: '/statistic/manage/statisticMain',
+    method: 'post',
+    data: data  // 使用 data 而不是 params
+  })
+}
+
+/**
+ * 获取下拉
+ * @returns {*}
+ */
+export function getSearchCompanyInfo(param){
+  return request({
+    url: '/statistic/manage/getSearchCompanyInfo',
+    method: 'get',
+    params: param
+  })
+}
+
+/**
+ * 获取下拉
+ * @returns {*}
+ */
+export function getSearchDeptInfo(param){
+  return request({
+    url: '/statistic/manage/getSearchDeptInfo',
+    method: 'get',
+    params: param
+  })
+}
+
+/**
+ * 获取下拉
+ * @returns {*}
+ */
+export function getSearchUserInfo(param){
+  return request({
+    url: '/statistic/manage/getSearchUserInfo',
+    method: 'get',
+    params: param
+  })
+}
+
+
+
+
+

+ 420 - 0
src/views/his/statistics/comprehensiveStatistics.vue

@@ -0,0 +1,420 @@
+<template>
+  <div class="app-container">
+    <div class="app-content">
+      <div class="title">综合统计看板</div>
+
+      <el-form class="search-form" :inline="true" label-width="90px">
+
+        <!-- 时间范围选择 -->
+        <el-form-item label="时间范围">
+          <el-date-picker
+            v-model="dateRange"
+            type="daterange"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            value-format="yyyy-MM-dd"
+            :picker-options="pickerOptions">
+          </el-date-picker>
+        </el-form-item>
+
+        <!-- 统计维度选择 -->
+        <el-form-item label="统计维度">
+          <el-select v-model="queryParams.dimension" placeholder="请选择统计维度" @change="handleDimensionChange" clearable>
+            <el-option label="个人" :value="1"></el-option>
+            <el-option label="公司" :value="2"></el-option>
+            <el-option label="部门" :value="3"></el-option>
+          </el-select>
+        </el-form-item>
+
+        <!-- 公司选择 -->
+        <el-form-item label="选择公司" v-if="queryParams.dimension">
+          <el-select
+            v-model="queryParams.companyId"
+            placeholder="请选择公司"
+            @change="handleCompanyChange"
+            clearable
+            :disabled="!queryParams.dimension">
+            <el-option
+              v-for="company in companyList"
+              :key="company.companyId"
+              :label="company.companyName"
+              :value="company.companyId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+
+        <!-- 部门选择 -->
+        <el-form-item label="选择部门" v-if="showDepartmentSelect">
+          <el-select
+            v-model="queryParams.deptId"
+            placeholder="请选择部门"
+            @change="handleDeptChange"
+            clearable
+            :disabled="!queryParams.companyId">
+            <el-option
+              v-for="dept in deptList"
+              :key="dept.deptId"
+              :label="dept.deptName"
+              :value="dept.deptId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+
+        <!-- 人员选择 -->
+        <el-form-item label="选择人员" v-if="showUserSelect">
+          <el-select
+            v-model="queryParams.userId"
+            placeholder="请选择人员"
+            clearable
+            :disabled="!queryParams.deptId">
+            <el-option
+              v-for="user in userList"
+              :key="user.userId"
+              :label="user.userName"
+              :value="user.userId">
+            </el-option>
+          </el-select>
+        </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>
+    </div>
+
+    <!-- 数据表格 -->
+    <div class="table-section">
+      <el-table :data="paginatedTableData" border style="width: 100%" height="400">
+        <el-table-column prop="companyName" label="公司名称" />
+        <el-table-column prop="deptName" label="部门名称" />
+        <el-table-column prop="userName" label="人员姓名" />
+        <el-table-column prop="lineNum" label="进线数" />
+        <el-table-column prop="activeNum" label="激活数" />
+        <el-table-column prop="completeNum" label="完课数" />
+        <el-table-column prop="answerNum" label="答题数" />
+        <el-table-column prop="redPacketNum" label="红包领取数" />
+      </el-table>
+
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="currentPage"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="tableData.length"
+        style="margin-top: 20px; text-align: right;">
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getStatisticsData, getSearchUserInfo, getSearchCompanyInfo, getSearchDeptInfo } from "@/api/statistics/statistics";
+
+export default {
+  data() {
+    return {
+      companyList: [],
+      deptList: [],
+      userList: [],
+      rawData: [],
+      tableData: [],
+      currentPage: 1,
+      pageSize: 20,
+      dateRange: [],
+      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]);
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      queryParams: {
+        dimension: null,
+        companyId: null,
+        deptId: null,
+        userId: null
+      }
+    };
+  },
+
+  computed: {
+    paginatedTableData() {
+      const start = (this.currentPage - 1) * this.pageSize;
+      const end = start + this.pageSize;
+      return this.tableData.slice(start, end);
+    },
+
+    showDepartmentSelect() {
+      return this.queryParams.dimension &&
+        (this.queryParams.dimension === 3 || this.queryParams.dimension === 1) &&
+        this.queryParams.companyId;
+    },
+
+    showUserSelect() {
+      return this.queryParams.dimension === 1 &&
+        this.queryParams.companyId &&
+        this.queryParams.deptId;
+    }
+  },
+
+  mounted() {
+    // 设置默认时间为当天
+    const today = new Date();
+    this.dateRange = [today, today];
+    // 默认设置统计维度为公司
+    this.queryParams.dimension = 2;
+    this.loadData();
+  },
+
+  methods: {
+    loadData() {
+      // 使用 getSearchCompanyInfo 获取公司下拉数据
+      getSearchCompanyInfo().then(response => {
+        this.companyList = response.data || [];
+
+        // 默认选择第一个公司(如果存在)
+        if (this.companyList.length > 0) {
+          this.queryParams.companyId = this.companyList[0].companyId;
+          // 加载该公司的部门数据
+          return this.loadDeptData(this.queryParams.companyId);
+        }
+      }).then(() => {
+        // 在公司和部门默认选择完成后,请求统计数据
+        return this.fetchStatisticsData();
+      }).catch(error => {
+        console.error('数据加载失败:', error);
+        this.$message.error('数据加载失败');
+      });
+    },
+
+    loadDeptData(companyId) {
+      return getSearchDeptInfo({ id: companyId }).then(response => {
+        this.deptList = response.data || [];
+
+        // 默认选择第一个部门(如果存在)
+        if (this.deptList.length > 0) {
+          this.queryParams.deptId = this.deptList[0].deptId;
+        }
+      }).catch(error => {
+        console.error('部门数据加载失败:', error);
+        this.$message.error('部门数据加载失败');
+      });
+    },
+
+    fetchStatisticsData() {
+      // 构造请求参数对象
+      const params = {
+        dimension: this.queryParams.dimension,
+        startTime: this.formatDate(this.dateRange[0]),
+        endTime: this.formatDate(this.dateRange[1])
+      };
+
+      // 根据维度设置id参数
+      if (this.queryParams.dimension === 1 && this.queryParams.userId) {
+        params.id = this.queryParams.userId;
+      } else if (this.queryParams.dimension === 2 && this.queryParams.companyId) {
+        params.id = this.queryParams.companyId;
+      } else if (this.queryParams.dimension === 3 && this.queryParams.deptId) {
+        params.id = this.queryParams.deptId;
+      }
+
+      // 以POST方式发送请求体
+      return getStatisticsData(params).then(response => {
+        this.rawData = response.data || [];
+        this.tableData = [...this.rawData];
+        this.currentPage = 1;
+      }).catch(error => {
+        console.error('统计数据加载失败:', error);
+        this.$message.error('统计数据加载失败');
+      });
+    },
+
+    formatDate(date) {
+      if (!date) return '';
+      const d = new Date(date);
+      const year = d.getFullYear();
+      const month = String(d.getMonth() + 1).padStart(2, '0');
+      const day = String(d.getDate()).padStart(2, '0');
+      return `${year}-${month}-${day}`;
+    },
+
+    handleCompanyChange(companyId) {
+      this.queryParams.deptId = null;
+      this.queryParams.userId = null;
+      this.deptList = [];
+      this.userList = [];
+
+      if (!companyId) return;
+
+      // 使用 getSearchDeptInfo 获取部门下拉数据
+      getSearchDeptInfo({ id: companyId }).then(response => {
+        this.deptList = response.data || [];
+
+        // 默认选择第一个部门(如果存在)
+        // 仅在部门维度或个人维度下默认选择第一个部门
+        if (this.deptList.length > 0 &&
+          (this.queryParams.dimension === 3 || this.queryParams.dimension === 1)) {
+          this.queryParams.deptId = this.deptList[0].deptId;
+
+          // 如果是个人维度,还需要加载用户数据
+          if (this.queryParams.dimension === 1 && this.queryParams.deptId) {
+            this.loadUserData(this.queryParams.deptId);
+          }
+        }
+      }).catch(error => {
+        console.error('部门数据加载失败:', error);
+        this.$message.error('部门数据加载失败');
+      });
+    },
+
+    // 新增加载用户数据的方法
+    loadUserData(deptId) {
+      if (!deptId) return;
+
+      getSearchUserInfo({ id: deptId }).then(response => {
+        this.userList = response.data || [];
+
+        // 可以选择默认选中第一个用户
+        if (this.userList.length > 0) {
+          // this.queryParams.userId = this.userList[0].userId;
+        }
+      }).catch(error => {
+        console.error('人员数据加载失败:', error);
+        this.$message.error('人员数据加载失败');
+      });
+    },
+
+    handleDeptChange(deptId) {
+      this.queryParams.userId = null;
+      this.userList = [];
+
+      if (!deptId) return;
+
+      // 使用 getSearchUserInfo 获取人员下拉数据
+      getSearchUserInfo({ id: deptId }).then(response => {
+        this.userList = response.data || [];
+
+        // 在个人维度下,默认选择第一个用户(可选)
+        if (this.userList.length > 0 && this.queryParams.dimension === 1) {
+          // this.queryParams.userId = this.userList[0].userId;
+        }
+      }).catch(error => {
+        console.error('人员数据加载失败:', error);
+        this.$message.error('人员数据加载失败');
+      });
+    },
+
+    handleQuery() {
+      // 触发统计数据请求
+      this.fetchStatisticsData();
+    },
+
+    handleDimensionChange() {
+      // 重置后续选择项
+      this.queryParams.companyId = null;
+      this.queryParams.deptId = null;
+      this.queryParams.userId = null;
+      this.deptList = [];
+      this.userList = [];
+    },
+
+    resetQuery() {
+      this.queryParams = {
+        dimension: null,
+        companyId: null,
+        deptId: null,
+        userId: null
+      };
+      // 重置时间为当天
+      const today = new Date();
+      this.dateRange = [today, today];
+      this.deptList = [];
+      this.userList = [];
+      this.tableData = [...this.rawData];
+      this.currentPage = 1;
+    },
+
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.currentPage = 1;
+    },
+
+    handleCurrentChange(val) {
+      this.currentPage = val;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.app-container {
+  border: 1px solid #e6e6e6;
+  padding: 12px;
+  background-color: #f5f7fa;
+}
+
+.app-content {
+  background-color: white;
+  padding: 20px;
+  border-radius: 4px;
+  margin-bottom: 20px;
+}
+
+.title {
+  text-align: center;
+  font-size: 24px;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 20px;
+}
+
+.search-form {
+  display: flex;
+  justify-content: center;
+  flex-wrap: wrap;
+}
+
+.search-form .el-form-item {
+  margin-bottom: 10px;
+}
+
+.table-section {
+  background-color: white;
+  padding: 20px;
+  border-radius: 4px;
+}
+
+.table-section .el-table {
+  width: 100% !important;
+}
+
+@media (min-width: 1200px) {
+  .table-section {
+    padding: 20px 50px;
+  }
+}
+</style>