|
@@ -4,7 +4,7 @@
|
|
|
<!-- 原有的统计卡片部分保持不变 -->
|
|
|
<el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
<SummaryCard
|
|
|
- :value="summary?.userCount || 0"
|
|
|
+ :value="device.total || 0"
|
|
|
icon="fa-solid:project-diagram"
|
|
|
icon-bg-color="text-blue-500"
|
|
|
icon-color="bg-blue-100"
|
|
@@ -13,65 +13,65 @@
|
|
|
</el-col>
|
|
|
<el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
<SummaryCard
|
|
|
- :value="summary?.userCount || 0"
|
|
|
+ :value="maintain.total || 0"
|
|
|
icon="fa-solid:list"
|
|
|
- icon-bg-color="text-blue-500"
|
|
|
+ icon-bg-color="text-pink-500"
|
|
|
icon-color="bg-blue-100"
|
|
|
title="维修工单"
|
|
|
/>
|
|
|
</el-col>
|
|
|
<el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
<SummaryCard
|
|
|
- :value="summary?.rechargeUserCount || 0"
|
|
|
+ :value="fill.unfilledCount || 0"
|
|
|
icon="fa-solid:times-circle"
|
|
|
icon-bg-color="text-purple-500"
|
|
|
icon-color="bg-purple-100"
|
|
|
- title="未填写运行记录"
|
|
|
+ title="运行未填写"
|
|
|
/>
|
|
|
</el-col>
|
|
|
<el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
<SummaryCard
|
|
|
- :value="fenToYuan(summary?.rechargePrice || 0)"
|
|
|
+ :value="fill.filledCount || 0"
|
|
|
icon="fa-solid:award"
|
|
|
icon-bg-color="text-purple-500"
|
|
|
icon-color="bg-purple-100"
|
|
|
- title="已填写运行记录"
|
|
|
+ title="运行已填写"
|
|
|
/>
|
|
|
</el-col>
|
|
|
<el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
<SummaryCard
|
|
|
- :value="fenToYuan(summary?.expensePrice || 0)"
|
|
|
+ :value="by.todo || 0"
|
|
|
icon="fa-solid:times-circle"
|
|
|
icon-bg-color="text-green-500"
|
|
|
icon-color="bg-green-100"
|
|
|
- title="未执行保养工单"
|
|
|
+ title="未执行保养"
|
|
|
/>
|
|
|
</el-col>
|
|
|
<el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
<SummaryCard
|
|
|
- :value="fenToYuan(summary?.expensePrice || 0)"
|
|
|
+ :value="by.finished || 0"
|
|
|
icon="fa-solid:award"
|
|
|
icon-bg-color="text-green-500"
|
|
|
icon-color="bg-green-100"
|
|
|
- title="已执行保养工单"
|
|
|
+ title="已执行保养"
|
|
|
/>
|
|
|
</el-col>
|
|
|
<el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
<SummaryCard
|
|
|
- :value="fenToYuan(summary?.expensePrice || 0)"
|
|
|
+ :value="inspect.todo || 0"
|
|
|
icon="fa-solid:times-circle"
|
|
|
icon-bg-color="text-yellow-500"
|
|
|
icon-color="bg-yellow-100"
|
|
|
- title="待填写巡检工单"
|
|
|
+ title="待填写巡检"
|
|
|
/>
|
|
|
</el-col>
|
|
|
<el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
<SummaryCard
|
|
|
- :value="fenToYuan(summary?.expensePrice || 0)"
|
|
|
+ :value="inspect.finished || 0"
|
|
|
icon="fa-solid:award"
|
|
|
icon-bg-color="text-yellow-500"
|
|
|
icon-color="bg-yellow-100"
|
|
|
- title="已填写巡检工单"
|
|
|
+ title="已填写巡检"
|
|
|
/>
|
|
|
</el-col>
|
|
|
<!-- 其他统计卡片... -->
|
|
@@ -101,7 +101,7 @@
|
|
|
</el-row>
|
|
|
<el-row :gutter="16" class="mb-4">
|
|
|
<!-- 备件更换情况部分保持不变 -->
|
|
|
- <el-col :span="8">
|
|
|
+ <el-col :span="7">
|
|
|
<el-card class="chart-card" shadow="never">
|
|
|
<template #header>
|
|
|
<div class="flex items-center justify-between">
|
|
@@ -136,11 +136,11 @@
|
|
|
<div ref="sparePartRef" class="h-[330px]"></div>
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
- <el-col :span="16">
|
|
|
+ <el-col :span="17">
|
|
|
<div class="flex flex-col justify-between">
|
|
|
<el-card class="chart-card" shadow="never">
|
|
|
<template #header>
|
|
|
- <div class="flex items-center justify-between">
|
|
|
+ <div class="flex items-center justify-between" >
|
|
|
<span class="text-base font-medium text-gray-600">保养情况</span>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -149,19 +149,19 @@
|
|
|
<div class="w-3/5 p-4 flex flex-col mt-5">
|
|
|
<div class="flex justify-between">
|
|
|
<div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:list" size="20" color="gray"/>
|
|
|
- <p>总工单数</p>
|
|
|
- <span>{{ totalMaintenanceOrders }}</span>
|
|
|
+ <Icon icon="fa-solid:list" size="30" color="blue"/>
|
|
|
+ <p style="font-size: 20px;margin-top: 5px">总工单数</p>
|
|
|
+ <span style="font-size: 20px">{{ by.finished+by.todo }}</span>
|
|
|
</div>
|
|
|
<div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:check-circle" size="20" color="green"/>
|
|
|
- <p>已执行工单数</p>
|
|
|
- <span>{{ completedMaintenanceOrders }}</span>
|
|
|
+ <Icon icon="fa-solid:check-circle" size="30" color="green"/>
|
|
|
+ <p style="font-size: 20px;margin-top: 5px">已执行工单数</p>
|
|
|
+ <span style="font-size: 20px">{{ by.finished }}</span>
|
|
|
</div>
|
|
|
<div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:hourglass-half" size="20" color="orange"/>
|
|
|
- <p>待执行工单数 </p>
|
|
|
- <span>{{ pendingMaintenanceOrders }}</span>
|
|
|
+ <Icon icon="fa-solid:hourglass-half" size="30" color="orange"/>
|
|
|
+ <p style="font-size: 20px;margin-top: 5px">待执行工单数 </p>
|
|
|
+ <span style="font-size: 20px">{{ by.todo }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -178,19 +178,19 @@
|
|
|
<div class="w-3/5 p-4 flex flex-col mt-5">
|
|
|
<div class="flex justify-between">
|
|
|
<div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:list" size="20" color="gray"/>
|
|
|
- <p>总工单数</p>
|
|
|
- <span>{{ totalMaintenanceOrders }}</span>
|
|
|
+ <Icon icon="fa-solid:list" size="30" color="blue"/>
|
|
|
+ <p style="font-size: 20px;margin-top: 5px">总工单数</p>
|
|
|
+ <span style="font-size: 20px">{{ inspect.todo+inspect.finished }}</span>
|
|
|
</div>
|
|
|
<div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:check-circle" size="20" color="green"/>
|
|
|
- <p>已执行工单数</p>
|
|
|
- <span>{{ completedMaintenanceOrders }}</span>
|
|
|
+ <Icon icon="fa-solid:check-circle" size="30" color="green"/>
|
|
|
+ <p style="font-size: 20px;margin-top: 5px">已执行工单数</p>
|
|
|
+ <span style="font-size: 20px">{{ inspect.finished }}</span>
|
|
|
</div>
|
|
|
<div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:hourglass-half" size="20" color="orange"/>
|
|
|
- <p>待执行工单数</p>
|
|
|
- <span>{{ pendingMaintenanceOrders }}</span>
|
|
|
+ <Icon icon="fa-solid:hourglass-half" size="30" color="orange"/>
|
|
|
+ <p style="font-size: 20px;margin-top: 5px">待执行工单数</p>
|
|
|
+ <span style="font-size: 20px">{{ inspect.todo }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -198,23 +198,6 @@
|
|
|
</el-card>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
- <el-col :span="24">
|
|
|
- <el-card class="chart-card mt-1" shadow="never">
|
|
|
- <template #header>
|
|
|
- <div class="flex items-center justify-between">
|
|
|
- <span class="text-base font-medium text-gray-600">维保日历</span>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <el-calendar v-model="currentDate">
|
|
|
- <template #dateCell="{ data }">
|
|
|
- <div class="calendar-cell">
|
|
|
- <span>{{ data.day.split('-').pop() }}</span>
|
|
|
- <div :ref="el => calendarPieRefs[data.day] = el" class="calendar-pie"></div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-calendar>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -233,15 +216,9 @@ import {
|
|
|
} from 'echarts/components'
|
|
|
import { LabelLayout, UniversalTransition } from 'echarts/features'
|
|
|
import { CanvasRenderer } from 'echarts/renderers'
|
|
|
-import { useElementSize } from '@vueuse/core'
|
|
|
-import {
|
|
|
- IotStatisticsDeviceMessageSummaryRespVO,
|
|
|
- IotStatisticsSummaryRespVO
|
|
|
-} from '@/api/iot/statistics'
|
|
|
-import { formatDate } from '@/utils/formatTime'
|
|
|
import { IotStatApi } from '@/api/pms/stat'
|
|
|
-import { ref, onMounted, computed, watch, nextTick } from 'vue';
|
|
|
-import { ElCalendar } from 'element-plus';
|
|
|
+import {ref, onMounted, computed, watch, nextTick, reactive} from 'vue';
|
|
|
+import {useUserStore} from "@/store/modules/user";
|
|
|
|
|
|
/** 会员统计 */
|
|
|
defineOptions({ name: 'IotRdStat' })
|
|
@@ -273,10 +250,29 @@ let maintenanceChartInstance = null
|
|
|
const inspectionChartRef = ref(null)
|
|
|
let inspectionChartInstance = null
|
|
|
const maintenanceChartRef1 = ref(null)
|
|
|
-let maintenanceChartInstance1 = null
|
|
|
|
|
|
const typeData = ref({})
|
|
|
const orderSevenData = ref({})
|
|
|
+const device = ref({
|
|
|
+ total: undefined,
|
|
|
+ today: undefined
|
|
|
+})
|
|
|
+const maintain = ref({
|
|
|
+ total: undefined,
|
|
|
+ today: undefined
|
|
|
+})
|
|
|
+const by = ref({
|
|
|
+ todo: undefined,
|
|
|
+ finished: undefined,
|
|
|
+})
|
|
|
+const fill = ref({
|
|
|
+ filledCount: undefined,
|
|
|
+ unfilledCount: undefined
|
|
|
+})
|
|
|
+const inspect = ref({
|
|
|
+ finished: 0,
|
|
|
+ todo: 0
|
|
|
+})
|
|
|
const sparePartData = ref({
|
|
|
xAxis: ['扳手', '水杯', '皮带', '螺丝'],
|
|
|
series: [
|
|
@@ -303,7 +299,6 @@ const pendingMaintenanceOrders = ref(20)
|
|
|
// 模拟巡检工单数据
|
|
|
const totalInspectionOrders = ref(80)
|
|
|
const completedInspectionOrders = ref(60)
|
|
|
-const pendingInspectionOrders = ref(20)
|
|
|
|
|
|
// 计算物料消耗数量及费用
|
|
|
const totalMaterialCount = computed(() => {
|
|
@@ -316,16 +311,6 @@ const totalMaterialCost = computed(() => {
|
|
|
return costSeries ? costSeries.data.reduce((sum, val) => sum + val, 0) : 0;
|
|
|
});
|
|
|
|
|
|
-// 维保日历相关
|
|
|
-const currentDate = ref(new Date())
|
|
|
-const calendarPieRefs = ref({})
|
|
|
-const maintenanceData = ref({
|
|
|
- // 示例数据,需要根据实际情况替换
|
|
|
- '2024-01-01': { maintenance: 5, inspection: 3 },
|
|
|
- '2024-01-02': { maintenance: 2, inspection: 4 },
|
|
|
- // ... 其他日期数据
|
|
|
-})
|
|
|
-
|
|
|
const getStats = () => {
|
|
|
IotStatApi.getDeviceStatusCount().then((res) => {
|
|
|
typeData.value = res
|
|
@@ -335,12 +320,32 @@ const getStats = () => {
|
|
|
orderSevenData.value = res
|
|
|
initQxChart()
|
|
|
})
|
|
|
+ IotStatApi.getDeviceCount().then((res) => {
|
|
|
+ device.value = res
|
|
|
+ })
|
|
|
+ IotStatApi.getMaintainCount().then((res) => {
|
|
|
+ maintain.value = res
|
|
|
+ })
|
|
|
+ IotStatApi.getMaintenanceStatus().then((res) => {
|
|
|
+ by.value = res
|
|
|
+ initMaintenanceChart()
|
|
|
+ })
|
|
|
+ const fillQueryParams = reactive({
|
|
|
+ startTime: Date.now() - 7 * 24 * 60 * 60 * 1000, // 设置默认开始时间为 7 天前
|
|
|
+ endTime: Date.now(), // 设置默认结束时间为当前时间
|
|
|
+ createTime: [],
|
|
|
+ deptId: null, // 选中的部门ID
|
|
|
+ status: null // 填写状态
|
|
|
+ })
|
|
|
+ IotStatApi.getInspectStatus(fillQueryParams).then((res) => {
|
|
|
+ inspect.value = res
|
|
|
+ })
|
|
|
+ fillQueryParams.deptId = useUserStore().getUser.deptId;
|
|
|
+ IotStatApi.getDeptStatistics(fillQueryParams).then((res) => {
|
|
|
+ fill.value = res.totalList[0] || [];
|
|
|
+ })
|
|
|
initSparePartChart()
|
|
|
- initMaintenanceChart()
|
|
|
initInspectionChart()
|
|
|
- nextTick(() => {
|
|
|
- initCalendarPieCharts()
|
|
|
- })
|
|
|
}
|
|
|
|
|
|
const initQxChart = () => {
|
|
@@ -483,15 +488,41 @@ const initSparePartChart = () => {
|
|
|
const initMaintenanceChart = () => {
|
|
|
if (!maintenanceChartRef.value) return
|
|
|
maintenanceChartInstance = echarts.init(maintenanceChartRef.value)
|
|
|
- const completionRate = (completedMaintenanceOrders.value / totalMaintenanceOrders.value) * 100
|
|
|
+ const completionRate = (by.value.finished / (by.value.finished+by.value.todo)) * 100
|
|
|
+ debugger
|
|
|
const option = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ // top: '5%',
|
|
|
+ // right: '10%',
|
|
|
+ // align: 'center',
|
|
|
+ orient: 'horizontal', // 水平排列图例项
|
|
|
+ bottom: '0%', // 放置在底部
|
|
|
+ icon: 'circle'
|
|
|
+ },
|
|
|
series: [
|
|
|
{
|
|
|
type: 'pie',
|
|
|
radius: ['40%', '70%'],
|
|
|
+ label: {
|
|
|
+ show: false,
|
|
|
+ position: 'outside'
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ fontSize: 15,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: true
|
|
|
+ },
|
|
|
data: [
|
|
|
- { value: completionRate, name: '完成率' },
|
|
|
- { value: 100 - completionRate, name: '未完成率' }
|
|
|
+ { name:'完成率',value: completionRate },
|
|
|
+ { name:'未完成率',value: 100 - completionRate }
|
|
|
]
|
|
|
}
|
|
|
]
|
|
@@ -557,33 +588,6 @@ const initDeviceStatusCharts = () => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-const initCalendarPieCharts = () => {
|
|
|
- Object.entries(calendarPieRefs.value).forEach(([date, el]) => {
|
|
|
- if (el) {
|
|
|
- const { maintenance = 0, inspection = 0 } = maintenanceData.value[date] || {}
|
|
|
- const total = maintenance + inspection
|
|
|
- const option = {
|
|
|
- series: [
|
|
|
- {
|
|
|
- type: 'pie',
|
|
|
- radius: ['30%', '60%'],
|
|
|
- data: [
|
|
|
- { value: maintenance, name: '保养' },
|
|
|
- { value: inspection, name: '巡检' }
|
|
|
- ]
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
- echarts.init(el).setOption(option)
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-watch(currentDate, () => {
|
|
|
- nextTick(() => {
|
|
|
- initCalendarPieCharts()
|
|
|
- })
|
|
|
-})
|
|
|
|
|
|
/** 初始化 **/
|
|
|
onMounted(async () => {
|