| | |
| | | <template> |
| | | <BaseCard> |
| | | <el-row> 巡查汇总 </el-row> |
| | | <el-segmented v-model="value" :options="options" /> |
| | | <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 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> |
| | | export default { |
| | | props: { |
| | | height: String |
| | | }, |
| | | emits: ['update:height'], |
| | | data() { |
| | | return { |
| | | value: '今日汇总', |
| | | options: ['今日汇总', '周度汇总', '月度汇总', '季度汇总', '年度汇总'], |
| | | styleRed: 'color:var(--el-color-danger);', |
| | | styleYellow: 'color:var(--el-color-warning);', |
| | | styleGreen: 'color:var(--el-color-success);' |
| | | <script setup> |
| | | /** |
| | | * 1. 区域分类统计更加灵活 |
| | | */ |
| | | import * as echarts from 'echarts' |
| | | 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 = 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) |
| | | } |
| | | }, |
| | | mounted() {} |
| | | }) |
| | | |
| | | 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 { |
| | | --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); |
| | |
| | | .red { |
| | | color: var(--el-color-error); |
| | | } |
| | | |
| | | .bar-chart { |
| | | width: 400px; |
| | | height: 400px; |
| | | } |
| | | </style> |