瀏覽代碼

feat(report): 添加设备类型维度统计功能

- 在设备工时统计图表中新增按设备类型维度的数据聚合功能
- 添加图表维度切换控件,支持按设备和按设备类型两种统计方式
- 实现前端数据分组汇总逻辑,避免重复请求后端接口
- 更新图表标题显示逻辑以反映当前统计维度
- 在表格中新增设备类型列显示设备分类信息
- 优化图表数据处理流程,支持多维度数据转换和排序
dazhaxie 1 周之前
父節點
當前提交
514405d367
共有 1 個文件被更改,包括 60 次插入12 次删除
  1. 60 12
      src/views/report/repairworkhour/RepairWorkHour.vue

+ 60 - 12
src/views/report/repairworkhour/RepairWorkHour.vue

@@ -43,11 +43,17 @@
       </div>
 
       <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px">
-        <span style="font-weight: 600">{{ activeTab === 'user' ? '维修人工时统计图' : '设备工时统计图' }}(按总维修工时降序)</span>
-        <a-radio-group v-model="chartTop" size="small" @change="doRenderChart">
-          <a-radio-button value="top20">前20名</a-radio-button>
-          <a-radio-button value="all">全部</a-radio-button>
-        </a-radio-group>
+        <span style="font-weight: 600">{{ chartTitle }}(按总维修工时降序)</span>
+        <span>
+          <a-radio-group v-if="activeTab === 'sb'" v-model="chartDim" size="small" style="margin-right: 8px" @change="doRenderChart">
+            <a-radio-button value="sb">按设备</a-radio-button>
+            <a-radio-button value="type">按设备类型</a-radio-button>
+          </a-radio-group>
+          <a-radio-group v-model="chartTop" size="small" @change="doRenderChart">
+            <a-radio-button value="top20">前20名</a-radio-button>
+            <a-radio-button value="all">全部</a-radio-button>
+          </a-radio-group>
+        </span>
       </div>
       <a-spin :spinning="chartLoading">
         <div :id="chartContainerId" style="min-height: 400px"></div>
@@ -112,6 +118,8 @@ export default {
       chartContainerId: 'workHourChartContainer',
       // 图表展示范围:top20-前20名,all-全部(数据量大时默认前20,防止柱子过细/标签重叠)
       chartTop: 'top20',
+      // 图表聚合维度(仅按设备统计Tab):sb-按设备,type-按设备类型(前端对全量数据分组)
+      chartDim: 'sb',
       // 图表全量数据缓存,切换前20/全部时不重复请求
       chartRows: [],
       // 加载数据方法 必须为 Promise 对象
@@ -130,6 +138,12 @@ export default {
     }
   },
   computed: {
+    chartTitle () {
+      if (this.activeTab === 'user') {
+        return '维修人工时统计图'
+      }
+      return this.chartDim === 'type' ? '设备类型工时统计图' : '设备工时统计图'
+    },
     rowKey () {
       return this.activeTab === 'user' ? 'repairUserId' : 'sbId'
     },
@@ -206,6 +220,11 @@ export default {
           checked: true,
           dataIndex: 'sbName'
         },
+        {
+          title: '设备类型',
+          checked: true,
+          dataIndex: 'sbTypeName'
+        },
         ...commonColumns
       ]
     }
@@ -231,12 +250,8 @@ export default {
       fetchFn(parameter)
         .then(res => {
           const rows = (res.data && res.data.rows) || []
-          // 后端已按总维修工时降序,映射后即可直接取前20
-          this.chartRows = rows.map(r => ({
-            name: this.activeTab === 'user' ? (r.repairUserName || '-') : (r.sbName || r.sbNo || '-'),
-            totalRepairHours: Number(r.totalRepairHours || 0),
-            num: Number(r.num || 0)
-          }))
+          // 保存原始行,按图表维度分组/截取统一在 doRenderChart 处理
+          this.chartRows = rows
           this.doRenderChart()
         })
         .finally(() => {
@@ -244,7 +259,38 @@ export default {
         })
     },
     doRenderChart () {
-      let data = this.chartRows
+      let data = []
+      if (this.activeTab === 'user') {
+        data = this.chartRows.map(r => ({
+          name: r.repairUserName || '-',
+          totalRepairHours: Number(r.totalRepairHours || 0),
+          num: Number(r.num || 0)
+        }))
+      } else if (this.chartDim === 'type') {
+        // 按设备类型:前端对按设备全量数据分组汇总,次数/总工时求和,不重复请求后端
+        const groupMap = {}
+        this.chartRows.forEach(r => {
+          const key = r.sbTypeName || '未分类'
+          if (!groupMap[key]) {
+            groupMap[key] = { name: key, totalRepairHours: 0, num: 0 }
+          }
+          groupMap[key].totalRepairHours += Number(r.totalRepairHours || 0)
+          groupMap[key].num += Number(r.num || 0)
+        })
+        data = Object.keys(groupMap).map(key => {
+          const item = groupMap[key]
+          item.totalRepairHours = Math.round(item.totalRepairHours * 100) / 100
+          return item
+        })
+        data.sort((a, b) => b.totalRepairHours - a.totalRepairHours)
+      } else {
+        // 设备维度用名称(编号)区分同名设备
+        data = this.chartRows.map(r => ({
+          name: (r.sbName || '-') + '(' + (r.sbNo || '-') + ')',
+          totalRepairHours: Number(r.totalRepairHours || 0),
+          num: Number(r.num || 0)
+        }))
+      }
       if (this.chartTop === 'top20' && data.length > 20) {
         data = data.slice(0, 20)
       }
@@ -298,6 +344,8 @@ export default {
       return query
     },
     handleTabChange () {
+      // 切换维度后图表聚合维度恢复按设备
+      this.chartDim = 'sb'
       this.$nextTick(() => {
         this.$refs.table.refresh(true)
         this.loadChartData()