Files
admin-vben5/apps/web-antd/src/views/property/customerService/centerConsole/index.vue
2025-07-23 15:23:57 +08:00

326 lines
8.0 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.

<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";
import {countsList} from '#/api/property/customerService/centerConsole'
const board = ref ({})
const getBoard = async () => {
board.value = await countsList();
}
const xAxisData = ref<any[]>([]);
const seriesData = ref<any[]>([]);
// 工单计数
const workOrderCount = ref<EchartsUIType>();
const { renderEcharts: renderWorkOrderCount } = useEcharts(workOrderCount);
async function fetchWorkOrderCount() {
xAxisData.value = board.value.recentWeekWorkOrders
console.log(xAxisData.value)
renderWorkOrderCount({
tooltip: { trigger: 'axis' },
xAxis: {
type: 'category',
boundaryGap: false,
data: ['06-17周二', '06-17周二', '06-17周二', '06-17周二', '06-17周二', '06-17周二', '06-17周二']
},
yAxis: {
type: 'value',
name: '近一周工单数',
},
series: [
{
data: [6, 2, 0, 1, 0, 0, 1],
type: 'line',
areaStyle: {},
smooth: true,
}
]
});
}
// 满意度指数
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' }
]
}
]
})
}
onMounted(async () => {
await getBoard()
await fetchWorkOrderCount()
await fetchSatisfactionLevel()
await fetchOrderNumber()
await fetchOrderTyper()
})
</script>
<template>
<div class="panel">
<div class="bulletin-board">
<div class="bulletin-board-title">工单看板</div>
<div class="bulletin-board-content">
<div>
<div>
<div>工单总数</div>
<div>{{ board.workOrdersTotal }}</div>
<div style="color: #1890FF">点击前往工单池</div>
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
<div>
<div>
<div>待派工单数</div>
<div>{{ board.notWorkOrdersTotal }}</div>
<div style="color: #1890FF">点击前往工单待办</div>
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
<div>
<div>
<div>未办结超时工单</div>
<div>{{ board.novertimeOrdersTotal }}</div>
<div>处理中的工单数<span style="color: green">{{ board.inHandOrdersTotal }}</span></div>
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
<div>
<div>
<div>当月工单超时率</div>
<div>{{ board.novertimeOrdersRate }}%</div>
<div>超时工单数<span style="color: red">{{ board.outTimeOrdersTotal }}</span></div>
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
<div>
<div>
<div>当月满意度</div>
<div>{{ board.monthoSatisfaction }}%</div>
<div>满意度{{ board.satisfaction }}</div>
</div>
<div class="icon-edit"><EditOutlined /></div>
</div>
</div>
</div>
<div class="chart">
<div class="chart-one">
<div>
<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>
<EchartsUI
ref="workOrderCount"
height="400px"
width="100%"
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"
/>
</div>
</div>
<div class="chart-two">
<div>
<EchartsUI
ref="orderNumber"
height="400px"
width="100%"
style="background: #fff; border-radius: 8px;padding-top: 18px"
/>
</div>
<div>
<EchartsUI
ref="orderTyper"
height="400px"
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;
>div:first-child{
background-color: #FFFFFF;
border-radius: 8px;
display: grid;
grid-template-columns: 1fr 6fr;
>div:first-child{
padding: 18px 0 0 18px;
}
}
}
.chart-two{
margin-top:40px;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 40px;
}
}
}
</style>