<template>
|
<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>
|
</template>
|
|
<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: {},
|
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>
|
|
<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>
|