车间能级提升-智能设备管理系统
zhuguifei
2025-05-26 bbfd68648872621be182fd51f3a56a09cd21e09e
eims-ui/apps/web-antd/src/views/index.vue
@@ -1,51 +1,166 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
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 { Avatar, Card, Col, Image, Row } from 'ant-design-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 faultChart = ref<EchartsUIType>();
const { renderEcharts: renderFaultChart } = useEcharts(faultChart);
const maintenChart = ref<EchartsUIType>();
const { renderEcharts: renderMaintenChart } = useEcharts(maintenChart);
const maintChart = ref<EchartsUIType>();
const { renderEcharts: renderMaintChart } = useEcharts(maintChart);
const todoItems = ref<any>([
  {
    completed: false,
    content: `审查最近提交到Git仓库的前端代码,确保代码质量和规范。`,
    date: '2024-07-30 11:00:00',
    title: '审查前端代码提交'
  },
  {
    completed: true,
    content: `检查并优化系统性能,降低CPU使用率。`,
    date: '2024-07-30 11:00:00',
    title: '系统性能优化'
    content: `为提升系统稳定性及用户体验,设备管理系统将于 2025年5月25日(星期日)凌晨0:00至4:00 进行例行系统维护升级。期间系统可能暂时无法访问,请您提前做好相关安排。`,
    date: '2025-05-18 10:12:00',
    title: '系统维护通知'
  },
  {
    completed: false,
    content: `进行系统安全检查,确保没有安全漏洞或未授权的访问。 `,
    date: '2024-07-30 11:00:00',
    title: '安全检查'
  },
    content: `为进一步规范设备故障处理流程,即日起所有设备报修需通过系统“故障报修”模块提交申请,请勿再使用线下纸质流程。技术支持人员将依据工单优先级及时响应处理。`,
    date: '2024-07-28 14:30:00',
    title: '新增设备报修流程说明'
  }
]);
const commonFunctions = ref<any>([
  {
    completed: false,
    content: `修复用户报告的页面UI显示问题,确保在不同浏览器中显示一致。 `,
    date: '2024-07-30 11:00:00',
    title: '修复UI显示问题'
    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'
  }
]);
onMounted(() => {
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: [
      {
@@ -99,16 +214,16 @@
          formatter(value: number) {
            switch (value) {
              case 0.125: {
                return 'Grade D';
                return '严重故障';
              }
              case 0.375: {
                return 'Grade C';
                return '急需维护';
              }
              case 0.625: {
                return 'Grade B';
                return '基本可用';
              }
              case 0.875: {
                return 'Grade A';
                return '可靠运行';
              }
              // No default
            }
@@ -130,7 +245,7 @@
        },
        data: [
          {
            value: 0.95,
            value: data?.normal,
            name: '正常设备占比'
          }
        ]
@@ -140,6 +255,12 @@
      trigger: 'item'
    }
  });
}
function initEquStatuChart(data: any) {
  showEquStatuSkeleton.value = false;
  const keyList = Object.keys(data);
  const valueList = Object.values(data);
  renderUseChart({
    tooltip: {
      trigger: 'axis',
@@ -161,13 +282,13 @@
    },
    yAxis: {
      type: 'category',
      data: ['待检', '在用', '停用', '其他', '报废']
      data: keyList
    },
    series: [
      {
        name: '2012',
        name: '2025',
        type: 'bar',
        data: [10, 63, 21, 91, 8],
        data: valueList,
        label: {
          show: true,
          position: 'right'
@@ -176,127 +297,60 @@
      }
    ]
  });
  renderRepairChart({
}
function initInspChart(data: any) {
  showInspSkeleton.value = false;
  const nameList = data?.data.map((item) => item.name);
  renderInspChart({
    tooltip: {
      trigger: 'item'
    },
    title: {
      left: '18%', // 基于容器宽度的50%
      top: '35%',
      text: `{a|10个}\n{b|未修复}\n{c|今日新增 +1}`,
      textStyle: {
        rich: {
          a: {
            color: '#4E5766',
            fontSize: 20,
            lineHeight: 30,
            align: 'center'
          },
          b: {
            color: '#1C2029',
            fontSize: 18,
            lineHeight: 30,
            align: 'center'
          },
          c: {
            color: '#ef6666',
            fontSize: 15,
            lineHeight: 30,
            align: 'center'
          }
        }
      }
      trigger: 'item',
      formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
      orient: 'vertical',
      top: 'center',
      right: 'right',
      left: '70%'
      data: nameList
    },
    series: [
      {
        name: 'Access From',
        name: '点检项',
        type: 'pie',
        radius: ['40%', '65%'], // 调整内外半径
        center: ['30%', '50%'], // 将饼图中心向左移一点
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 10,
          borderColor: '#fff',
          borderWidth: 2
        },
        selectedMode: 'single',
        radius: [0, '30%'],
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: false,
            fontSize: 40,
            fontWeight: 'bold'
          }
          position: 'inner',
          fontSize: 14
        },
        labelLine: {
          show: false
        },
        data: [
          { value: 10, name: '待接单' },
          { value: 8, name: '待维修' },
          { value: 9, name: '维修中' },
          { value: 16, name: '审核中' },
          { value: 8, name: '其他' }
        ]
      }
    ]
  });
  renderFaultChart({
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
        data: data?.sub
      },
      {
        type: 'category',
        data: ['smt', '贴片机', '注胶机'],
        axisTick: {
          alignWithLabel: true
        }
      }
    ],
    yAxis: [
      {
        type: 'value'
      }
    ],
    series: [
      {
        name: 'Direct',
        type: 'bar',
        barWidth: 20,
        data: [10, 8, 12],
        name: '点检',
        type: 'pie',
        radius: ['45%', '60%'],
        labelLine: {
          length: 30
        },
        label: {
          show: true,
          position: 'top'
        }
          show: true
        },
        data: data?.data
      }
    ]
  });
  renderMaintenChart({
}
function initRepairChart(data: any) {
  showRepairSkeleton.value = false;
  renderRepairChart({
    tooltip: {
      trigger: 'item'
    },
    title: {
      left: '21%', // 基于容器宽度的50%
      top: '40%',
      text: `{a|总台数}\n{b|20}`,
      text: `{a|总故障}\n{b|${data?.data?.length}}`,
      textStyle: {
        rich: {
          a: {
@@ -322,7 +376,7 @@
    },
    series: [
      {
        name: 'Access From',
        name: '设备维修',
        type: 'pie',
        radius: ['40%', '65%'], // 调整内外半径
        center: ['30%', '50%'], // 将饼图中心向左移一点
@@ -346,15 +400,142 @@
        labelLine: {
          show: false
        },
        data: [
          { value: 10, name: '未保养' },
          { value: 8, name: '待保养' },
          { value: 9, name: '保养中' },
          { value: 16, name: '待接单' }
        ]
        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>
@@ -367,13 +548,15 @@
          <label class="ml-2">常用功能</label>
        </template>
        <Row>
          <Col v-for="i in 9" :span="8" class="flex cursor-pointer flex-col items-center justify-center py-6 hover:bg-gray-100">
            <Avatar size="large" src="/src/assets/logo.png">
              <!--            <template #icon>
                          <UserOutlined />
                        </template>-->
            </Avatar>
            <label class="mt-1">设备台账{{ i }}</label>
          <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>
@@ -383,52 +566,59 @@
          <TagTwoTone />
          <span class="ml-2">使用状态</span>
        </template>
        <EchartsUI ref="useStatuChart" height="400px" />
        <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>
          <span class="ml-2">今日点检</span>
        </template>
        <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">3</span>
              <span>响应超时</span>
            </div>
            <div class="flex flex-col justify-center items-center w-1/3">
              <span class="font-bold text-xl">1</span>
              <span>维修超时</span>
            </div>
            <div class="flex flex-col justify-center items-center w-1/3">
              <span class="font-bold text-xl">0</span>
              <span>停机超时</span>
            </div>
          </div>
          <EchartsUI ref="repairChart" height="300px" width="400px" />
        </div>
        <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">
          <EchartsUI ref="instChart" width="400px" />
          <div class="flex justify-around pb-5">
        <div class="w-full pt-4">
          <Skeleton :loading="showInstSkeleton" :paragraph="{ rows: 12, width: 400 }" active>
            <div>
              <div class="text-center text-4xl">100<label class="ml-1 text-xl font-bold">台</label></div>
              <div class="text-center font-bold">设备总数</div>
            </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">5<label class="ml-1 text-xl font-bold">台</label></div>
              <div class="text-center font-bold">故障总数</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>
          </div>
          </Skeleton>
        </div>
      </Card>
      <Card :bordered="false" class="section-height mt-2 rounded-none">
@@ -472,26 +662,43 @@
      <Card :bordered="false" class="section-height mt-2 rounded-none">
        <template #title>
          <TagTwoTone />
          <span class="ml-2">故障统计</span>
          <span class="ml-2">本月维修</span>
        </template>
        <span class="text-gray-500 text-xs ml-3">故障次数:10</span>
        <EchartsUI  ref="faultChart"  height="360px" />
      </Card>
        <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="/src/assets/logo.png" />
          <span class="mr-2 font-bold" style="color: #2d83f4">故障知识库</span>
          <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="/src/assets/logo.png" />
          <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="/src/assets/logo.png" />
          <Image :preview="false" :width="20" src="/static/menu/ico13.png" />
          <span class="mr-2 font-bold" style="color: #32b9af">帮助中心</span>
        </div>
      </div>
@@ -504,36 +711,38 @@
        <div class="todo-title mt-5">设备管理</div>
        <div class="flex w-full flex-wrap justify-between">
          <div
            v-for="index in 12"
            v-for="(item, index) in todoMenu"
            :class="{
              'justify-center': index % 3 == 2,
              'justify-end': index % 3 == 0,
              'mt-2': index > 3
              '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" :width="20" src="/src/assets/logo.png" />
              <span>故障审核</span>
              <span>{{ index }}</span>
              <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-20">备件管理</div>
        <div class="todo-title mt-44">备件管理</div>
        <div class="flex w-full flex-wrap justify-between">
          <div
            v-for="index in 3"
            v-for="(item, index) in spareMenu"
            :class="{
              'justify-center': index % 3 == 2,
              'justify-end': index % 3 == 0
              '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" :width="20" src="/src/assets/logo.png" />
              <span>故障审核</span>
              <span>{{ index }}</span>
              <Image :preview="false" :src="item?.icon" :width="20" />
              <span>{{ item.menu }}</span>
              <span>{{}}</span>
            </div>
          </div>
        </div>
@@ -548,25 +757,25 @@
          <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">7</span>
                <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="/src/assets/img/img-up-limit.png" />
              <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">10</span>
                <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="/src/assets/img/img-lower-limit.png" />
              <Image :preview="false" src="/static/img/img-lower-limit.png" />
            </div>
          </div>
        </div>
@@ -575,26 +784,28 @@
      <Card :bordered="false" class="section-height mt-2 rounded-none">
        <template #title>
          <TagTwoTone />
          <span class="ml-2">设备保养</span>
          <span class="ml-2">本月保养</span>
        </template>
        <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">3</span>
              <span>未保养</span>
        <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>
            <div class="flex flex-col justify-center items-center w-1/3">
              <span class="font-bold text-xl">1</span>
              <span>本月到期</span>
            </div>
            <div class="flex flex-col justify-center items-center w-1/3">
              <span class="font-bold text-xl">0</span>
              <span>下月到期</span>
            </div>
          </div>
          <EchartsUI ref="maintenChart" height="300px" width="400px" />
        </div>
            <EchartsUI ref="maintChart" height="300px" width="400px" />
          </div>
        </Skeleton>
      </Card>
    </div>
  </div>