<script setup lang="ts">
|
import { computed, onMounted, ref } from 'vue';
|
import { useRouter } from 'vue-router';
|
|
import { EchartsUI, type EchartsUIType, useEcharts } from '@vben/plugins/echarts';
|
|
import { AlertTwoTone, NotificationTwoTone, TagTwoTone } from '@ant-design/icons-vue';
|
import { Card, Col, Image, Row, Skeleton } from 'ant-design-vue';
|
|
import { queryEquStatu, queryMonthMainit, queryMonthReq, querySpareWarn, queryTodayInsp, queryTodoList } from '#/api/eims/dashboard';
|
import { listEqu } from '#/api/eims/equ';
|
import { listRepairRes } from '#/api/eims/repair-res';
|
|
const router = useRouter();
|
|
const equTotal = ref<number>(0);
|
const equFaultTotal = ref<number>(0);
|
|
const showInstSkeleton = ref<boolean>(true);
|
const showEquStatuSkeleton = ref<boolean>(true);
|
const showInspSkeleton = ref<boolean>(true);
|
const showRepairSkeleton = ref<boolean>(true);
|
const showMaintSkeleton = ref<boolean>(true);
|
|
const instChart = ref<EchartsUIType>();
|
const { renderEcharts: renderInstChart } = useEcharts(instChart);
|
const useStatuChart = ref<EchartsUIType>();
|
const { renderEcharts: renderUseChart } = useEcharts(useStatuChart);
|
const inspChart = ref<EchartsUIType>();
|
const { renderEcharts: renderInspChart } = useEcharts(inspChart);
|
const repairChart = ref<EchartsUIType>();
|
const { renderEcharts: renderRepairChart } = useEcharts(repairChart);
|
const maintChart = ref<EchartsUIType>();
|
const { renderEcharts: renderMaintChart } = useEcharts(maintChart);
|
|
const todoItems = ref<any>([
|
{
|
completed: false,
|
content: `为提升系统稳定性及用户体验,设备管理系统将于 2025年5月25日(星期日)凌晨0:00至4:00 进行例行系统维护升级。期间系统可能暂时无法访问,请您提前做好相关安排。`,
|
date: '2025-05-18 10:12:00',
|
title: '系统维护通知'
|
},
|
{
|
completed: false,
|
content: `为进一步规范设备故障处理流程,即日起所有设备报修需通过系统“故障报修”模块提交申请,请勿再使用线下纸质流程。技术支持人员将依据工单优先级及时响应处理。`,
|
date: '2024-07-28 14:30:00',
|
title: '新增设备报修流程说明'
|
}
|
]);
|
const commonFunctions = ref<any>([
|
{
|
menu: '故障报修',
|
path: '/repair/repairReq',
|
icon: '/static/menu/ico1.png'
|
},
|
{
|
menu: '维修工单',
|
path: '/repair/repairRes',
|
icon: '/static/menu/ico2.png'
|
},
|
{
|
menu: '点检汇总',
|
path: '/inspect/st',
|
icon: '/static/menu/ico3.png'
|
},
|
{
|
menu: '点检计划',
|
path: '/inspect/plan',
|
icon: '/static/menu/ico4.png'
|
},
|
{
|
menu: '保养汇总',
|
path: '/maint/st',
|
icon: '/static/menu/ico5.png'
|
},
|
{
|
menu: '保养计划',
|
path: '/maint/plan',
|
icon: '/static/menu/ico6.png'
|
},
|
{
|
menu: '设备台账',
|
path: '/equ/ledger',
|
icon: '/static/menu/ico7.png'
|
}
|
]);
|
|
const todoMenu = ref<any>([
|
{
|
menu: '故障报修',
|
path: '/repair/repairReq',
|
icon: '/static/menu/ico1.png'
|
},
|
{
|
menu: '维修任务',
|
path: '/repair/repairRes',
|
icon: '/static/menu/ico2.png'
|
},
|
{
|
menu: '维修评价',
|
path: '/repair/repairRes',
|
icon: '/static/menu/ico2.png'
|
},
|
{
|
menu: '点检任务',
|
path: '/inspect/st',
|
icon: '/static/menu/ico3.png'
|
},
|
{
|
menu: '保养任务',
|
path: '/maint/st',
|
icon: '/static/menu/ico5.png'
|
},
|
{
|
menu: '状态变更',
|
path: '/equ/equStatu',
|
icon: '/static/menu/ico5.png'
|
},
|
{
|
menu: '设备台账',
|
path: '/equ/ledger',
|
icon: '/static/menu/ico7.png'
|
}
|
]);
|
|
// 备件预警
|
const spareWarn = ref<any>({});
|
// 设备使用状态
|
const equStatu = ref<any>({});
|
// 今日点检
|
const todayInsp = ref<any>({});
|
// 本月故障
|
const monthReq = ref<any>({});
|
// 本月保养
|
const monthMaint = ref<any>({});
|
|
const spareMenu = ref<any>([
|
{
|
menu: '备件台账',
|
path: '/spare/index',
|
icon: '/static/menu/ico8.png'
|
},
|
{
|
menu: '入库单',
|
path: '/spare/in',
|
icon: '/static/menu/ico9.png'
|
},
|
{
|
menu: '出库单',
|
path: '/spare/out',
|
icon: '/static/menu/ico10.png'
|
}
|
]);
|
|
function itemClick(item: any) {
|
router.push(item.path);
|
}
|
function goToKnowledge() {
|
router.push('/faultKnow');
|
}
|
|
function initInstChart(data: any) {
|
showInstSkeleton.value = false;
|
renderInstChart({
|
series: [
|
{
|
type: 'gauge',
|
startAngle: 180,
|
endAngle: 0,
|
center: ['50%', '75%'],
|
radius: '90%',
|
min: 0,
|
max: 1,
|
splitNumber: 8,
|
axisLine: {
|
lineStyle: {
|
width: 6,
|
color: [
|
[0.25, '#FF6E76'],
|
[0.5, '#FDDD60'],
|
[0.75, '#58D9F9'],
|
[1, '#7CFFB2']
|
]
|
}
|
},
|
pointer: {
|
icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
|
length: '12%',
|
width: 20,
|
offsetCenter: [0, '-60%'],
|
itemStyle: {
|
color: 'auto'
|
}
|
},
|
axisTick: {
|
length: 12,
|
lineStyle: {
|
color: 'auto',
|
width: 2
|
}
|
},
|
splitLine: {
|
length: 20,
|
lineStyle: {
|
color: 'auto',
|
width: 5
|
}
|
},
|
axisLabel: {
|
color: '#464646',
|
fontSize: 20,
|
distance: -60,
|
rotate: 'tangential',
|
formatter(value: number) {
|
switch (value) {
|
case 0.125: {
|
return '严重故障';
|
}
|
case 0.375: {
|
return '急需维护';
|
}
|
case 0.625: {
|
return '基本可用';
|
}
|
case 0.875: {
|
return '可靠运行';
|
}
|
// No default
|
}
|
return '';
|
}
|
},
|
title: {
|
offsetCenter: [0, '-10%'],
|
fontSize: 20
|
},
|
detail: {
|
fontSize: 30,
|
offsetCenter: [0, '-35%'],
|
valueAnimation: true,
|
formatter(value: number) {
|
return `${Math.round(value * 100)}%`;
|
},
|
color: 'inherit'
|
},
|
data: [
|
{
|
value: data?.normal,
|
name: '正常设备占比'
|
}
|
]
|
}
|
],
|
tooltip: {
|
trigger: 'item'
|
}
|
});
|
}
|
|
function initEquStatuChart(data: any) {
|
showEquStatuSkeleton.value = false;
|
const keyList = Object.keys(data);
|
const valueList = Object.values(data);
|
renderUseChart({
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'shadow'
|
}
|
},
|
legend: {
|
show: false
|
},
|
grid: {
|
show: false
|
},
|
xAxis: {
|
type: 'value',
|
boundaryGap: [0, 0.01],
|
splitLine: { show: false }, // 隐藏网格线
|
axisTick: { show: false } // 隐藏刻度线
|
},
|
yAxis: {
|
type: 'category',
|
data: keyList
|
},
|
series: [
|
{
|
name: '2025',
|
type: 'bar',
|
data: valueList,
|
label: {
|
show: true,
|
position: 'right'
|
},
|
barWidth: 20
|
}
|
]
|
});
|
}
|
|
function initInspChart(data: any) {
|
showInspSkeleton.value = false;
|
const nameList = data?.data.map((item) => item.name);
|
renderInspChart({
|
tooltip: {
|
trigger: 'item',
|
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
},
|
legend: {
|
data: nameList
|
},
|
series: [
|
{
|
name: '点检项',
|
type: 'pie',
|
selectedMode: 'single',
|
radius: [0, '30%'],
|
label: {
|
position: 'inner',
|
fontSize: 14
|
},
|
labelLine: {
|
show: false
|
},
|
data: data?.sub
|
},
|
{
|
name: '点检',
|
type: 'pie',
|
radius: ['45%', '60%'],
|
labelLine: {
|
length: 30
|
},
|
label: {
|
show: true
|
},
|
data: data?.data
|
}
|
]
|
});
|
}
|
|
function initRepairChart(data: any) {
|
showRepairSkeleton.value = false;
|
renderRepairChart({
|
tooltip: {
|
trigger: 'item'
|
},
|
title: {
|
left: '21%', // 基于容器宽度的50%
|
top: '40%',
|
text: `{a|总故障}\n{b|${data?.data?.length}}`,
|
textStyle: {
|
rich: {
|
a: {
|
color: '#4E5766',
|
fontSize: 20,
|
lineHeight: 30,
|
align: 'center'
|
},
|
b: {
|
color: '#1C2029',
|
fontSize: 18,
|
lineHeight: 30,
|
align: 'center'
|
}
|
}
|
}
|
},
|
legend: {
|
orient: 'vertical',
|
top: 'center',
|
right: 'right',
|
left: '70%'
|
},
|
series: [
|
{
|
name: '设备维修',
|
type: 'pie',
|
radius: ['40%', '65%'], // 调整内外半径
|
center: ['30%', '50%'], // 将饼图中心向左移一点
|
avoidLabelOverlap: false,
|
itemStyle: {
|
borderRadius: 10,
|
borderColor: '#fff',
|
borderWidth: 2
|
},
|
label: {
|
show: false,
|
position: 'center'
|
},
|
emphasis: {
|
label: {
|
show: false,
|
fontSize: 40,
|
fontWeight: 'bold'
|
}
|
},
|
labelLine: {
|
show: false
|
},
|
data: data?.data
|
}
|
]
|
});
|
}
|
|
function initMaintChart(data: any) {
|
showMaintSkeleton.value = false;
|
renderMaintChart({
|
tooltip: {
|
trigger: 'item'
|
},
|
title: {
|
left: '21%', // 基于容器宽度的50%
|
top: '40%',
|
text: `{a|总保养}\n{b|${data?.data?.length}}`,
|
textStyle: {
|
rich: {
|
a: {
|
color: '#4E5766',
|
fontSize: 20,
|
lineHeight: 30,
|
align: 'center'
|
},
|
b: {
|
color: '#1C2029',
|
fontSize: 18,
|
lineHeight: 30,
|
align: 'center'
|
}
|
}
|
}
|
},
|
legend: {
|
orient: 'vertical',
|
top: 'center',
|
right: 'right',
|
left: '70%'
|
},
|
series: [
|
{
|
name: '保养',
|
type: 'pie',
|
radius: ['40%', '65%'], // 调整内外半径
|
center: ['30%', '50%'], // 将饼图中心向左移一点
|
avoidLabelOverlap: false,
|
itemStyle: {
|
borderRadius: 10,
|
borderColor: '#fff',
|
borderWidth: 2
|
},
|
label: {
|
show: false,
|
position: 'center'
|
},
|
emphasis: {
|
label: {
|
show: false,
|
fontSize: 40,
|
fontWeight: 'bold'
|
}
|
},
|
labelLine: {
|
show: false
|
},
|
data: data?.data
|
}
|
]
|
});
|
}
|
|
async function initData() {
|
const equResult = await listEqu();
|
const repairRes = await listRepairRes();
|
const equCount = equResult?.total || 0;
|
const rpairTotal = repairRes?.total || 0;
|
const instData = { normal: 0 };
|
if (rpairTotal > 0 && equCount > 0) {
|
equTotal.value = equCount;
|
equFaultTotal.value = rpairTotal;
|
instData.normal = (equCount - rpairTotal) / equCount;
|
}
|
initInstChart(instData);
|
|
const todoList = await queryTodoList();
|
todoMenu.value = todoMenu.value.map((frontendItem: any) => {
|
// 查找对应menu的后端数据
|
const backendItem = todoList?.find((item: any) => item.menu === frontendItem.menu);
|
// 如果找到了对应的后端数据,则合并之(不覆盖已有的属性)
|
if (backendItem) {
|
frontendItem = { ...frontendItem, ...backendItem };
|
}
|
return frontendItem;
|
});
|
spareWarn.value = await querySpareWarn();
|
equStatu.value = await queryEquStatu();
|
initEquStatuChart(equStatu.value);
|
const tInsp = (await queryTodayInsp()) || {};
|
todayInsp.value = tInsp;
|
initInspChart(tInsp);
|
monthReq.value = (await queryMonthReq()) || {};
|
initRepairChart(monthReq.value);
|
monthMaint.value = (await queryMonthMainit()) || {};
|
initMaintChart(monthMaint.value);
|
}
|
|
onMounted(async () => {
|
initData();
|
});
|
|
const todayInspTotal = computed(() => {
|
return todayInsp.value?.data?.reduce((sum, item) => sum + item.value, 0);
|
});
|
|
const todayInspFinish = computed(() => {
|
return todayInsp.value?.data?.filter((item) => item.name === '已完成').reduce((sum, item) => sum + item.value, 0);
|
});
|
|
const finishReqCount = computed(() => {
|
const completedItem = monthReq.value?.data?.find((item) => item.name === '已完成');
|
return completedItem ? completedItem.value : 0;
|
});
|
|
const reqCount = computed(() => {
|
// 已完成
|
return monthReq.value?.data?.reduce((sum, item) => sum + item.value, 0);
|
});
|
|
const maintCount = computed(() => {
|
// 已完成
|
return monthMaint.value?.data?.reduce((sum, item) => sum + item.value, 0);
|
});
|
|
const finishMaintCount = computed(() => {
|
const completedItem = monthMaint.value?.data?.find((item) => item.name === '已完成');
|
return completedItem ? completedItem.value : 0;
|
});
|
</script>
|
|
<template>
|
<div class="main flex justify-center p-2">
|
<div class="mr-2 w-1/3">
|
<Card :bordered="false" class="section-height rounded-none">
|
<template #title>
|
<TagTwoTone />
|
<label class="ml-2">常用功能</label>
|
</template>
|
<Row>
|
<Col
|
v-for="(item, index) in commonFunctions"
|
:key="index"
|
:span="8"
|
class="flex cursor-pointer flex-col items-center justify-center py-6 hover:bg-gray-100"
|
@click.stop="itemClick(item)"
|
>
|
<Image :preview="false" :src="item.icon" :width="35" />
|
<label class="mt-1"> {{ item.menu }}</label>
|
</Col>
|
</Row>
|
</Card>
|
|
<Card :bordered="false" class="section-height mt-2 rounded-none">
|
<template #title>
|
<TagTwoTone />
|
<span class="ml-2">使用状态</span>
|
</template>
|
<Skeleton :loading="showInstSkeleton" :paragraph="{ rows: 12, width: 400 }" active>
|
<EchartsUI ref="useStatuChart" height="400px" />
|
</Skeleton>
|
</Card>
|
|
<Card :bordered="false" class="section-height mt-2 rounded-none">
|
<template #title>
|
<TagTwoTone />
|
<span class="ml-2">今日点检</span>
|
</template>
|
|
<Skeleton :loading="showInspSkeleton" :paragraph="{ rows: 12, width: 400 }" active>
|
<div class="flex w-full flex-col justify-center items-center">
|
<div class="flex w-full py-3">
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl">{{ todayInspTotal }}</span>
|
<span>点检批次</span>
|
</div>
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl"></span>
|
<span> </span>
|
</div>
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl">{{ todayInspFinish }}</span>
|
<span>已完成</span>
|
</div>
|
</div>
|
|
<EchartsUI ref="inspChart" height="300px" width="400px" />
|
</div>
|
</Skeleton>
|
</Card>
|
</div>
|
|
<div class="mr-2 w-1/3">
|
<Card :bordered="false" class="section-height flex justify-center rounded-none p-0">
|
<div class="w-full pt-4">
|
<Skeleton :loading="showInstSkeleton" :paragraph="{ rows: 12, width: 400 }" active>
|
<div>
|
<EchartsUI ref="instChart" width="400px" />
|
<div class="flex justify-around pb-5">
|
<div>
|
<div class="text-center text-4xl">{{ equTotal }}<label class="ml-1 text-xl font-bold">台</label></div>
|
<div class="text-center font-bold">设备总数</div>
|
</div>
|
|
<div>
|
<div class="text-center text-4xl text-red-500">{{ equFaultTotal }}<label class="ml-1 text-xl font-bold">台</label></div>
|
<div class="text-center font-bold">故障总数</div>
|
</div>
|
</div>
|
</div>
|
</Skeleton>
|
</div>
|
</Card>
|
<Card :bordered="false" class="section-height mt-2 rounded-none">
|
<template #title>
|
<NotificationTwoTone />
|
<span class="ml-2">公告</span>
|
</template>
|
<template #extra>
|
<a-button type="link">查看更多 ></a-button>
|
</template>
|
|
<div>
|
<ul class="divide-border w-full divide-y" role="list">
|
<li
|
v-for="item in todoItems"
|
:key="item.title"
|
:class="{
|
'select-none line-through opacity-60': item.completed
|
}"
|
class="flex cursor-pointer justify-between gap-x-6 py-5"
|
>
|
<div class="flex min-w-0 items-center gap-x-4">
|
<div class="min-w-0 flex-auto">
|
<p class="text-foreground text-sm font-semibold leading-6">
|
{{ item.title }}
|
</p>
|
<!-- eslint-disable vue/no-v-html -->
|
<p class="text-foreground/80 *:text-primary mt-1 truncate text-xs leading-5" v-html="item.content"></p>
|
</div>
|
</div>
|
<div class="hidden h-full shrink-0 sm:flex sm:flex-col sm:items-end">
|
<span class="text-foreground/80 mt-6 text-xs leading-6">
|
{{ item.date }}
|
</span>
|
</div>
|
</li>
|
</ul>
|
</div>
|
</Card>
|
|
<Card :bordered="false" class="section-height mt-2 rounded-none">
|
<template #title>
|
<TagTwoTone />
|
<span class="ml-2">本月维修</span>
|
</template>
|
<Skeleton :loading="showRepairSkeleton" :paragraph="{ rows: 12, width: 400 }" active>
|
<div class="flex w-full flex-col justify-center items-center">
|
<div class="flex w-full py-3">
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl">{{ reqCount || 0 }}</span>
|
<span>本月报修</span>
|
</div>
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl">{{ monthReq?.today?.length || 0 }}</span>
|
<span>今日新增</span>
|
</div>
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl">{{ finishReqCount }}</span>
|
<span>本月完成</span>
|
</div>
|
</div>
|
|
<EchartsUI ref="repairChart" height="300px" width="400px" />
|
</div>
|
</Skeleton>
|
</Card>
|
</div>
|
|
<div class="w-1/3">
|
<div class="flex h-14 items-center justify-around rounded-none bg-white p-0">
|
<div class="flex h-10 w-28 cursor-pointer items-center justify-around rounded-sm hover:bg-gray-100" style="background: #eaf3fe">
|
<Image :preview="false" :width="20" src="/static/menu/ico11.png" />
|
<span class="mr-2 font-bold" style="color: #2d83f4" @click="goToKnowledge()">故障知识库</span>
|
</div>
|
<div class="flex h-10 w-28 cursor-pointer items-center justify-around rounded-sm hover:bg-gray-100" style="background: #eaeafe">
|
<Image :preview="false" :width="20" src="/static/menu/ico12.png" />
|
<span class="mr-2 font-bold" style="color: #5070e0">智能搜索</span>
|
</div>
|
<div class="flex h-10 w-28 cursor-pointer items-center justify-around rounded-sm hover:bg-gray-100" style="background: #ebf8f7">
|
<Image :preview="false" :width="20" src="/static/menu/ico13.png" />
|
<span class="mr-2 font-bold" style="color: #32b9af">帮助中心</span>
|
</div>
|
</div>
|
<Card :bordered="false" class="todo-height mt-2 rounded-none">
|
<template #title>
|
<TagTwoTone />
|
<span class="ml-2">待办事项</span>
|
</template>
|
|
<div class="todo-title mt-5">设备管理</div>
|
<div class="flex w-full flex-wrap justify-between">
|
<div
|
v-for="(item, index) in todoMenu"
|
:class="{
|
'justify-center': (index + 1) % 3 == 2,
|
'justify-end': (index + 1) % 3 == 0,
|
'mt-2': index > 2
|
}"
|
class="flex w-1/3"
|
@click="itemClick(item)"
|
>
|
<div class="todo-box cursor-pointer hover:bg-gray-100">
|
<Image :preview="false" :src="item?.icon" :width="20" />
|
<span>{{ item.menu }}</span>
|
<span>{{ item?.count || 0 }}</span>
|
</div>
|
</div>
|
</div>
|
|
<div class="todo-title mt-44">备件管理</div>
|
<div class="flex w-full flex-wrap justify-between">
|
<div
|
v-for="(item, index) in spareMenu"
|
:class="{
|
'justify-center': (index + 1) % 3 == 2,
|
'justify-end': (index + 1) % 3 == 0
|
}"
|
class="flex w-1/3"
|
@click="itemClick(item)"
|
>
|
<div class="todo-box border-gray-100">
|
<Image :preview="false" :src="item?.icon" :width="20" />
|
<span>{{ item.menu }}</span>
|
<span>{{}}</span>
|
</div>
|
</div>
|
</div>
|
</Card>
|
|
<Card :bordered="false" class="early-warn-height mt-2 rounded-none">
|
<template #title>
|
<AlertTwoTone two-tone-color="red" />
|
<span class="ml-2">预警管理</span>
|
</template>
|
<div class="flex h-full items-center">
|
<div class="up-info-box w-1/2 flex h-40">
|
<div class="w-1/2 flex items-center h-full justify-center flex-col">
|
<div class="w-16">
|
<span class="text-xl text-green-600">{{ spareWarn?.upper || 0 }}</span>
|
<span class="ml-1">种</span>
|
</div>
|
<div class="w-16">高于上限</div>
|
</div>
|
<div class="w-1/2 h-full flex items-center justify-center">
|
<Image :preview="false" src="/static/img/img-up-limit.png" />
|
</div>
|
</div>
|
<div class="low-info-box w-1/2 flex h-40">
|
<div class="w-1/2 flex items-center h-full justify-center flex-col">
|
<div class="w-16">
|
<span class="text-xl text-red-600">{{ spareWarn?.lower || 0 }}</span>
|
<span class="ml-1">种</span>
|
</div>
|
<div class="w-16">低于下限</div>
|
</div>
|
<div class="w-1/2 h-full flex items-center justify-center">
|
<Image :preview="false" src="/static/img/img-lower-limit.png" />
|
</div>
|
</div>
|
</div>
|
</Card>
|
|
<Card :bordered="false" class="section-height mt-2 rounded-none">
|
<template #title>
|
<TagTwoTone />
|
<span class="ml-2">本月保养</span>
|
</template>
|
<Skeleton :loading="showMaintSkeleton" :paragraph="{ rows: 12, width: 400 }" active>
|
<div class="flex w-full flex-col justify-center items-center">
|
<div class="flex w-full py-3">
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl">{{ maintCount || 0 }}</span>
|
<span>本月保养</span>
|
</div>
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl">{{ maintCount - finishMaintCount }}</span>
|
<span>未完成</span>
|
</div>
|
<div class="flex flex-col justify-center items-center w-1/3">
|
<span class="font-bold text-xl">{{ finishMaintCount }}</span>
|
<span>已完成</span>
|
</div>
|
</div>
|
|
<EchartsUI ref="maintChart" height="300px" width="400px" />
|
</div>
|
</Skeleton>
|
</Card>
|
</div>
|
</div>
|
</template>
|
|
<style scoped lang="scss">
|
.main {
|
height: 2000px;
|
}
|
|
.section-height {
|
height: 484px;
|
}
|
|
.todo-height {
|
height: 644px;
|
}
|
|
.early-warn-height {
|
height: 260px;
|
|
:deep(.ant-card-body) {
|
height: calc(100% - 56px);
|
}
|
|
.up-info-box {
|
background: #f2faff;
|
}
|
|
.low-info-box {
|
background: #fff5eb;
|
}
|
}
|
|
.todo-title {
|
width: 100px;
|
height: 30px;
|
background: #ecf3fe;
|
border-left: 2px solid #2c83f4;
|
line-height: 30px;
|
text-align: center;
|
color: #2d83f4;
|
clip-path: polygon(0 0, 100% 0, 90% 100%, 0% 100%);
|
border-bottom-right-radius: 15px;
|
border-top-right-radius: 5px;
|
}
|
|
.todo-box {
|
width: 120px;
|
height: 42px;
|
background: #f5f6f7;
|
padding: 10px;
|
display: flex;
|
flex-wrap: nowrap;
|
overflow: hidden;
|
align-content: center;
|
justify-content: space-around;
|
margin-top: 20px;
|
cursor: pointer;
|
}
|
|
.todo-box:hover {
|
background: #eaf3fe;
|
}
|
</style>
|