Files
admin-vben5/apps/web-antd/src/views/property/customerService/centerConsole/index.vue

326 lines
8.0 KiB
Vue
Raw Normal View History

2025-07-22 18:55:04 +08:00
<script setup lang="ts">
import { EditOutlined } from '@ant-design/icons-vue';
import {EchartsUI, type EchartsUIType, useEcharts} from "@vben/plugins/echarts";
import {onMounted, ref} from "vue";
2025-07-23 15:23:57 +08:00
import {countsList} from '#/api/property/customerService/centerConsole'
2025-07-22 18:55:04 +08:00
2025-07-23 15:23:57 +08:00
const board = ref ({})
const getBoard = async () => {
board.value = await countsList();
}
2025-07-22 18:55:04 +08:00
const xAxisData = ref<any[]>([]);
const seriesData = ref<any[]>([]);
2025-07-23 15:23:57 +08:00
// 工单计数
const workOrderCount = ref<EchartsUIType>();
const { renderEcharts: renderWorkOrderCount } = useEcharts(workOrderCount);
async function fetchWorkOrderCount() {
xAxisData.value = board.value.recentWeekWorkOrders
console.log(xAxisData.value)
renderWorkOrderCount({
2025-07-22 18:55:04 +08:00
tooltip: { trigger: 'axis' },
xAxis: {
type: 'category',
boundaryGap: false,
2025-07-23 15:23:57 +08:00
data: ['06-17周二', '06-17周二', '06-17周二', '06-17周二', '06-17周二', '06-17周二', '06-17周二']
},
yAxis: {
type: 'value',
name: '近一周工单数',
2025-07-22 18:55:04 +08:00
},
series: [
{
2025-07-23 15:23:57 +08:00
data: [6, 2, 0, 1, 0, 0, 1],
2025-07-22 18:55:04 +08:00
type: 'line',
2025-07-23 15:23:57 +08:00
areaStyle: {},
2025-07-22 18:55:04 +08:00
smooth: true,
2025-07-23 15:23:57 +08:00
}
]
2025-07-22 18:55:04 +08:00
});
}
2025-07-23 15:23:57 +08:00
// 满意度指数
const satisfactionLevel = ref<EchartsUIType>();
const { renderEcharts: renderSatisfactionLevel } = useEcharts(satisfactionLevel);
async function fetchSatisfactionLevel() {
renderSatisfactionLevel({
title: {text: '满意度指数',left: '18px'},
tooltip: { trigger: 'item'},
radar: {
indicator: [
{name: '1星', max: 1000},
{name: '2星', max: 1000},
{name: '3星', max: 1000},
{name: '4星', max: 1000},
{name: '5星', max: 1000},
]
},
series: [
{
type: 'radar',
name: '满意度指数',
data: [
{
value: [500, 400, 800, 600, 400],
}
]
}
]
})
}
// 近半年工单数
const orderNumber = ref<EchartsUIType>();
const { renderEcharts: renderOrderNumber } = useEcharts(orderNumber);
async function fetchOrderNumber() {
renderOrderNumber({
title: {text: '近半年工单数',left: '18px'},
legend: {},
tooltip: { trigger: 'axis' },
dataset: {
source: [
['product', '物业', '入驻员工'],
['2025-01', 2, 5.8],
['2025-02', 10.1, 7.4],
['2025-03', 6.4, 5.2],
['2025-04', 3.3, 5.8],
['2025-05', 8.1, 7.4],
['2025-06', 6.4, 5.2],
]
},
xAxis: { type: 'category' },
yAxis: {},
series: [{ type: 'bar' }, { type: 'bar' }]
})
}
// 工单类型分类占比
const orderTyper = ref<EchartsUIType>();
const { renderEcharts: renderOrderTyper } = useEcharts(orderTyper);
async function fetchOrderTyper() {
renderOrderTyper({
title: {text: '工单类型分类占比',left: '18px',top: '18px'},
tooltip: {
trigger: 'item'
},
legend: {
top: '40%',
right: '10%',
orient: 'vertical',
icon: 'circle',
itemWidth: 8,
itemHeight: 8
},
series: [
{
type: 'pie',
center: ['40%', '55%'],
radius: ['40%', '70%'],
label: {
show: true,
position: 'center',
formatter: '员工单数量\n{num|56个}',
fontSize: 14,
fontWeight: 'bold',
color: 'gray',
rich: {
num: {
fontSize: 18,
fontWeight: 'bolder',
color:'black',
padding: [10, 0, 0, 0],
}
}
},
avoidLabelOverlap: false,
labelLine: {
show: false
},
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' }
]
}
]
})
}
2025-07-22 18:55:04 +08:00
onMounted(async () => {
2025-07-23 15:23:57 +08:00
await getBoard()
await fetchWorkOrderCount()
await fetchSatisfactionLevel()
await fetchOrderNumber()
await fetchOrderTyper()
2025-07-22 18:55:04 +08:00
})
</script>
<template>
<div class="panel">
<div class="bulletin-board">
<div class="bulletin-board-title">工单看板</div>
<div class="bulletin-board-content">
<div>
<div>
<div>工单总数</div>
2025-07-23 15:23:57 +08:00
<div>{{ board.workOrdersTotal }}</div>
2025-07-22 18:55:04 +08:00
<div style="color: #1890FF">点击前往工单池</div>
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
<div>
<div>
<div>待派工单数</div>
2025-07-23 15:23:57 +08:00
<div>{{ board.notWorkOrdersTotal }}</div>
2025-07-22 18:55:04 +08:00
<div style="color: #1890FF">点击前往工单待办</div>
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
<div>
<div>
<div>未办结超时工单</div>
2025-07-23 15:23:57 +08:00
<div>{{ board.novertimeOrdersTotal }}</div>
<div>处理中的工单数<span style="color: green">{{ board.inHandOrdersTotal }}</span></div>
2025-07-22 18:55:04 +08:00
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
<div>
<div>
<div>当月工单超时率</div>
2025-07-23 15:23:57 +08:00
<div>{{ board.novertimeOrdersRate }}%</div>
<div>超时工单数<span style="color: red">{{ board.outTimeOrdersTotal }}</span></div>
2025-07-22 18:55:04 +08:00
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
<div>
<div>
<div>当月满意度</div>
2025-07-23 15:23:57 +08:00
<div>{{ board.monthoSatisfaction }}%</div>
<div>满意度{{ board.satisfaction }}</div>
2025-07-22 18:55:04 +08:00
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
</div>
</div>
<div class="chart">
<div class="chart-one">
<div>
2025-07-23 15:23:57 +08:00
<div>
<div style="font-size: 20px;font-weight: bold;margin-bottom: 20px;color: #464646">工单计数</div>
<div style="margin-left: 20px;line-height: 30px">
<div>累计处理工单数</div>
<div>12</div>
<div>累计回复数</div>
<div>2</div>
</div>
</div>
2025-07-22 18:55:04 +08:00
<EchartsUI
2025-07-23 15:23:57 +08:00
ref="workOrderCount"
height="400px"
2025-07-22 18:55:04 +08:00
width="100%"
2025-07-23 15:23:57 +08:00
style="background: #fff; border-radius: 8px;padding-top: 30px"
/>
</div>
<div>
<EchartsUI
ref="satisfactionLevel"
height="400px"
width="100%"
style="background: #fff; border-radius: 8px;padding-top: 18px"
2025-07-22 18:55:04 +08:00
/>
</div>
</div>
<div class="chart-two">
<div>
<EchartsUI
2025-07-23 15:23:57 +08:00
ref="orderNumber"
height="400px"
width="100%"
style="background: #fff; border-radius: 8px;padding-top: 18px"
/>
</div>
<div>
<EchartsUI
ref="orderTyper"
height="400px"
2025-07-22 18:55:04 +08:00
width="100%"
style="background: #fff; border-radius: 8px"
/>
</div>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.panel{
width: 100%;
padding: 40px;
box-sizing: border-box;
.bulletin-board{
.bulletin-board-title{
font-size: 25px;
font-weight: bold;
margin-bottom: 20px;
}
.bulletin-board-content{
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 40px;
> div{
height: auto;
background-color: #FFFFFF;
padding: 18px;
border-radius: 10px;
display: flex;
justify-content: space-between;
> div:first-child {
line-height: 32px;
div:nth-child(2) {
font-size: 20px;
font-weight: bold;
}
}
.icon-edit{
font-size: 30px;
}
}
}
}
.chart{
.chart-one{
margin-top:40px;
display: grid;
grid-template-columns: 2fr 1fr;
gap: 40px;
2025-07-23 15:23:57 +08:00
>div:first-child{
background-color: #FFFFFF;
border-radius: 8px;
display: grid;
grid-template-columns: 1fr 6fr;
>div:first-child{
padding: 18px 0 0 18px;
}
}
2025-07-22 18:55:04 +08:00
}
.chart-two{
margin-top:40px;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 40px;
}
}
}
</style>