Browse Source

feat: 系统月度使用情况图表形式展示完成

zhangying 10 months ago
parent
commit
6c31d66812

+ 59 - 0
vue/package-lock.json

@@ -19,6 +19,7 @@
         "core-js": "~3.24.1",
         "crypto-js": "^4.1.1",
         "dayjs": "~1.11.5",
+        "echarts": "^5.5.0",
         "file-saver": "~2.0.5",
         "lodash-es": "~4.17.21",
         "mitt": "~3.0.0",
@@ -7533,6 +7534,20 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/echarts": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.5.0.tgz",
+      "integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==",
+      "dependencies": {
+        "tslib": "2.3.0",
+        "zrender": "5.5.0"
+      }
+    },
+    "node_modules/echarts/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+    },
     "node_modules/ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
@@ -18995,6 +19010,19 @@
       "resolved": "https://registry.npmmirror.com/yallist/-/yallist-2.1.2.tgz",
       "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
       "dev": true
+    },
+    "node_modules/zrender": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.5.0.tgz",
+      "integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==",
+      "dependencies": {
+        "tslib": "2.3.0"
+      }
+    },
+    "node_modules/zrender/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
     }
   },
   "dependencies": {
@@ -24569,6 +24597,22 @@
       "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==",
       "dev": true
     },
+    "echarts": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.5.0.tgz",
+      "integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==",
+      "requires": {
+        "tslib": "2.3.0",
+        "zrender": "5.5.0"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+        }
+      }
+    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
@@ -33178,6 +33222,21 @@
           "dev": true
         }
       }
+    },
+    "zrender": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.5.0.tgz",
+      "integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==",
+      "requires": {
+        "tslib": "2.3.0"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+        }
+      }
     }
   }
 }

+ 1 - 0
vue/package.json

@@ -42,6 +42,7 @@
     "core-js": "~3.24.1",
     "crypto-js": "^4.1.1",
     "dayjs": "~1.11.5",
+    "echarts": "^5.5.0",
     "file-saver": "~2.0.5",
     "lodash-es": "~4.17.21",
     "mitt": "~3.0.0",

+ 96 - 0
vue/src/utils/echartsUtil.ts

@@ -0,0 +1,96 @@
+import * as echarts from 'echarts';
+
+/**
+ * 柱状图表初始化
+ * @param xTitleList X轴数据
+ * @param yValueList Y轴数据
+ * @param domId 目标DOM元素ID
+ * @param title 图表标题
+ */
+export function initBarImageTable(xTitleList: any, yValueList: any, domId: any, title: string) {
+  const chartDom = document.getElementById(domId);
+  const myChart = echarts.init(chartDom);
+  let option;
+
+  option = {
+    title: {
+      text: title,
+    },
+    toolbox: {
+      feature: {
+        saveAsImage: {}
+      }
+    },
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: xTitleList
+    },
+    yAxis: {
+      type: 'value'
+    },
+    series: [
+      {
+        data: yValueList,
+        type: 'bar'
+      }
+    ]
+  };
+
+  option && myChart.setOption(option);
+}
+
+/**
+ * 折线图表初始化
+ * @param xTitleList X轴标题数据
+ * @param seriesList 折线数据内容
+ * @param domId 目标DOM元素ID
+ * @param title 图表标题
+ */
+export function initLineImageTable(xTitleList: any, seriesList: any, domId: any, title: string) {
+  const chartDom = document.getElementById(domId);
+  const myChart = echarts.init(chartDom);
+  let option;
+
+  option = {
+    title: {
+      text: title
+    },
+    tooltip: {
+      trigger: 'axis'
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    toolbox: {
+      feature: {
+        saveAsImage: {}
+      }
+    },
+    xAxis: {
+      type: 'category',
+      boundaryGap: false,
+      data: xTitleList
+    },
+    yAxis: {
+      type: 'value'
+    },
+    series: seriesList
+  };
+
+  option && myChart.setOption(option);
+}

+ 135 - 27
vue/src/views/statistics/MonthSystemApplyCount.vue

@@ -15,7 +15,7 @@
           </a-form-item>
         </a-col>
         <a-col :span="6" style="text-align: left">
-          <a-button type="primary" html-type="submit" @click="loadData">查询</a-button>
+          <a-button type="primary" html-type="submit" @click="loadData" :loading="tableLoading">查询</a-button>
           <a-button style="margin: 0 8px" @click="onReset">重置</a-button>
         </a-col>
       </a-row>
@@ -24,7 +24,7 @@
     <a-row class="edit-operation" style="margin-bottom: 20px">
       <a-col :span="24" class="flex-space-between">
         <div>
-          <a-radio-group v-model:value="dataType" button-style="solid">
+          <a-radio-group v-model:value="dataType" button-style="solid" @change="dataTypeChange">
             <a-radio-button value="table">表格</a-radio-button>
             <a-radio-button value="imageTable">图表</a-radio-button>
           </a-radio-group>
@@ -45,17 +45,21 @@
                bordered>
       </a-table>
     </div>
-    <div v-show="dataType == 'imageTable'">
-
+    <div v-show="dataType == 'imageTable'" class="image-table-box">
+      <div id="companyImageTable" class="echarts-main"></div>
+      <div id="postImageTable" class="echarts-main"></div>
+      <div id="jobUserImageTable" class="echarts-main"></div>
+      <div id="weekCountImageTable" class="echarts-main"></div>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import {computed, onMounted, reactive, ref} from "vue";
+import {computed, nextTick, onMounted, reactive, ref} from "vue";
 import {getMonthSystemDataCount} from "@/api/statistics";
 import dayjs from "dayjs";
 import BExportExcel from "@/components/basic/excel/exportExcel/exportExcel.vue";
+import {initBarImageTable, initLineImageTable} from "@/utils/echartsUtil";
 
 // 查询条件
 const searchParams = reactive({
@@ -87,40 +91,125 @@ const originalColumns = ref<Array<any>>([
     ]
   }
 ])
+// 查询方法未处理的初始数据
+const searchOriginalList = ref();
 
 // 数据加载
 function loadData() {
   tableLoading.value = true;
   getMonthSystemDataCount(searchParams).then((result: any) => {
-    console.log(result);
-    // 初始化数据,获取到区县名称
-    let arr = new Array<any>();
-    if (result && Object.keys(result).length > 0) {
-      // 获取到查询结果Map中的第一个键值对,解析获取到县区信息,填充进初始数组中
-      result[Object.keys(result)[0]].forEach((item: any) => {
-        arr.push({
-          regionCode: item.regionCode,
-          regionName: item.regionName
-        });
-      });
+    searchOriginalList.value = result;
+    if (dataType.value == 'table') {
+      analysisByTable();
     }
-    // 初始化表结构
-    originalColumns.value = [{
-      title: '项目', dataIndex: 'regionName', key: 'regionName', align: "center", width: 200, fixed: 'left'
-    }]
-    // 解析第一周到第五周的统计数据
-    for (let i = 1; i <= 5; i++) {
-      // 填充数据
-      initTableData(result, '第' + i + '周', arr, i + 'z');
+    if (dataType.value == 'imageTable') {
+      analysisByImageTable();
     }
-    // 解析汇总数据
-    initTableData(result, '汇总', arr, 'hz');
-    systemApplyCount.value = arr;
   }).finally(() => {
     tableLoading.value = false;
   })
 }
 
+// 解析生成表格内容
+function analysisByTable() {
+  let arr = new Array<any>();
+  // 获取到区县名称信息
+  if (searchOriginalList.value && Object.keys(searchOriginalList.value).length > 0) {
+    // 获取到查询结果Map中的第一个键值对,解析获取到县区信息,填充进初始数组中
+    searchOriginalList.value[Object.keys(searchOriginalList.value)[0]].forEach((item: any) => {
+      arr.push({
+        regionCode: item.regionCode,
+        regionName: item.regionName
+      });
+    });
+  }
+  // 初始化表结构
+  originalColumns.value = [{
+    title: '项目', dataIndex: 'regionName', key: 'regionName', align: "center", width: 200, fixed: 'left'
+  }]
+
+  // 解析第一周到第五周的统计数据
+  for (let i = 1; i <= 5; i++) {
+    // 填充数据
+    initTableData(searchOriginalList.value, '第' + i + '周', arr, i + 'z');
+  }
+  // 解析汇总数据
+  initTableData(searchOriginalList.value, '汇总', arr, 'hz');
+  systemApplyCount.value = arr;
+}
+
+function analysisByImageTable() {
+  let regionNameList = new Array<any>();
+  let weekNameList = new Array<any>();
+
+  // 获取到区县名称信息
+  if (searchOriginalList.value && Object.keys(searchOriginalList.value).length > 0) {
+    // 获取到查询结果Map中的第一个键值对,解析获取到县区信息,填充进初始数组中
+    searchOriginalList.value[Object.keys(searchOriginalList.value)[0]].forEach((item: any) => {
+      if (item.regionCode != 100) {
+        regionNameList.push(item.regionName);
+      }
+    });
+  }
+  // 初始化折线图数据
+  let weekLineData = [
+    {
+      name: '驿站人员数量',
+      type: 'line',
+      data: new Array<any>()
+    },
+    {
+      name: '录入企业数量',
+      type: 'line',
+      data: new Array<any>()
+    },
+    {
+      name: '收集岗位数量',
+      type: 'line',
+      data: new Array<any>()
+    },
+    {
+      name: '登记求职人数',
+      type: 'line',
+      data: new Array<any>()
+    },
+  ]
+
+  // 解析第一周到第五周的统计数据
+  for (let i = 1; i <= 5; i++) {
+    if (searchOriginalList.value['第' + i + '周']) {
+      weekNameList.push('第' + i + '周');
+
+      // 查询获取到每周的合计总数,填充进折线图数据中
+      const hjData = searchOriginalList.value['第' + i + '周'].find(item => item.regionCode == '100');
+      if (hjData) {
+        weekLineData[0].data.push(hjData.siteUserCount);
+        weekLineData[1].data.push(hjData.companyCount);
+        weekLineData[2].data.push(hjData.postCount);
+        weekLineData[3].data.push(hjData.jobUserCount);
+      }
+    }
+  }
+
+  // 收集图表数据
+  let companyImageTableData = new Array<any>();
+  let postImageTableData = new Array<any>();
+  let jobUserImageTableData = new Array<any>();
+  searchOriginalList.value['汇总'].forEach((item: any) => {
+    if (item.regionCode != 100) {
+      companyImageTableData.push(item.companyCount)
+      postImageTableData.push(item.postCount)
+      jobUserImageTableData.push(item.jobUserCount)
+    }
+  })
+
+  // 初始化图表
+  initBarImageTable(regionNameList, companyImageTableData, "companyImageTable", '录入企业数量');
+  initBarImageTable(regionNameList, postImageTableData, "postImageTable", "收集岗位数量");
+  initBarImageTable(regionNameList, jobUserImageTableData, "jobUserImageTable", "登记求职人数");
+  initLineImageTable(weekNameList, weekLineData, "weekCountImageTable", "全市就业驿站运行概括");
+}
+
 // 查询表单
 function onReset() {
   searchParams.dateStr = dayjs(new Date().getDate()).format("YYYY-MM");
@@ -187,6 +276,15 @@ function initTableData(result: any, resultKey: any, arr: any, arrNewKey: any) {
   })
 }
 
+function dataTypeChange(value: any) {
+  if (dataType.value == 'table') {
+    analysisByTable();
+  }
+  if (dataType.value == 'imageTable') {
+    nextTick(analysisByImageTable);
+  }
+}
+
 onMounted(() => {
   searchParams.dateStr = dayjs().format("YYYY-MM");
   loadData();
@@ -201,5 +299,15 @@ export default {
 </script>
 
 <style scoped>
+.image-table-box {
+  width: 100%;
+  height: 100%;
+  display: grid;
+  grid-template-columns: repeat(2, minmax(0, 1fr));
+  gap: 10px;
 
+  .echarts-main {
+    height: 280px;
+  }
+}
 </style>