| | |
| | | <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: [ |
| | | { |
| | |
| | | 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 |
| | | } |
| | |
| | | }, |
| | | data: [ |
| | | { |
| | | value: 0.95, |
| | | value: data?.normal, |
| | | name: '正常设备占比' |
| | | } |
| | | ] |
| | |
| | | trigger: 'item' |
| | | } |
| | | }); |
| | | } |
| | | |
| | | function initEquStatuChart(data: any) { |
| | | showEquStatuSkeleton.value = false; |
| | | const keyList = Object.keys(data); |
| | | const valueList = Object.values(data); |
| | | renderUseChart({ |
| | | tooltip: { |
| | | trigger: 'axis', |
| | |
| | | }, |
| | | 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' |
| | |
| | | } |
| | | ] |
| | | }); |
| | | 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: { |
| | |
| | | }, |
| | | series: [ |
| | | { |
| | | name: 'Access From', |
| | | name: '设备维修', |
| | | type: 'pie', |
| | | radius: ['40%', '65%'], // 调整内外半径 |
| | | center: ['30%', '50%'], // 将饼图中心向左移一点 |
| | |
| | | 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> |
| | | |
| | |
| | | <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> |
| | |
| | | <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"> |
| | |
| | | <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> |
| | |
| | | <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> |
| | |
| | | <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> |
| | |
| | | <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> |