From 91513e171078ed6b0887f87b9fced33895d6d3fb Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期二, 08 七月 2025 08:35:50 +0800
Subject: [PATCH] 2025.7.8

---
 src/views/management/TaskSummary.vue |  480 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 458 insertions(+), 22 deletions(-)

diff --git a/src/views/management/TaskSummary.vue b/src/views/management/TaskSummary.vue
index 4bc0909..1926d9f 100644
--- a/src/views/management/TaskSummary.vue
+++ b/src/views/management/TaskSummary.vue
@@ -1,26 +1,462 @@
 <template>
-  <el-row> 宸℃煡姹囨�� </el-row>
-  <el-row>
-    <el-col :span="8">
-      <TaskSummaryItem title="浠婃棩姹囨��"></TaskSummaryItem>
-    </el-col>
-    <el-col :span="8">
-      <TaskSummaryItem title="鍛ㄥ害姹囨��"></TaskSummaryItem>
-    </el-col>
-    <el-col :span="8">
-      <TaskSummaryItem title="鏈堝害姹囨��"></TaskSummaryItem>
-    </el-col>
-  </el-row>
-  <el-row>
-    <el-col :span="12">
-      <TaskSummaryItem title="瀛e害姹囨��"></TaskSummaryItem>
-    </el-col>
-    <el-col :span="12">
-      <TaskSummaryItem title="骞村害姹囨��"></TaskSummaryItem>
-    </el-col>
-  </el-row>
+  <BaseCard title="宸℃煡姹囨��">
+    <!-- <el-row> 宸℃煡姹囨�� </el-row> -->
+    <el-segmented v-model="value" :options="options" block />
+    <div v-show="value == '浠婃棩姹囨��'">
+      <div ref="echart1" class="bar-chart"></div>
+    </div>
+    <div v-show="value == '鏈懆姹囨��'">
+      <div ref="echart2" class="bar-chart"></div>
+    </div>
+    <div v-show="value == '涓婂懆姹囨��'">
+      <div ref="echart3" class="bar-chart"></div>
+    </div>
+    <div v-show="value == '鏈湀姹囨��'">
+      <div ref="echart4" class="bar-chart"></div>
+    </div>
+  </BaseCard>
 </template>
 
-<script setup></script>
+<script setup>
+/**
+ * 1. 鍖哄煙鍒嗙被缁熻鏇村姞鐏垫椿
+ */
+import * as echarts from 'echarts'
+import { ref, onMounted } from 'vue'
+import dayjs from 'dayjs'
+import taskApi from '@/api/fysp/taskApi.js'
 
-<style scoped></style>
+const props = defineProps({
+  height: String
+})
+
+const emits = defineEmits(['update:height'])
+
+const value = ref('鏈湀姹囨��')
+const options = ['浠婃棩姹囨��', '鏈懆姹囨��', '涓婂懆姹囨��', '鏈湀姹囨��']
+
+const subtaskToday = ref([])
+const subtaskWeek = ref([])
+const subtaskLastWeek = ref([])
+const subtaskMonth = ref([])
+
+const echart1 = ref()
+const echart2 = ref()
+const echart3 = ref()
+const echart4 = ref()
+let echartToday
+let echartWeek
+let echartLastWeek
+let echartMonth
+
+function getParams(type) {
+  const d = dayjs()
+  return {
+    starttime: d.startOf(type).format('YYYY-MM-DD HH:mm:ss'),
+    endtime: d.endOf(type).format('YYYY-MM-DD HH:mm:ss')
+  }
+}
+
+function fetchSubtaskToday() {
+  const area = getParams('day')
+  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
+    subtaskToday.value = res.data
+    const series = refreshChartData(res.data)
+    setOption(echartToday, series)
+  })
+}
+
+function fetchSubtaskThisWeek() {
+  const area = getParams('week')
+  // 淇敼鏃舵涓哄懆涓�鍒板懆鏃�
+  area.starttime = dayjs(area.starttime).add(1, 'day').format('YYYY-MM-DD HH:mm:ss')
+  area.endtime = dayjs(area.endtime).add(1, 'day').format('YYYY-MM-DD HH:mm:ss')
+  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
+    subtaskWeek.value = res.data
+    const series = refreshChartData(res.data)
+    setOption(echartWeek, series)
+  })
+}
+
+function fetchSubtaskLastWeek() {
+  const area = getParams('week')
+  // 淇敼鏃舵涓哄懆涓�鍒板懆鏃�
+  area.starttime = dayjs(area.starttime).add(-6, 'day').format('YYYY-MM-DD HH:mm:ss')
+  area.endtime = dayjs(area.endtime).add(-6, 'day').format('YYYY-MM-DD HH:mm:ss')
+  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
+    subtaskLastWeek.value = res.data
+    const series = refreshChartData(res.data)
+    setOption(echartLastWeek, series)
+  })
+}
+
+function fetchSubtaskThisMonth() {
+  const area = getParams('month')
+  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
+    subtaskMonth.value = res.data
+    const series = refreshChartData(res.data)
+    setOption(echartMonth, series)
+  })
+}
+
+onMounted(() => {
+  echartToday = echarts.init(echart1.value)
+  echartWeek = echarts.init(echart2.value)
+  echartLastWeek = echarts.init(echart3.value)
+  echartMonth = echarts.init(echart4.value)
+  fetchSubtaskToday()
+  fetchSubtaskThisWeek()
+  fetchSubtaskLastWeek()
+  fetchSubtaskThisMonth()
+})
+
+/**chart**********************************************************************/
+function setOption(echart, series) {
+  const option = {
+    textStyle: {
+      color: 'white'
+    },
+    legend: {
+      textStyle: {
+        color: 'white'
+      }
+    },
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: [
+      {
+        type: 'value'
+      }
+    ],
+    yAxis: [
+      {
+        type: 'category',
+        data: ['澶嶆牳鏁�', '鏁存敼鏁�', '闂鏁�', '瀹屾垚閲�']
+      }
+    ],
+    series: series
+  }
+  echart.setOption(option)
+}
+
+function refreshChartData(dataList) {
+  // 浠诲姟閲忋�侀棶棰樻暟銆佹暣鏀规暟
+  // 浠诲姟閲�
+  const totalCount = {
+    numByTotal: {},
+    numByDistrict: {},
+    numByStreet: {},
+    numByScene: {},
+    numByUser: {}
+  }
+  // 闂鏁�
+  const proCount = {
+    numByTotal: {},
+    numByDistrict: {},
+    numByStreet: {},
+    numByScene: {},
+    numByUser: {}
+  }
+  // 鏁存敼鏁�
+  const changeCount = {
+    numByTotal: {},
+    numByDistrict: {},
+    numByStreet: {},
+    numByScene: {},
+    numByUser: {}
+  }
+  // 澶嶆牳鏁�
+  const reCheckCount = {
+    numByTotal: {},
+    numByDistrict: {},
+    numByStreet: {},
+    numByScene: {},
+    numByUser: {}
+  }
+  const historySceneId = []
+
+  dataList.forEach((d) => {
+    const tName = '鎬昏'
+    const dName = d.subtask.districtname
+    const townName = d.scene.townname
+    const sType = d.sceneType
+    const uName = d.subtask.deployerrealname
+
+    // 浠诲姟閲忔�昏
+    totalCount.numByTotal[tName] = totalCount.numByTotal[tName]
+      ? totalCount.numByTotal[tName] + 1
+      : 1
+    // 浠诲姟閲忓垎鍖哄幙
+    totalCount.numByDistrict[dName] = totalCount.numByDistrict[dName]
+      ? totalCount.numByDistrict[dName] + 1
+      : 1
+    // 浠诲姟閲忓垎琛楅晣
+    totalCount.numByStreet[townName] = totalCount.numByStreet[townName]
+      ? totalCount.numByStreet[townName] + 1
+      : 1
+    // 浠诲姟閲忓垎鍦烘櫙绫诲瀷
+    totalCount.numByScene[sType] = totalCount.numByScene[sType]
+      ? totalCount.numByScene[sType] + 1
+      : 1
+    // 浠诲姟閲忓垎鐢ㄦ埛
+    totalCount.numByUser[uName] = totalCount.numByUser[uName] ? totalCount.numByUser[uName] + 1 : 1
+
+    // 闂鏁版�昏
+    proCount.numByTotal[tName] = proCount.numByTotal[tName]
+      ? proCount.numByTotal[tName] + d.proCheckedNum
+      : d.proCheckedNum
+    // 闂鏁板垎鍖哄幙
+    proCount.numByDistrict[dName] = proCount.numByDistrict[dName]
+      ? proCount.numByDistrict[dName] + d.proCheckedNum
+      : d.proCheckedNum
+    // 闂鏁板垎琛楅晣
+    proCount.numByStreet[townName] = proCount.numByStreet[townName]
+      ? proCount.numByStreet[townName] + d.proCheckedNum
+      : d.proCheckedNum
+    // 闂鏁板垎鍦烘櫙绫诲瀷
+    proCount.numByScene[sType] = proCount.numByScene[sType]
+      ? proCount.numByScene[sType] + d.proCheckedNum
+      : d.proCheckedNum
+    // 闂鏁板垎鐢ㄦ埛
+    proCount.numByUser[uName] = proCount.numByUser[uName]
+      ? proCount.numByUser[uName] + d.proCheckedNum
+      : d.proCheckedNum
+
+    // 鏁存敼鏁版�昏
+    changeCount.numByTotal[tName] = changeCount.numByTotal[tName]
+      ? changeCount.numByTotal[tName] + d.changeCheckedNum
+      : d.changeCheckedNum
+    // 鏁存敼鏁板垎鍖哄幙
+    changeCount.numByDistrict[dName] = changeCount.numByDistrict[dName]
+      ? changeCount.numByDistrict[dName] + d.changeCheckedNum
+      : d.changeCheckedNum
+    // 鏁存敼鏁板垎琛楅晣
+    changeCount.numByStreet[townName] = changeCount.numByStreet[townName]
+      ? changeCount.numByStreet[townName] + d.changeCheckedNum
+      : d.changeCheckedNum
+    // 鏁存敼鏁板垎鍦烘櫙绫诲瀷
+    changeCount.numByScene[sType] = changeCount.numByScene[sType]
+      ? changeCount.numByScene[sType] + d.changeCheckedNum
+      : d.changeCheckedNum
+    // 鏁存敼鏁板垎鐢ㄦ埛
+    changeCount.numByUser[uName] = changeCount.numByUser[uName]
+      ? changeCount.numByUser[uName] + d.changeCheckedNum
+      : d.changeCheckedNum
+
+    if (historySceneId.length == 0) {
+      reCheckCount.numByTotal[tName] = 0
+      reCheckCount.numByDistrict[dName] = 0
+      reCheckCount.numByScene[sType] = 0
+      reCheckCount.numByUser[uName] = 0
+    } else if (historySceneId.indexOf(d.sceneId) != -1) {
+      // 澶嶆牳鏁版�昏
+      reCheckCount.numByTotal[tName] = reCheckCount.numByTotal[tName]
+        ? reCheckCount.numByTotal[tName] + 1
+        : 1
+      // 澶嶆牳鏁板垎鍖哄幙
+      reCheckCount.numByDistrict[dName] = reCheckCount.numByDistrict[dName]
+        ? reCheckCount.numByDistrict[dName] + 1
+        : 1
+      // 澶嶆牳鏁板垎琛楅晣
+      reCheckCount.numByStreet[townName] = reCheckCount.numByStreet[townName]
+        ? reCheckCount.numByStreet[townName] + 1
+        : 1
+      // 澶嶆牳鏁板垎鍦烘櫙绫诲瀷
+      reCheckCount.numByScene[sType] = reCheckCount.numByScene[sType]
+        ? reCheckCount.numByScene[sType] + 1
+        : 1
+      // 澶嶆牳鏁板垎鐢ㄦ埛
+      reCheckCount.numByUser[uName] = reCheckCount.numByUser[uName]
+        ? reCheckCount.numByUser[uName] + 1
+        : 1
+    } else {
+      historySceneId.push(d.sceneId)
+    }
+  })
+
+  let series = {}
+  parseSeries(series, reCheckCount)
+  parseSeries(series, changeCount)
+  parseSeries(series, proCount)
+  parseSeries(series, totalCount)
+
+  const res = []
+  for (const key in series) {
+    const e = series[key]
+    res.push(e)
+  }
+
+  return res
+}
+
+function parseSeries(series, c) {
+  // c.numByTotal
+  // c.numByDistrict
+  // c.numByScene
+  // c.numByUser
+
+  for (const key in c.numByTotal) {
+    const value = c.numByTotal[key]
+    if (series[key]) {
+      series[key].data.push(value)
+    } else {
+      series[key] = {
+        name: key,
+        type: 'bar',
+        emphasis: {
+          focus: 'series'
+        },
+        label: {
+          show: true,
+          formatter: '{c}'
+          // position: [0, 10],
+        },
+        data: [value]
+      }
+    }
+  }
+  for (const key in c.numByDistrict) {
+    const value = c.numByDistrict[key]
+    if (series[key]) {
+      series[key].data.push(value)
+    } else {
+      series[key] = {
+        name: `鍖哄幙锛�${key}`,
+        type: 'bar',
+        stack: 'district',
+        emphasis: {
+          focus: 'series'
+        },
+        label: {
+          show: true,
+          formatter: '{c}'
+          // position: 'top',
+        },
+        data: [value]
+      }
+    }
+  }
+  // for (const key in c.numByStreet) {
+  //   const value = c.numByStreet[key]
+  //   if (series[key]) {
+  //     series[key].data.push(value)
+  //   } else {
+  //     series[key] = {
+  //       name: `琛楅晣锛�${key}`,
+  //       type: 'bar',
+  //       stack: 'street',
+  //       emphasis: {
+  //         focus: 'series'
+  //       },
+  //       label: {
+  //         show: true,
+  //         formatter: '{c}'
+  //         // position: 'top',
+  //       },
+  //       data: [value]
+  //     }
+  //   }
+  // }
+  for (const key in c.numByScene) {
+    const value = c.numByScene[key]
+    if (series[key]) {
+      series[key].data.push(value)
+    } else {
+      series[key] = {
+        name: `鍦烘櫙锛�${key}`,
+        type: 'bar',
+        stack: 'scene',
+        emphasis: {
+          focus: 'series'
+        },
+        label: {
+          show: true,
+          formatter: '{c}'
+          // position: [0, 10],
+        },
+        data: [value]
+      }
+    }
+  }
+  for (const key in c.numByUser) {
+    const value = c.numByUser[key]
+    if (series[key]) {
+      series[key].data.push(value)
+    } else {
+      series[key] = {
+        name: `鐢ㄦ埛锛�${key}`,
+        type: 'bar',
+        stack: 'user',
+        emphasis: {
+          focus: 'series'
+        },
+        label: {
+          show: true,
+          formatter: '{c}'
+          // position: [0, 10],
+        },
+        data: [value]
+      }
+    }
+  }
+  return series
+}
+</script>
+
+<style scoped>
+/* .el-segmented {
+  --el-segmented-item-selected-color: var(--el-text-color-primary);
+  --el-segmented-item-selected-bg-color: #ffd100;
+  --el-border-radius-base: 16px;
+} */
+
+.el-statistic {
+  --el-statistic-content-font-size: var(--el-font-size-base);
+  /* background-color: aliceblue; */
+}
+
+.statistic-footer {
+  background-color: #ffd100;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  flex-wrap: wrap;
+  font-size: 12px;
+  color: var(--el-text-color-regular);
+  /* margin-top: 16px; */
+}
+
+.statistic-footer .footer-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.statistic-footer .footer-item span:last-child {
+  display: inline-flex;
+  align-items: center;
+  margin-left: 4px;
+}
+
+.green {
+  color: var(--el-color-success);
+}
+.red {
+  color: var(--el-color-error);
+}
+
+.bar-chart {
+  width: 400px;
+  height: 400px;
+}
+</style>

--
Gitblit v1.9.3