dbd-meeting-html/src/views/admin/repair/RepairStatistics.vue

803 lines
19 KiB
Vue
Raw Normal View History

2024-08-08 14:32:22 +08:00
<template>
2024-08-17 16:31:37 +08:00
<div class="container">
2024-08-08 14:32:22 +08:00
2024-08-17 16:31:37 +08:00
<div class="topHeadView">
<div class="itemView">
<div class="imgView"></div>
<div class="label">待派单</div>
<div class="num">{{ adminStatsCount.wait }}</div>
</div>
<div class="itemView">
<div class="imgView"></div>
<div class="label">重派单</div>
<div class="num">{{ adminStatsCount.anew }}</div>
</div>
<div class="itemView">
<div class="imgView"></div>
<div class="label">未查看通知</div>
<div class="num">{{ adminStatsCount.newnotice }}</div>
</div>
<div class="itemView">
<div class="imgView"></div>
<div class="label">已查看通知</div>
<div class="num">{{ adminStatsCount.oldnotice }}</div>
2024-08-08 17:18:00 +08:00
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="caseStatisticsView">
<div class="headView">
<div class="titleView">工单统计</div>
<div class="typeView">
<div :class="type=='month' ? 'activity' : ''" class="type " @click="repairCount">本月</div>
<div :class="type=='year' ? 'activity' : ''" class="type" @click="getYearCount">本年</div>
2024-08-08 17:18:00 +08:00
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="contentView">
<div class="itemView">
<div class="label">维修工单</div>
<div class="value">{{ repairStatsCount.zs }}</div>
</div>
<div class="itemView">
<div class="label">待维修工单</div>
<div class="value">{{ repairStatsCount.wait }}</div>
</div>
<div class="itemView">
<div class="label">超时量</div>
<div class="value">{{ repairStatsCount.timeout }}</div>
</div>
<div class="itemView">
<div class="label">差评量</div>
<div class="value">{{ repairStatsCount.l }}</div>
</div>
<div class="itemView">
<div class="label">中评量</div>
<div class="value">{{ repairStatsCount.m }}</div>
</div>
<div class="itemView">
<div class="label">好评量</div>
<div class="value">{{ repairStatsCount.h }}</div>
2024-08-08 17:18:00 +08:00
</div>
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="statusView">
<div class="caseStatusView">
<div class="headView">
<div class="titleView">工单完成情况</div>
<!-- <div class="typeView">-->
<!-- <div class="type activity">本周</div>-->
<!-- <div class="type">本年</div>-->
<!-- </div>-->
2024-08-08 17:18:00 +08:00
</div>
2024-08-17 16:31:37 +08:00
<div class="contentView">
<div class="circularView">
<div id="echart1" style="width: 400px; height: 300px"></div>
2024-08-08 17:18:00 +08:00
</div>
2024-08-17 16:31:37 +08:00
<div class="centerLine"></div>
<div class="circularView">
<div id="echart2" style="width: 400px; height: 300px"></div>
2024-08-08 17:18:00 +08:00
</div>
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="evaluateView">
<div class="headView">
<div class="titleView">评价情况</div>
2024-08-08 17:18:00 +08:00
</div>
2024-08-17 16:31:37 +08:00
<div class="contentView">
<div id="echart3" style="width: 400px; height: 300px"></div>
2024-08-08 17:18:00 +08:00
</div>
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="faultView">
<div class="floorView">
<div class="headView">
<div class="titleView">楼层负责人情况</div>
<div class="conditionView">
<a-select default-value="week" style="width: 120px;margin-right: 10px">
<a-select-option value="month" >按月</a-select-option>
<a-select-option value="year">按年</a-select-option>
2024-08-08 17:18:00 +08:00
</a-select>
2024-08-17 16:31:37 +08:00
<a-month-picker placeholder="请选择时间" />
<a-year-picker placeholder="请选择时间" />
2024-08-08 17:18:00 +08:00
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="contentView">
<div id="echart4" style="width: 550px; height: 600px"></div>
2024-08-08 17:36:38 +08:00
</div>
2024-08-08 17:18:00 +08:00
</div>
2024-08-17 16:31:37 +08:00
<div class="rightView">
<div class="blockView">
<div class="headView">
<div class="titleView">故障统计</div>
<div class="conditionView">
<a-select default-value="week" style="width: 120px;margin-right: 10px">
<a-select-option value="month">按月</a-select-option>
<a-select-option value="year">按年</a-select-option>
2024-08-09 10:57:16 +08:00
</a-select>
2024-08-17 16:31:37 +08:00
<a-date-picker placeholder="请选择时间" />
2024-08-09 10:57:16 +08:00
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="contentView">
<div id="echart5" style="width: 700px; height: 327px"></div>
2024-08-09 10:57:16 +08:00
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="blockView">
<div class="headView">
<div class="titleView">故障类型</div>
<div class="conditionView">
<a-select default-value="week" style="width: 120px;margin-right: 10px">
<a-select-option value="month">按月</a-select-option>
<a-select-option value="year">按年</a-select-option>
2024-08-09 10:57:16 +08:00
</a-select>
2024-08-17 16:31:37 +08:00
<a-date-picker placeholder="请选择时间" />
2024-08-09 10:57:16 +08:00
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="contentView">
<div id="echart6" style="width: 700px; height: 327px"></div>
2024-08-09 10:57:16 +08:00
</div>
</div>
2024-08-08 17:18:00 +08:00
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="tableView">
<div class="headView">
<div class="titleView">故障统计</div>
<div class="conditionView">
<a-select default-value="week" style="width: 120px;margin-right: 10px">
<a-select-option value="week">按周</a-select-option>
<a-select-option value="month">按月</a-select-option>
<a-select-option value="year">按年</a-select-option>
2024-08-09 10:57:16 +08:00
</a-select>
2024-08-17 16:31:37 +08:00
<a-date-picker placeholder="请选择时间" />
2024-08-09 10:57:16 +08:00
</div>
</div>
2024-08-17 16:31:37 +08:00
<div class="contentView">
2024-08-09 11:02:17 +08:00
<a-table
:columns="columns"
:data-source="loadData"
showPagination="true"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
>
2024-08-09 10:57:16 +08:00
</a-table>
</div>
</div>
2024-08-08 17:18:00 +08:00
</div>
2024-08-08 14:32:22 +08:00
</template>
<script>
2024-08-08 17:18:00 +08:00
import * as echarts from 'echarts'
2024-08-17 16:31:37 +08:00
import { repairAdminStats, repairStats, floorStats } from '@/api/admin/repair/repairStats'
2024-08-08 17:18:00 +08:00
2024-08-08 14:32:22 +08:00
export default {
2024-08-08 17:18:00 +08:00
name: 'RepairStatistics',
2024-08-09 10:57:16 +08:00
data () {
return {
2024-08-17 16:31:37 +08:00
type: '',
adminStatsCount: [],
repairStatsCount: [],
finishCount: [],
timeout: [],
pj: [],
floorStatsCount: [],
2024-08-09 10:57:16 +08:00
// 查询参数
queryParam: {},
2024-08-09 11:02:17 +08:00
selectedRowKeys: [],
selectedRows: [],
2024-08-09 10:57:16 +08:00
// 表头
columns: [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
2024-08-17 16:31:37 +08:00
scopedSlots: { customRender: 'name' }
2024-08-09 10:57:16 +08:00
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
2024-08-17 16:31:37 +08:00
width: 80
2024-08-09 10:57:16 +08:00
},
{
title: 'Address',
dataIndex: 'address',
key: 'address 1',
2024-08-17 16:31:37 +08:00
ellipsis: true
2024-08-09 11:05:28 +08:00
}
2024-08-09 10:57:16 +08:00
],
// 加载数据方法 必须为 Promise 对象
loadData: [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park, New York No. 1 Lake Park',
2024-08-17 16:31:37 +08:00
tags: ['nice', 'developer']
2024-08-09 10:57:16 +08:00
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 2 Lake Park, London No. 2 Lake Park',
2024-08-17 16:31:37 +08:00
tags: ['loser']
2024-08-09 10:57:16 +08:00
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park, Sidney No. 1 Lake Park',
2024-08-17 16:31:37 +08:00
tags: ['cool', 'teacher']
}
]
2024-08-09 10:57:16 +08:00
}
},
2024-08-17 16:31:37 +08:00
mounted () {
this.adminStats()
this.repairCount()
this.getfloorStats()
// this.createEchartCake('echart2', {
// bottom: 10,
// left: 'right',
// orient: 'vertical'
// })
// this.createEchartCake('echart3', {
// bottom: 10,
// left: 'right',
// orient: 'vertical'
// })
2024-08-08 17:36:38 +08:00
this.createEchartLine('echart4')
2024-08-09 10:57:16 +08:00
this.createColumnEcharrt('echart5')
this.createEchartCake('echart6', {
bottom: 'center',
right: '10%',
orient: 'vertical'
})
2024-08-08 17:18:00 +08:00
},
methods: {
2024-08-17 16:31:37 +08:00
adminStats () {
repairAdminStats().then(res => {
this.adminStatsCount = res.repairAdminStats
})
},
getYearCount () {
this.type = 'year'
repairStats().then(res => {
this.repairStatsCount = res.currentYear.stats
this.finishCount = res.currentYear.wc
this.timeout = res.currentYear.timeout
this.pj = res.currentYear.pj
this.createEchartCake('echart1', {
bottom: 10,
left: 'right',
orient: 'vertical'
}, this.finishCount)
this.createEchartCake('echart2', {
bottom: 10,
left: 'right',
orient: 'vertical'
}, this.timeout)
this.createEchartCake('echart3', {
bottom: 10,
left: 'right',
orient: 'vertical'
}, this.pj)
})
},
repairCount () {
repairStats().then(res => {
this.type = 'month'
console.log(res.currentMonth.wc)
this.repairStatsCount = res.currentMonth.stats
this.finishCount = res.currentMonth.wc
this.timeout = res.currentMonth.timeout
this.pj = res.currentMonth.pj
this.createEchartCake('echart1', {
bottom: 10,
left: 'right',
orient: 'vertical'
}, this.finishCount)
this.createEchartCake('echart2', {
bottom: 10,
left: 'right',
orient: 'vertical'
}, this.timeout)
this.createEchartCake('echart3', {
bottom: 10,
left: 'right',
orient: 'vertical'
}, this.pj)
})
},
// 楼层负责人情况
getfloorStats () {
floorStats().then(res => {
console.log(res)
})
},
2024-08-09 11:02:17 +08:00
onSelectChange (selectedRowKeys, selectedRows) {
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
},
2024-08-17 16:31:37 +08:00
createEchartCake (id, legend, data) {
console.log(data)
2024-08-08 17:18:00 +08:00
// 基于准备好的dom初始化echarts实例
let myChart = echarts.init(document.getElementById(id))
// 指定图表的配置项和数据
let option = {
tooltip: {
trigger: 'item'
},
2024-08-09 10:57:16 +08:00
legend: legend,
2024-08-08 17:18:00 +08:00
series: [
{
2024-08-17 16:31:37 +08:00
name: '完成率',
2024-08-08 17:18:00 +08:00
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 2,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
2024-08-17 16:31:37 +08:00
data: data
2024-08-08 17:18:00 +08:00
}
]
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option)
2024-08-08 17:36:38 +08:00
},
2024-08-17 16:31:37 +08:00
createEchartLine (id) {
2024-08-08 17:36:38 +08:00
// 基于准备好的dom初始化echarts实例
let myChart = echarts.init(document.getElementById(id))
let option = {
title: {
text: 'World Population'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.01]
},
yAxis: {
type: 'category',
data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World']
},
series: [
{
name: '2011',
type: 'bar',
data: [18203, 23489, 29034, 104970, 131744, 630230]
},
{
name: '2012',
type: 'bar',
data: [19325, 23438, 31000, 121594, 134141, 681807]
}
]
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option)
2024-08-09 10:57:16 +08:00
},
2024-08-17 16:31:37 +08:00
createColumnEcharrt (id) {
2024-08-09 10:57:16 +08:00
// 基于准备好的dom初始化echarts实例
let myChart = echarts.init(document.getElementById(id))
// There should not be negative values in rawData
const rawData = [
[100, 302, 301, 334, 390, 330, 320],
[320, 132, 101, 134, 90, 230, 210],
[220, 182, 191, 234, 290, 330, 310],
[150, 212, 201, 154, 190, 330, 410],
[820, 832, 901, 934, 1290, 1330, 1320]
]
const totalData = []
for (let i = 0; i < rawData[0].length; ++i) {
let sum = 0
for (let j = 0; j < rawData.length; ++j) {
sum += rawData[j][i]
}
totalData.push(sum)
}
const grid = {
left: 100,
right: 100,
top: 50,
bottom: 50
}
const series = [
'Direct',
'Mail Ad',
'Affiliate Ad',
'Video Ad',
'Search Engine'
].map((name, sid) => {
return {
name,
type: 'bar',
stack: 'total',
barWidth: '60%',
label: {
show: true,
formatter: (params) => Math.round(params.value * 1000) / 10 + '%'
},
data: rawData[sid].map((d, did) =>
totalData[did] <= 0 ? 0 : d / totalData[did]
)
}
})
let option = {
legend: {
selectedMode: false
},
grid,
yAxis: {
type: 'value'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
series
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option)
2024-08-08 17:18:00 +08:00
}
}
2024-08-08 14:32:22 +08:00
}
</script>
<style scoped>
2024-08-08 17:18:00 +08:00
* {
box-sizing: border-box;
margin: 0;
padding: 0;
word-break: break-all;
line-height: 1;
}
.topHeadView {
display: flex;
justify-content: space-around;
align-items: center;
padding: 40px 0;
background: #4093f7;
border-radius: 10px;
}
.topHeadView .itemView {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.topHeadView .itemView .imgView {
width: 80px;
height: 80px;
background: white;
border-radius: 80px;
}
.topHeadView .itemView .label {
margin-top: 10px;
color: white;
}
.topHeadView .itemView .num {
position: absolute;
left: calc(100% + 10px);
top: 50%;
transform: translateY(-100%);
width: 90px;
color: white;
font-size: 28px;
}
.caseStatisticsView {
margin-top: 10px;
padding: 0 20px;
border-radius: 10px;
background: white;
}
.caseStatisticsView .headView {
display: flex;
justify-content: space-between;
align-items: center;
}
.caseStatisticsView .headView .titleView {
font-size: 14px;
color: #4093f7;
font-weight: bold;
padding: 14px 30px;
border-bottom: 2px solid #4093f7;
}
.caseStatisticsView .headView .typeView {
display: flex;
justify-content: center;
align-items: center;
}
.caseStatisticsView .headView .typeView .type {
margin-right: 40px;
font-weight: bold;
}
.caseStatisticsView .headView .typeView .activity {
color: #4093f7;
}
.caseStatisticsView .contentView {
display: flex;
justify-content: center;
align-items: center;
padding: 30px 50px;
}
.caseStatisticsView .contentView .itemView {
flex: 1;
border: 1px solid #4093f7;
border-radius: 4px;
padding: 14px 20px;
margin-left: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.caseStatisticsView .contentView .itemView:first-of-type {
margin-left: 0;
}
.caseStatisticsView .contentView .itemView .label {
font-size: 12px;
font-weight: bold;
color: #4093f7;
}
.caseStatisticsView .contentView .itemView .value {
font-size: 12px;
}
.statusView {
display: flex;
justify-content: flex-start;
align-items: center;
margin-top: 10px;
}
.statusView .caseStatusView, .statusView .evaluateView {
background: white;
border-radius: 10px;
}
.statusView .caseStatusView {
flex: 2;
}
.statusView .evaluateView {
flex: 1;
margin-left: 6px;
}
.statusView .caseStatusView .headView, .statusView .evaluateView .headView {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
height: 40px;
}
.statusView .caseStatusView .headView .titleView, .statusView .evaluateView .headView .titleView {
font-size: 14px;
color: gray;
}
.statusView .caseStatusView .headView .typeView {
display: flex;
justify-content: center;
align-items: center;
}
.statusView .caseStatusView .headView .typeView .type {
font-size: 12px;
color: #4093f7;
margin-left: 20px;
padding: 4px 8px;
border-radius: 4px;
}
.statusView .caseStatusView .headView .typeView .type.activity {
border: 1px solid #4093f7;
}
.statusView .caseStatusView .contentView {
display: flex;
justify-content: flex-start;
align-items: center;
}
.statusView .caseStatusView .contentView .circularView {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.statusView .caseStatusView .contentView .centerLine {
width: 1px;
height: 200px;
background: rgba(0, 0, 0, 0.1);
}
.statusView .evaluateView .contentView {
display: flex;
justify-content: center;
align-items: center;
}
.faultView {
display: flex;
justify-content: flex-start;
2024-08-09 10:57:16 +08:00
align-items: flex-start;
2024-08-08 17:18:00 +08:00
margin-top: 10px;
}
2024-08-08 17:36:38 +08:00
.faultView .floorView {
2024-08-08 17:18:00 +08:00
background: white;
border-radius: 10px;
width: 600px;
}
.faultView .floorView .headView {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
height: 40px;
}
.faultView .floorView .headView .titleView {
font-size: 14px;
color: gray;
}
.faultView .floorView .headView .conditionView {
2024-08-08 17:36:38 +08:00
display: flex;
2024-08-08 17:18:00 +08:00
justify-content: center;
align-items: center;
}
2024-08-08 17:36:38 +08:00
.faultView .floorView .contentView {
display: flex;
justify-content: center;
align-items: center;
height: 700px;
}
2024-08-08 14:32:22 +08:00
2024-08-09 10:57:16 +08:00
.rightView {
flex: 1;
margin-left: 6px;
}
.rightView .blockView {
background: white;
border-radius: 10px;
}
.rightView .blockView:last-of-type {
margin-top: 6px;
}
.rightView .blockView .headView {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
height: 40px;
}
.rightView .blockView .headView .titleView {
font-size: 14px;
color: gray;
}
.rightView .blockView .headView .conditionView {
display: flex;
justify-content: center;
align-items: center;
}
.rightView .blockView .contentView {
display: flex;
justify-content: center;
align-items: center;
}
.tableView {
background: white;
border-radius: 10px;
margin-top: 6px;
}
.tableView .headView {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
height: 40px;
}
.tableView .headView .titleView {
font-size: 14px;
color: gray;
}
.tableView .headView .conditionView {
display: flex;
justify-content: center;
align-items: center;
}
.tableView .contentView {
display: flex;
justify-content: center;
align-items: center;
}
2024-08-08 14:32:22 +08:00
</style>