Files
dvcp_v2_wxcp_app/library/project/qujing/AppPatrolReport/Statistics.vue
2024-10-31 14:34:57 +08:00

505 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="statistics">
<AiTopFixed>
<div class="select-gird">
<AiPagePicker type="gird" valueObj nodeKey="id" formType="2" @select="handleSelectGird" class="right-span"
action="/app/apppatrolreportinfo/listByInfo">
<img src="./components/img/gird-icon.png" alt="" class="gird-png">
<span>{{selectGird.girdName || '所属网格'}}</span>
<u-icon name="arrow-down" color="#8A8A8A" size="24"></u-icon>
</AiPagePicker>
</div>
</AiTopFixed>
<div class="statstics-content">
<div class="el-row">
<div class="item" v-for="(item, index) in todayList" :key="index" @click="toList(item)" :class="`item`+index" v-if="item.label != '累计办结'">
<div><span class="circle"><span class="cir"></span></span>{{ item.label }}</div>
<h2>{{ item.value }}</h2>
</div>
</div>
<div class="info-content">
<div class="title">事件办结率</div>
<div class="echart-content" id="finish" v-if="showFinish"></div>
<div class="num" v-if="showFinish">{{ finshNum || 0 }}%</div>
<AiEmpty v-else></AiEmpty>
</div>
<div class="info-content">
<div class="title">事件上报趋势图</div>
<AiEmpty v-if="!trendData.length"></AiEmpty>
<div class="echart-content" id="trend" v-else></div>
</div>
<div class="info-content">
<div class="title">巡查事件分类
<div class="type-select" :style="statusInfo.name ? '' : 'color:#999;'" @click="show=true">{{statusInfo.name || '请选择'}}<u-icon name="arrow-right"></u-icon></div>
<u-select v-model="show" :list="$dict.getDict('qujingEventStatus')" value-name="dictValue"
label-name="dictName" @confirm="selectStatus"></u-select>
</div>
<AiEmpty v-if="!typeData.length"></AiEmpty>
<div class="echart-content" id="type" v-else></div>
</div>
<div class="pad-b120"></div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
import echarts from 'echarts'
export default {
props: {},
data() {
return {
todayList: [],
selectGird: {id: '', girdName: '', girdCode: ''},
finishChart: null,
trendChart: null,
typeChart: null,
show: false,
finishData: [],
showFinish: false,
finshNum: '',
trendData: [],
trendDataX: [],
typeData: [],
statusInfo: {name: '', eventStatus: ''},
}
},
computed: {
...mapState(['user']),
},
created() {
this.getGirdInfo()
},
methods: {
getStatistics() {
this.todayList = [], this.finishData = [], this.trendDataX = [], this.trendData = [], this.typeData = [], this.showFinish = false
this.$http.post(`/app/appclapeventinfoqujing/countByGirdCode?girdCode=${this.selectGird.girdCode}&eventStatus=${this.statusInfo.eventStatus}`).then((res) => {
if (res.code == 0) {
Object.keys(res.data.allCountMap).forEach((key) => {
var info = {
label: key,
value: res.data.allCountMap[key]
}
this.todayList.push(info)
})
Object.keys(res.data.allCountMap).forEach((key) => {
if(key == '累计办结' || key == '累计上报') {
var info = {
name: key,
value: res.data.allCountMap[key]
}
if (res.data.allCountMap['累计上报'] > 0) {
this.showFinish = true
}
this.finishData.push(info)
}
})
if (this.showFinish) {
var num = res.data.allCountMap['累计办结'] / res.data.allCountMap['累计上报']
this.finshNum = Number(num * 100).toFixed(2)
}
res.data.dateCountList.map((item) => {
this.trendData.push(item.ecount)
this.trendDataX.push(item.ymd)
})
res.data.groupList.map((item) => {
var info = {
name: item.groupName,
value: item.totalNum
}
this.typeData.push(info)
})
this.$nextTick(() => {
if (this.showFinish) {
this.finishChartInit()
}
if (this.trendData.length) {
this.trendChartInit()
}
if (this.typeData.length) {
this.typeChartInit()
}
})
}
})
},
getGirdInfo() {
this.$http.post(`/app/apppatrolreportinfo/getRootByGirdMember`).then((res) => {
if (res.code == 0) {
this.selectGird.girdName = res.data.girdName
this.selectGird.id = res.data.id
this.selectGird.girdCode = res.data.girdCode
this.$dict.load('qujingEventStatus').then(() => {
this.getStatistics()
})
}
})
},
finishChartInit() {
this.finishChart = echarts.init(document.getElementById('finish'))
var option = {
tooltip: {
trigger: 'item'
},
series: [
{
name: '事件办结率',
type: 'pie',
radius: ['50%', '70%'],
itemStyle: {
normal: {
color: function (colors) {
var colorList = ['#7E94F6', '#85E3D5', '#2891FF'];
return colorList[colors.dataIndex];
}
},
},
data: this.finishData,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
}
}
}
]
};
this.finishChart.setOption(option)
},
trendChartInit() {
this.trendChart = echarts.init(document.getElementById('trend'))
var option2 = {
grid: {
left: '5%',
right: '5%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#E1E5EF', //x轴的颜色
width: 1, //轴线的宽度
},
},
axisLabel: {
show: true,
textStyle: {
color: '#666',
},
},
data: this.trendDataX
},
yAxis: {
axisLine: { //y轴
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
textStyle: {
color: '#666',
},
},
type: 'value',
},
tooltip: {
trigger: 'axis'
},
series: [
{
data: this.trendData,
type: 'line',
areaStyle: {//覆盖区域的渐变色
normal: {
color: {
type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
colorStops: [
{
offset: 0, color: 'rgba(58,132,255, 0.8)' // 0% 处的颜色
},
{
offset: 1, color: 'rgba(58,132,255, 0)' // 100% 处的颜色
}
],
global: false // 缺省为 false
},
}
},
lineStyle: {
normal: {
color: '#2891FF'
}
},
itemStyle: {
normal: {
color: '#2891FF',
}
}
}
]
};
this.trendChart.setOption(option2)
},
typeChartInit() {
this.typeChart = echarts.init(document.getElementById('type'))
var option3 = {
tooltip: {
trigger: 'item'
},
series: [
{
name: '巡查事件分类',
type: 'pie',
radius: ['40%', '70%'],
itemStyle: {
normal: {
color: function (colors) {
var colorList = ['#2891FF', '#FF8700', '#83B5F7', '#7E94F6', '#85E3D5', '#2891FF'];
return colorList[colors.dataIndex];
}
},
},
data: this.typeData,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
}
}
}
]
};
this.typeChart.setOption(option3)
},
selectStatus(e) {
this.statusInfo.name = e[0].label
this.statusInfo.eventStatus = e[0].value
this.getStatistics()
},
handleSelectGird(v) {
console.log(v)
this.selectGird = v || {}
this.getStatistics()
},
toList(row) { //0、查询网格员待办事件1、查询网格员历史事件2、累计上报事件3、今日上报事件4、今日办结事件5、办理中事件
var searchType = '', typeList = ['', '', '累计上报', '今日上报', '今日办结', '办理中']
typeList.map((item, index) => {
if (item == row.label) {
return searchType = index
}
})
uni.navigateTo({url: `./StatisticsList?title=${row.label}&searchType=${searchType}&girdCode=${this.selectGird.girdCode}`})
}
},
}
</script>
<style scoped lang="scss">
.statistics {
background-color: #F3F7F8;
.statstics-content {
padding: 30px 30px 0;
}
::v-deep .AiTopFixed {
background-color: #f5f5f5!important;
.fixed {
background-color: #f5f5f5!important;
}
.content {
padding: 24px;
box-sizing: border-box;
width: 686px;
height: 96px;
background: #FFF;
border-radius: 8px;
margin: 32px 32px 0;
}
.gird-png {
width: 30px;
height: 30px;
margin-right: 16px;
vertical-align: middle;
}
span {
display: inline-block;
width: calc(100% - 84px);
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
color: #333;
letter-spacing: 0;
line-height: 48px;
vertical-align: middle;
}
}
::v-deep .AiMore {
span {
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
color: #333;
letter-spacing: 0;
line-height: 48px;
}
}
.el-row {
margin-bottom: 16px;
.item {
display: inline-block;
width: calc(50% - 7px);
background-color: #fff;
padding: 24px;
box-sizing: border-box;
margin-bottom: 16px;
div {
line-height: 40px;
font-family: PingFangSC-Regular;
font-size: 28px;
color: #666;
margin-bottom: 8px;
.circle {
display: inline-block;
width: 16px;
height: 16px;
margin-right: 8px;
padding: 8px;
box-sizing: border-box;
border-radius: 50%;
position: relative;
.cir {
position: absolute;
top: 4px;
left: 4px;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #fff;
}
}
}
h2 {
padding-left: 32px;
font-family: PingFangSC-SNaNpxibold;
font-weight: 600;
font-size: 48px;
color: #333;
letter-spacing: 0;
line-height: 64px;
}
}
.item:nth-of-type(2n) {
margin-left: 7px;
}
.item:nth-of-type(2n-1) {
margin-right: 7px;
}
.item0 {
.circle {
background-color: #7A8EC5;
}
}
.item1 {
.circle {
background-color: #F6BD15;
}
}
.item2 {
.circle {
background-color: #5C8FFA;
}
}
.item3 {
.circle {
background-color: #60DCAA;
}
}
}
.info-content {
width: 100%;
background: #FFF;
border-radius: 16px;
margin-bottom: 24px;
position: relative;
padding-bottom: 32px;
.title {
font-size: 32px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333;
line-height: 48px;
padding: 24px 16px 24px 24px;
img {
float: right;
width: 40px;
height: 40px;
}
.type-select {
font-size: 26px;
position: absolute;
top: 20px;
right: 32px;
width: calc(100% - 250px);
text-align: right;
line-height: 48px;
}
}
.echart-content {
width: 100%;
height: 500px;
}
.num {
position: absolute;
left: 50%;
top: 320px;
margin-left: -100px;
font-size: 40px;
font-weight: 600;
width: 200px;
text-align: center;
}
}
.pad-b120 {
background-color: #F3F7F8;
padding-bottom: 120px;
}
}
</style>