From 31980b06d50d530feb2c0f1db9daf24bd3b8797a Mon Sep 17 00:00:00 2001
From: Riku <risaku@163.com>
Date: 星期日, 15 六月 2025 22:50:16 +0800
Subject: [PATCH] 2025.6.15

---
 src/views/management/TaskSummary.vue      |  392 +++++++++++++++++++++++++++++++-------
 src/api/index.js                          |    6 
 src/components/inspection/TaskItem.vue    |    2 
 src/views/management/TaskSummary copy.vue |  169 ++++++++++++++++
 4 files changed, 492 insertions(+), 77 deletions(-)

diff --git a/src/api/index.js b/src/api/index.js
index 7a84f90..3a2b325 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -1,13 +1,13 @@
 import axios from 'axios'
 import { ElMessage } from 'element-plus'
 
-const debug = true
+const debug = false
 
 var IP = '47.100.191.150'
 var PORT = '9005'
 if (debug) {
-  IP = '192.168.0.103'
-  // IP = 'localhost'
+  // IP = '192.168.0.103'
+  IP = 'localhost'
   PORT = '9001'
 }
 
diff --git a/src/components/inspection/TaskItem.vue b/src/components/inspection/TaskItem.vue
index b3b6c0b..9a32527 100644
--- a/src/components/inspection/TaskItem.vue
+++ b/src/components/inspection/TaskItem.vue
@@ -4,7 +4,7 @@
   </el-row>
   <div>
     <el-text>鎬婚噺</el-text>
-    <el-text size="small">{{ completetask + '/' + totaltask }}</el-text>
+    <el-text size="default">{{ completetask + '/' + totaltask }}</el-text>
     <el-progress
       style="width: 300px"
       type="line"
diff --git a/src/views/management/TaskSummary copy.vue b/src/views/management/TaskSummary copy.vue
new file mode 100644
index 0000000..9020a79
--- /dev/null
+++ b/src/views/management/TaskSummary copy.vue
@@ -0,0 +1,169 @@
+<template>
+  <!-- <BaseCard> -->
+  <el-row> 宸℃煡姹囨�� </el-row>
+  <el-segmented v-model="value" :options="options" block />
+  <div><el-text tag="i"> 璇勪及 </el-text></div>
+  <el-row justify="space-evenly">
+    <div>
+      <el-statistic title="鎬昏" :value="10"> </el-statistic>
+      <div class="statistic-footer">
+        <div class="footer-item">
+          <span>瀵规瘮鏄ㄦ棩</span>
+          <span class="green">
+            24%
+            <el-icon>
+              <CaretTop />
+            </el-icon>
+          </span>
+        </div>
+      </div>
+    </div>
+    <el-statistic title="楂橀闄�" :value="2" :value-style="styleRed"> </el-statistic>
+    <el-statistic title="涓闄�" :value="6" :value-style="styleYellow"> </el-statistic>
+    <el-statistic title="浣庨闄�" :value="2" :value-style="styleGreen"> </el-statistic>
+  </el-row>
+  <div><el-text tag="i"> 澶嶆牳 </el-text></div>
+  <el-row justify="space-evenly">
+    <div>
+      <el-statistic title="闇�澶嶆牳" :value="2"> </el-statistic>
+      <div class="statistic-footer">
+        <div class="footer-item">
+          <span>瀵规瘮鏄ㄦ棩</span>
+          <span class="green">
+            24%
+            <el-icon>
+              <CaretTop />
+            </el-icon>
+          </span>
+        </div>
+      </div>
+    </div>
+    <el-statistic title="宸插畬鎴�" :value="2" :value-style="styleGreen"> </el-statistic>
+  </el-row>
+  <div><el-text tag="i"> 闂 </el-text></div>
+  <el-row justify="space-evenly">
+    <div>
+      <el-statistic title="鎬昏" :value="10"> </el-statistic>
+      <div class="statistic-footer">
+        <div class="footer-item">
+          <span>瀵规瘮鏄ㄦ棩</span>
+          <span class="green">
+            24%
+            <el-icon>
+              <CaretTop />
+            </el-icon>
+          </span>
+        </div>
+      </div>
+    </div>
+    <el-statistic title="寰呭鏍�" :value="2" :value-style="styleRed"> </el-statistic>
+    <el-statistic title="宸插鏍�" :value="6" :value-style="styleYellow"> </el-statistic>
+    <el-statistic title="寰呮暣鏀�" :value="2" :value-style="styleGreen"> </el-statistic>
+    <el-statistic title="宸叉暣鏀�" :value="2" :value-style="styleGreen"> </el-statistic>
+    <el-statistic title="寰呯‘璁�" :value="2" :value-style="styleGreen"> </el-statistic>
+  </el-row>
+  <!-- </BaseCard> -->
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue'
+import dayjs from 'dayjs'
+import taskApi from '@/api/fysp/taskApi.js'
+
+const props = defineProps({
+  height: String
+})
+
+const emits = defineEmits(['update:height'])
+
+const value = '浠婃棩姹囨��'
+const options = ['浠婃棩姹囨��', '鍛ㄥ害姹囨��', '鏈堝害姹囨��', '瀛e害姹囨��', '骞村害姹囨��']
+const styleRed = 'color:var(--el-color-danger);'
+const styleYellow = 'color:var(--el-color-warning);'
+const styleGreen = 'color:var(--el-color-success);'
+
+const subtaskToday = ref([])
+const subtaskWeek = ref([])
+const subtaskMonth = ref([])
+
+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
+  })
+}
+
+function fetchSubtaskThisWeek() {
+  const area = getParams('week')
+
+  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
+    subtaskWeek.value = res.data
+  })
+}
+
+function fetchSubtaskThisMonth() {
+  const area = getParams('month')
+
+  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
+    subtaskMonth.value = res.data
+  })
+}
+
+onMounted(() => {
+  // fetchSubtaskToday()
+  // fetchSubtaskThisWeek()
+  fetchSubtaskThisMonth()
+})
+</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);
+}
+</style>
diff --git a/src/views/management/TaskSummary.vue b/src/views/management/TaskSummary.vue
index 3e86186..910d206 100644
--- a/src/views/management/TaskSummary.vue
+++ b/src/views/management/TaskSummary.vue
@@ -1,72 +1,23 @@
 <template>
-  <!-- <BaseCard> -->
   <el-row> 宸℃煡姹囨�� </el-row>
   <el-segmented v-model="value" :options="options" block />
-  <div><el-text tag="i"> 璇勪及 </el-text></div>
-  <el-row justify="space-evenly">
-    <div>
-      <el-statistic title="鎬昏" :value="10"> </el-statistic>
-      <div class="statistic-footer">
-        <div class="footer-item">
-          <span>瀵规瘮鏄ㄦ棩</span>
-          <span class="green">
-            24%
-            <el-icon>
-              <CaretTop />
-            </el-icon>
-          </span>
-        </div>
-      </div>
-    </div>
-    <el-statistic title="楂橀闄�" :value="2" :value-style="styleRed"> </el-statistic>
-    <el-statistic title="涓闄�" :value="6" :value-style="styleYellow"> </el-statistic>
-    <el-statistic title="浣庨闄�" :value="2" :value-style="styleGreen"> </el-statistic>
-  </el-row>
-  <div><el-text tag="i"> 澶嶆牳 </el-text></div>
-  <el-row justify="space-evenly">
-    <div>
-      <el-statistic title="闇�澶嶆牳" :value="2"> </el-statistic>
-      <div class="statistic-footer">
-        <div class="footer-item">
-          <span>瀵规瘮鏄ㄦ棩</span>
-          <span class="green">
-            24%
-            <el-icon>
-              <CaretTop />
-            </el-icon>
-          </span>
-        </div>
-      </div>
-    </div>
-    <el-statistic title="宸插畬鎴�" :value="2" :value-style="styleGreen"> </el-statistic>
-  </el-row>
-  <div><el-text tag="i"> 闂 </el-text></div>
-  <el-row justify="space-evenly">
-    <div>
-      <el-statistic title="鎬昏" :value="10"> </el-statistic>
-      <div class="statistic-footer">
-        <div class="footer-item">
-          <span>瀵规瘮鏄ㄦ棩</span>
-          <span class="green">
-            24%
-            <el-icon>
-              <CaretTop />
-            </el-icon>
-          </span>
-        </div>
-      </div>
-    </div>
-    <el-statistic title="寰呭鏍�" :value="2" :value-style="styleRed"> </el-statistic>
-    <el-statistic title="宸插鏍�" :value="6" :value-style="styleYellow"> </el-statistic>
-    <el-statistic title="寰呮暣鏀�" :value="2" :value-style="styleGreen"> </el-statistic>
-    <el-statistic title="宸叉暣鏀�" :value="2" :value-style="styleGreen"> </el-statistic>
-    <el-statistic title="寰呯‘璁�" :value="2" :value-style="styleGreen"> </el-statistic>
-  </el-row>
-  <!-- </BaseCard> -->
+  <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>
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import * as echarts from 'echarts'
+import { ref, onMounted } from 'vue'
 import dayjs from 'dayjs'
 import taskApi from '@/api/fysp/taskApi.js'
 
@@ -76,22 +27,312 @@
 
 const emits = defineEmits(['update:height'])
 
-const alue = '浠婃棩姹囨��'
-const ptions = ['浠婃棩姹囨��', '鍛ㄥ害姹囨��', '鏈堝害姹囨��', '瀛e害姹囨��', '骞村害姹囨��']
-const tyleRed = 'color:var(--el-color-danger);'
-const tyleYellow = 'color:var(--el-color-warning);'
-const tyleGreen = 'color:var(--el-color-success);'
+const value = ref('鏈堝害姹囨��')
+const options = ['浠婃棩姹囨��', '鏈懆姹囨��', '涓婂懆姹囨��', '鏈堝害姹囨��']
 
-function name(params) {
+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()
-  const area = {
-    starttime: d.startOf('day').format('YYYY-MM-DD HH:mm:ss'),
+  return {
+    starttime: d.startOf(type).format('YYYY-MM-DD HH:mm:ss'),
     endtime: d.endOf(type).format('YYYY-MM-DD HH:mm:ss')
   }
+}
 
-  taskApi.fetchSubtaskSummaryByArea(this.area).then((res) => {
-    this.subtaskList = res.data
+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')
+  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(-7, 'day').format('YYYY-MM-DD HH:mm:ss')
+  area.endtime = dayjs(area.endtime).add(-7, '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: {},
+    numByScene: {},
+    numByUser: {}
+  }
+  // 闂鏁�
+  const proCount = {
+    numByTotal: {},
+    numByDistrict: {},
+    numByScene: {},
+    numByUser: {}
+  }
+  // 鏁存敼鏁�
+  const changeCount = {
+    numByTotal: {},
+    numByDistrict: {},
+    numByScene: {},
+    numByUser: {}
+  }
+  // // 鎸夌敤鎴峰垎绫�
+  // const userCount = {
+  //   numByTotal: {},
+  //   numByDistrict: {},
+  //   numByScene: {},
+  //   numByUser: {}
+  // }
+  dataList.forEach((d) => {
+    const tName = '鎬昏'
+    const dName = d.subtask.districtname
+    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.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.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.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
+  })
+
+  let series = {}
+  totalCount
+  proCount
+  changeCount
+  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: [0, 10],
+        },
+        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>
 
@@ -136,4 +377,9 @@
 .red {
   color: var(--el-color-error);
 }
+
+.bar-chart {
+  width: 400px;
+  height: 600px;
+}
 </style>

--
Gitblit v1.9.3