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