|
@@ -1,87 +1,164 @@
|
|
<template>
|
|
<template>
|
|
<!-- 第一行:统计卡片行 -->
|
|
<!-- 第一行:统计卡片行 -->
|
|
- <el-row :gutter="16" class="mb-4">
|
|
|
|
- <el-col :span="6">
|
|
|
|
- <el-card class="stat-card" shadow="never">
|
|
|
|
- <div class="flex flex-col">
|
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
|
- <span class="text-gray-500 text-base font-medium">设备数量</span>
|
|
|
|
- <Icon icon="ep:menu" class="text-[32px] text-blue-400" />
|
|
|
|
- </div>
|
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
|
- {{ device.total }}
|
|
|
|
- </span>
|
|
|
|
- <el-divider class="my-2" />
|
|
|
|
- <div class="flex justify-between items-center text-gray-400 text-sm">
|
|
|
|
- <span>今日新增</span>
|
|
|
|
- <span class="text-green-500">+{{ device.today }}</span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </el-card>
|
|
|
|
|
|
+ <div class="page-container">
|
|
|
|
+ <el-row :gutter="16" class="summary">
|
|
|
|
+ <!-- 原有的统计卡片部分保持不变 -->
|
|
|
|
+ <el-col :sm="3" :xs="12">
|
|
|
|
+ <SummaryCard
|
|
|
|
+ :value="device.total || 0"
|
|
|
|
+ icon="fa-solid:project-diagram"
|
|
|
|
+ icon-bg-color="text-blue-500"
|
|
|
|
+ icon-color="bg-blue-100"
|
|
|
|
+ title="设备数"
|
|
|
|
+ />
|
|
</el-col>
|
|
</el-col>
|
|
- <el-col :span="6">
|
|
|
|
- <el-card class="stat-card" shadow="never">
|
|
|
|
- <div class="flex flex-col">
|
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
|
- <span class="text-gray-500 text-base font-medium">维修工单数量</span>
|
|
|
|
- <Icon icon="ep:box" class="text-[32px] text-orange-400" />
|
|
|
|
- </div>
|
|
|
|
- <span class="text-3xl font-bold text-gray-700">{{ maintain.total }}</span>
|
|
|
|
- <el-divider class="my-2" />
|
|
|
|
- <div class="flex justify-between items-center text-gray-400 text-sm">
|
|
|
|
- <span>今日新增</span>
|
|
|
|
- <span class="text-green-500">+{{ maintain.today }}</span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </el-card>
|
|
|
|
|
|
+ <el-col :sm="3" :xs="12">
|
|
|
|
+ <SummaryCard
|
|
|
|
+ :value="maintain.total || 0"
|
|
|
|
+ icon="fa-solid:list"
|
|
|
|
+ icon-bg-color="text-pink-500"
|
|
|
|
+ icon-color="bg-blue-100"
|
|
|
|
+ title="维修工单"
|
|
|
|
+ />
|
|
</el-col>
|
|
</el-col>
|
|
- <el-col :span="6">
|
|
|
|
- <el-card class="stat-card" shadow="never">
|
|
|
|
- <div class="flex flex-col">
|
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
|
- <span class="text-gray-500 text-base font-medium">保养工单数量</span>
|
|
|
|
- <Icon icon="ep:cpu" class="text-[32px] text-purple-400" />
|
|
|
|
- </div>
|
|
|
|
- <span class="text-3xl font-bold text-gray-700">{{ work.total }}</span>
|
|
|
|
- <el-divider class="my-2" />
|
|
|
|
- <div class="flex justify-between items-center text-gray-400 text-sm">
|
|
|
|
- <span>今日新增</span>
|
|
|
|
- <span class="text-green-500">+{{ work.today }}</span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </el-card>
|
|
|
|
|
|
+ <el-col :sm="3" :xs="12">
|
|
|
|
+ <SummaryCard
|
|
|
|
+ :value="fill.unfilledCount || 0"
|
|
|
|
+ icon="fa-solid:times-circle"
|
|
|
|
+ icon-bg-color="text-purple-500"
|
|
|
|
+ icon-color="bg-purple-100"
|
|
|
|
+ title="运行未填写"
|
|
|
|
+ />
|
|
</el-col>
|
|
</el-col>
|
|
- <el-col :span="6">
|
|
|
|
- <el-card class="stat-card" shadow="never">
|
|
|
|
- <div class="flex flex-col">
|
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
|
- <span class="text-gray-500 text-base font-medium">巡检工单数量</span>
|
|
|
|
- <Icon icon="ep:camera" class="text-[32px] text-teal-400" />
|
|
|
|
- </div>
|
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
|
- {{ inspect.total }}
|
|
|
|
- </span>
|
|
|
|
- <el-divider class="my-2" />
|
|
|
|
- <div class="flex justify-between items-center text-gray-400 text-sm">
|
|
|
|
- <span>今日新增</span>
|
|
|
|
- <span class="text-green-500">+{{ inspect.today }}</span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </el-card>
|
|
|
|
|
|
+ <el-col :sm="3" :xs="12">
|
|
|
|
+ <SummaryCard
|
|
|
|
+ :value="fill.filledCount || 0"
|
|
|
|
+ icon="fa-solid:award"
|
|
|
|
+ icon-bg-color="text-purple-500"
|
|
|
|
+ icon-color="bg-purple-100"
|
|
|
|
+ title="运行已填写"
|
|
|
|
+ />
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :sm="3" :xs="12">
|
|
|
|
+ <SummaryCard
|
|
|
|
+ :value="by.todo || 0"
|
|
|
|
+ icon="fa-solid:times-circle"
|
|
|
|
+ icon-bg-color="text-green-500"
|
|
|
|
+ icon-color="bg-green-100"
|
|
|
|
+ title="未执行保养"
|
|
|
|
+ />
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :sm="3" :xs="12">
|
|
|
|
+ <SummaryCard
|
|
|
|
+ :value="by.finished || 0"
|
|
|
|
+ icon="fa-solid:award"
|
|
|
|
+ icon-bg-color="text-green-500"
|
|
|
|
+ icon-color="bg-green-100"
|
|
|
|
+ title="已执行保养"
|
|
|
|
+ />
|
|
</el-col>
|
|
</el-col>
|
|
|
|
+ <el-col :sm="3" :xs="12">
|
|
|
|
+ <SummaryCard
|
|
|
|
+ :value="inspectt.todo || 0"
|
|
|
|
+ icon="fa-solid:times-circle"
|
|
|
|
+ icon-bg-color="text-yellow-500"
|
|
|
|
+ icon-color="bg-yellow-100"
|
|
|
|
+ title="待填写巡检"
|
|
|
|
+ />
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :sm="3" :xs="12">
|
|
|
|
+ <SummaryCard
|
|
|
|
+ :value="inspectt.finished || 0"
|
|
|
|
+ icon="fa-solid:award"
|
|
|
|
+ icon-bg-color="text-yellow-500"
|
|
|
|
+ icon-color="bg-yellow-100"
|
|
|
|
+ title="已填写巡检"
|
|
|
|
+ />
|
|
|
|
+ </el-col>
|
|
|
|
+ <!-- 其他统计卡片... -->
|
|
</el-row>
|
|
</el-row>
|
|
|
|
+<!-- <el-row :gutter="16" class="mb-4">-->
|
|
|
|
+<!-- <el-col :span="6">-->
|
|
|
|
+<!-- <el-card class="stat-card" shadow="never">-->
|
|
|
|
+<!-- <div class="flex flex-col">-->
|
|
|
|
+<!-- <div class="flex justify-between items-center mb-1">-->
|
|
|
|
+<!-- <span class="text-gray-500 text-base font-medium">设备数量</span>-->
|
|
|
|
+<!-- <Icon icon="ep:menu" class="text-[32px] text-blue-400" />-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- <span class="text-3xl font-bold text-gray-700">-->
|
|
|
|
+<!-- {{ device.total }}-->
|
|
|
|
+<!-- </span>-->
|
|
|
|
+<!-- <el-divider class="my-2" />-->
|
|
|
|
+<!-- <div class="flex justify-between items-center text-gray-400 text-sm">-->
|
|
|
|
+<!-- <span>今日新增</span>-->
|
|
|
|
+<!-- <span class="text-green-500">+{{ device.today }}</span>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </el-card>-->
|
|
|
|
+<!-- </el-col>-->
|
|
|
|
+<!-- <el-col :span="6">-->
|
|
|
|
+<!-- <el-card class="stat-card" shadow="never">-->
|
|
|
|
+<!-- <div class="flex flex-col">-->
|
|
|
|
+<!-- <div class="flex justify-between items-center mb-1">-->
|
|
|
|
+<!-- <span class="text-gray-500 text-base font-medium">维修工单数量</span>-->
|
|
|
|
+<!-- <Icon icon="ep:box" class="text-[32px] text-orange-400" />-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- <span class="text-3xl font-bold text-gray-700">{{ maintain.total }}</span>-->
|
|
|
|
+<!-- <el-divider class="my-2" />-->
|
|
|
|
+<!-- <div class="flex justify-between items-center text-gray-400 text-sm">-->
|
|
|
|
+<!-- <span>今日新增</span>-->
|
|
|
|
+<!-- <span class="text-green-500">+{{ maintain.today }}</span>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </el-card>-->
|
|
|
|
+<!-- </el-col>-->
|
|
|
|
+<!-- <el-col :span="6">-->
|
|
|
|
+<!-- <el-card class="stat-card" shadow="never">-->
|
|
|
|
+<!-- <div class="flex flex-col">-->
|
|
|
|
+<!-- <div class="flex justify-between items-center mb-1">-->
|
|
|
|
+<!-- <span class="text-gray-500 text-base font-medium">保养工单数量</span>-->
|
|
|
|
+<!-- <Icon icon="ep:cpu" class="text-[32px] text-purple-400" />-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- <span class="text-3xl font-bold text-gray-700">{{ work.total }}</span>-->
|
|
|
|
+<!-- <el-divider class="my-2" />-->
|
|
|
|
+<!-- <div class="flex justify-between items-center text-gray-400 text-sm">-->
|
|
|
|
+<!-- <span>今日新增</span>-->
|
|
|
|
+<!-- <span class="text-green-500">+{{ work.today }}</span>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </el-card>-->
|
|
|
|
+<!-- </el-col>-->
|
|
|
|
+<!-- <el-col :span="6">-->
|
|
|
|
+<!-- <el-card class="stat-card" shadow="never">-->
|
|
|
|
+<!-- <div class="flex flex-col">-->
|
|
|
|
+<!-- <div class="flex justify-between items-center mb-1">-->
|
|
|
|
+<!-- <span class="text-gray-500 text-base font-medium">巡检工单数量</span>-->
|
|
|
|
+<!-- <Icon icon="ep:camera" class="text-[32px] text-teal-400" />-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- <span class="text-3xl font-bold text-gray-700">-->
|
|
|
|
+<!-- {{ inspect.total }}-->
|
|
|
|
+<!-- </span>-->
|
|
|
|
+<!-- <el-divider class="my-2" />-->
|
|
|
|
+<!-- <div class="flex justify-between items-center text-gray-400 text-sm">-->
|
|
|
|
+<!-- <span>今日新增</span>-->
|
|
|
|
+<!-- <span class="text-green-500">+{{ inspect.today }}</span>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </div>-->
|
|
|
|
+<!-- </el-card>-->
|
|
|
|
+<!-- </el-col>-->
|
|
|
|
+<!-- </el-row>-->
|
|
|
|
|
|
<!-- 第二行:图表行 -->
|
|
<!-- 第二行:图表行 -->
|
|
<el-row :gutter="16" class="mb-4">
|
|
<el-row :gutter="16" class="mb-4">
|
|
<el-col :span="6">
|
|
<el-col :span="6">
|
|
- <el-card class="stat-card" shadow="never">
|
|
|
|
|
|
+ <el-card class="chart-card" shadow="never">
|
|
<template #header>
|
|
<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">MTTR(平均解决时间)</span>
|
|
|
|
- <span class="text-base font-medium text-gray-600">库存预警物料数量</span>
|
|
|
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">MTTR(平均解决时间)</span>
|
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">库存预警物料数量</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
- <div class="flex flex-col h-[220px]">
|
|
|
|
|
|
+ <div class="flex flex-col h-[250px]">
|
|
<!-- <div class="flex justify-between items-center text-gray-400">-->
|
|
<!-- <div class="flex justify-between items-center text-gray-400">-->
|
|
<!-- <span>MTTR</span>-->
|
|
<!-- <span>MTTR</span>-->
|
|
|
|
|
|
@@ -104,20 +181,20 @@
|
|
<el-card class="chart-card" shadow="never">
|
|
<el-card class="chart-card" shadow="never">
|
|
<template #header>
|
|
<template #header>
|
|
<div class="flex items-center">
|
|
<div class="flex items-center">
|
|
- <span class="text-base font-medium text-gray-600">设备状态统计</span>
|
|
|
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">设备状态统计</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
- <div ref="statusChartRef" class="h-[220px]"></div>
|
|
|
|
|
|
+ <div ref="statusChartRef" class="h-[250px]"></div>
|
|
</el-card>
|
|
</el-card>
|
|
</el-col>
|
|
</el-col>
|
|
<el-col :span="9">
|
|
<el-col :span="9">
|
|
<el-card class="chart-card" shadow="never">
|
|
<el-card class="chart-card" shadow="never">
|
|
<template #header>
|
|
<template #header>
|
|
<div class="flex items-center">
|
|
<div class="flex items-center">
|
|
- <span class="text-base font-medium text-gray-600">设备类别TOP5数量</span>
|
|
|
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">设备类别TOP5数量</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
- <div ref="topContainer" class="h-[220px]"></div>
|
|
|
|
|
|
+ <div ref="topContainer" class="h-[250px]"></div>
|
|
</el-card>
|
|
</el-card>
|
|
</el-col>
|
|
</el-col>
|
|
</el-row>
|
|
</el-row>
|
|
@@ -128,25 +205,24 @@
|
|
<el-card class="chart-card" shadow="never">
|
|
<el-card class="chart-card" shadow="never">
|
|
<template #header>
|
|
<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>
|
|
|
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">近一周用户活跃度</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
- <div ref="activeDom" class="h-[300px]"></div>
|
|
|
|
|
|
+ <div ref="activeDom" class="h-[320px]"></div>
|
|
</el-card>
|
|
</el-card>
|
|
</el-col>
|
|
</el-col>
|
|
<el-col :span="18">
|
|
<el-col :span="18">
|
|
<el-card class="chart-card" shadow="never">
|
|
<el-card class="chart-card" shadow="never">
|
|
<template #header>
|
|
<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>
|
|
|
|
|
|
+ <span class="text-base font-medium" style="color: #b6c8da">工单数量情况</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
- <div ref="qxRef" class="h-[300px]"></div>
|
|
|
|
|
|
+ <div ref="qxRef" class="h-[320px]"></div>
|
|
</el-card>
|
|
</el-card>
|
|
</el-col>
|
|
</el-col>
|
|
</el-row>
|
|
</el-row>
|
|
-
|
|
|
|
- <!-- TODO 第四行:地图 -->
|
|
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts" name="Index">
|
|
<script setup lang="ts" name="Index">
|
|
@@ -168,6 +244,8 @@ import {
|
|
} from '@/api/iot/statistics'
|
|
} from '@/api/iot/statistics'
|
|
import { formatDate } from '@/utils/formatTime'
|
|
import { formatDate } from '@/utils/formatTime'
|
|
import { IotStatApi } from '@/api/pms/stat'
|
|
import { IotStatApi } from '@/api/pms/stat'
|
|
|
|
+import SummaryCard from "@/components/SummaryCard/index.vue";
|
|
|
|
+import {reactive, ref} from "vue";
|
|
|
|
|
|
// TODO @super:参考下 /Users/yunai/Java/yudao-ui-admin-vue3/src/views/mall/home/index.vue,拆一拆组件
|
|
// TODO @super:参考下 /Users/yunai/Java/yudao-ui-admin-vue3/src/views/mall/home/index.vue,拆一拆组件
|
|
|
|
|
|
@@ -220,7 +298,19 @@ const statsData = ref<IotStatisticsSummaryRespVO>({
|
|
deviceInactiveCount: 0,
|
|
deviceInactiveCount: 0,
|
|
productCategoryDeviceCounts: {}
|
|
productCategoryDeviceCounts: {}
|
|
})
|
|
})
|
|
-
|
|
|
|
|
|
+const orderSevenData = ref({})
|
|
|
|
+const by = ref({
|
|
|
|
+ todo: undefined,
|
|
|
|
+ finished: undefined
|
|
|
|
+})
|
|
|
|
+const fill = ref({
|
|
|
|
+ filledCount: undefined,
|
|
|
|
+ unfilledCount: undefined
|
|
|
|
+})
|
|
|
|
+const inspectt = ref({
|
|
|
|
+ finished: 0,
|
|
|
|
+ todo: 0
|
|
|
|
+})
|
|
const device = ref({
|
|
const device = ref({
|
|
total: undefined,
|
|
total: undefined,
|
|
today: undefined
|
|
today: undefined
|
|
@@ -283,18 +373,28 @@ const getStats = async () => {
|
|
IotStatApi.getSafeCount().then((res) => {
|
|
IotStatApi.getSafeCount().then((res) => {
|
|
safe.value = res
|
|
safe.value = res
|
|
})
|
|
})
|
|
- // IotStatApi.getInspectTodayStatus().then((res) => {
|
|
|
|
- // todayStatus.value = res
|
|
|
|
- // debugger
|
|
|
|
- // initCharts()
|
|
|
|
- // })
|
|
|
|
- // statsData.value = await ProductCategoryApi.getIotStatisticsSummary()
|
|
|
|
-
|
|
|
|
- //
|
|
|
|
- // // 获取消息统计数据
|
|
|
|
- // messageStats.value = await ProductCategoryApi.getIotStatisticsDeviceMessageSummary(queryParams)
|
|
|
|
|
|
+ IotStatApi.getOrderSeven('156').then((res) => {
|
|
|
|
+ orderSevenData.value = res
|
|
|
|
+ initQxChart()
|
|
|
|
+ })
|
|
|
|
|
|
- // 初始化图表
|
|
|
|
|
|
+ IotStatApi.getMaintenanceStatus().then((res) => {
|
|
|
|
+ by.value = res
|
|
|
|
+ })
|
|
|
|
+ const fillQueryParams = reactive({
|
|
|
|
+ startTime: Date.now() - 7 * 24 * 60 * 60 * 1000, // 设置默认开始时间为 7 天前
|
|
|
|
+ endTime: Date.now(), // 设置默认结束时间为当前时间
|
|
|
|
+ createTime: [],
|
|
|
|
+ deptId: null, // 选中的部门ID
|
|
|
|
+ status: null // 填写状态
|
|
|
|
+ })
|
|
|
|
+ IotStatApi.getInspectStatuss(fillQueryParams, '156').then((res) => {
|
|
|
|
+ inspectt.value = res
|
|
|
|
+ })
|
|
|
|
+ fillQueryParams.deptId = '156'
|
|
|
|
+ IotStatApi.getDeptStatistics(fillQueryParams).then((res) => {
|
|
|
|
+ fill.value = res.totalList[0] || []
|
|
|
|
+ })
|
|
}
|
|
}
|
|
|
|
|
|
/** 初始化图表 */
|
|
/** 初始化图表 */
|
|
@@ -309,7 +409,10 @@ const initCharts = () => {
|
|
right: '10%',
|
|
right: '10%',
|
|
align: 'left',
|
|
align: 'left',
|
|
orient: 'vertical',
|
|
orient: 'vertical',
|
|
- icon: 'circle'
|
|
|
|
|
|
+ icon: 'circle',
|
|
|
|
+ textStyle: {
|
|
|
|
+ color: 'white'
|
|
|
|
+ }
|
|
},
|
|
},
|
|
series: [
|
|
series: [
|
|
{
|
|
{
|
|
@@ -320,7 +423,8 @@ const initCharts = () => {
|
|
center: ['30%', '50%'],
|
|
center: ['30%', '50%'],
|
|
label: {
|
|
label: {
|
|
show: false,
|
|
show: false,
|
|
- position: 'outside'
|
|
|
|
|
|
+ position: 'outside',
|
|
|
|
+ color: 'white'
|
|
},
|
|
},
|
|
emphasis: {
|
|
emphasis: {
|
|
label: {
|
|
label: {
|
|
@@ -673,17 +777,37 @@ const getTopOption = () => {
|
|
xAxis: {
|
|
xAxis: {
|
|
type: 'value',
|
|
type: 'value',
|
|
axisLabel: {
|
|
axisLabel: {
|
|
|
|
+ color: 'white',
|
|
formatter: (value) => {
|
|
formatter: (value) => {
|
|
if (value >= 10000) return `${(value / 10000).toFixed(1)}万`
|
|
if (value >= 10000) return `${(value / 10000).toFixed(1)}万`
|
|
return value.toLocaleString()
|
|
return value.toLocaleString()
|
|
}
|
|
}
|
|
|
|
+ },
|
|
|
|
+ axisLine: {
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: '#B6C8DA' // X轴线白色半透明
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ splitLine: {
|
|
|
|
+ show: true, // 显示水平网格线(默认显示)
|
|
|
|
+ lineStyle: {
|
|
|
|
+ // 水平网格线颜色(可设置为纯色或带透明度的颜色)
|
|
|
|
+ color: '#B6C8DA', // 浅灰色半透明
|
|
|
|
+ // 可选:设置线条类型(实线/虚线/点线)
|
|
|
|
+ type: 'dashed'
|
|
|
|
+ }
|
|
}
|
|
}
|
|
},
|
|
},
|
|
yAxis: {
|
|
yAxis: {
|
|
type: 'category',
|
|
type: 'category',
|
|
data: data.map((item) => item.category),
|
|
data: data.map((item) => item.category),
|
|
axisTick: { show: false },
|
|
axisTick: { show: false },
|
|
- axisLabel: {}
|
|
|
|
|
|
+ axisLabel: { color: '#B6C8DA' },
|
|
|
|
+ axisLine: {
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: '#B6C8DA' // X轴线白色半透明
|
|
|
|
+ }
|
|
|
|
+ }
|
|
},
|
|
},
|
|
series: [
|
|
series: [
|
|
{
|
|
{
|
|
@@ -701,7 +825,7 @@ const getTopOption = () => {
|
|
show: true,
|
|
show: true,
|
|
position: 'right',
|
|
position: 'right',
|
|
formatter: '{@value}',
|
|
formatter: '{@value}',
|
|
- color: '#333',
|
|
|
|
|
|
+ color: 'white',
|
|
fontWeight: 'bold'
|
|
fontWeight: 'bold'
|
|
},
|
|
},
|
|
emphasis: {
|
|
emphasis: {
|
|
@@ -717,7 +841,7 @@ const getTopOption = () => {
|
|
|
|
|
|
// 初始化图表
|
|
// 初始化图表
|
|
const initTopChart = async () => {
|
|
const initTopChart = async () => {
|
|
- await IotStatApi.getDeviceTypeCount().then((res) => {
|
|
|
|
|
|
+ await IotStatApi.getDeviceTypeCount('yf').then((res) => {
|
|
backendData.value = res
|
|
backendData.value = res
|
|
})
|
|
})
|
|
if (!topContainer.value) return
|
|
if (!topContainer.value) return
|
|
@@ -773,7 +897,10 @@ const initActiveChart = async () => {
|
|
},
|
|
},
|
|
legend: {
|
|
legend: {
|
|
data: ['总人数', '活跃人数'],
|
|
data: ['总人数', '活跃人数'],
|
|
- top: 30
|
|
|
|
|
|
+ top: 30,
|
|
|
|
+ textStyle: {
|
|
|
|
+ color: '#B6C8DA',
|
|
|
|
+ }
|
|
},
|
|
},
|
|
grid: {
|
|
grid: {
|
|
left: '3%',
|
|
left: '3%',
|
|
@@ -785,16 +912,35 @@ const initActiveChart = async () => {
|
|
type: 'category',
|
|
type: 'category',
|
|
data: activeData.value.map((item) => item.department),
|
|
data: activeData.value.map((item) => item.department),
|
|
axisLabel: {
|
|
axisLabel: {
|
|
|
|
+ color: '#B6C8DA',
|
|
interval: 0,
|
|
interval: 0,
|
|
rotate: 0 //:ml-citation{ref="5" data="citationList"}
|
|
rotate: 0 //:ml-citation{ref="5" data="citationList"}
|
|
|
|
+ },
|
|
|
|
+ axisLine: {
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: '#B6C8DA'
|
|
|
|
+ }
|
|
}
|
|
}
|
|
},
|
|
},
|
|
yAxis: {
|
|
yAxis: {
|
|
type: 'value',
|
|
type: 'value',
|
|
name: '人数',
|
|
name: '人数',
|
|
|
|
+ axisLabel: {
|
|
|
|
+ color: '#B6C8DA',
|
|
|
|
+ },
|
|
splitLine: {
|
|
splitLine: {
|
|
- show: true,
|
|
|
|
- lineStyle: { type: 'dashed' }
|
|
|
|
|
|
+ show: true, // 显示水平网格线(默认显示)
|
|
|
|
+ lineStyle: {
|
|
|
|
+ // 水平网格线颜色(可设置为纯色或带透明度的颜色)
|
|
|
|
+ color: '#457794', // 浅灰色半透明
|
|
|
|
+ // 可选:设置线条类型(实线/虚线/点线)
|
|
|
|
+ type: 'dashed'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ axisLine: {
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: '#B6C8DA'
|
|
|
|
+ }
|
|
}
|
|
}
|
|
},
|
|
},
|
|
series: [
|
|
series: [
|
|
@@ -844,39 +990,9 @@ const generateMonths = () => {
|
|
return months.reverse()
|
|
return months.reverse()
|
|
}
|
|
}
|
|
|
|
|
|
-// 模拟工单数据
|
|
|
|
-const mockData = () => {
|
|
|
|
- const baseDate = generateMonths()
|
|
|
|
- return {
|
|
|
|
- xAxis: baseDate,
|
|
|
|
- series: [
|
|
|
|
- {
|
|
|
|
- // 维修工单
|
|
|
|
- name: '维修工单',
|
|
|
|
- data: baseDate.map((_, i) => Math.floor(Math.random() * 181) + 20)
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- // 保养工单
|
|
|
|
- name: '保养工单',
|
|
|
|
- data: baseDate.map((_, i) => Math.floor(Math.random() * 181) + 20)
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- // 巡检工单
|
|
|
|
- name: '巡检工单',
|
|
|
|
- data: baseDate.map((_, i) => Math.floor(Math.random() * 181) + 20)
|
|
|
|
- }
|
|
|
|
- ]
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
const initQxChart = () => {
|
|
const initQxChart = () => {
|
|
if (!qxRef.value) return
|
|
if (!qxRef.value) return
|
|
-
|
|
|
|
- const chartQxData = mockData()
|
|
|
|
- debugger
|
|
|
|
-
|
|
|
|
qxInstance = echarts.init(qxRef.value)
|
|
qxInstance = echarts.init(qxRef.value)
|
|
-
|
|
|
|
const option = {
|
|
const option = {
|
|
tooltip: {
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
trigger: 'axis',
|
|
@@ -888,8 +1004,11 @@ const initQxChart = () => {
|
|
}
|
|
}
|
|
},
|
|
},
|
|
legend: {
|
|
legend: {
|
|
- data: chartQxData.series.map((item) => item.name),
|
|
|
|
- top: 30
|
|
|
|
|
|
+ data: orderSevenData.value.series.map((item) => item.name),
|
|
|
|
+ top: 30,
|
|
|
|
+ textStyle: {
|
|
|
|
+ color: '#B6C8DA'
|
|
|
|
+ }
|
|
},
|
|
},
|
|
grid: {
|
|
grid: {
|
|
left: '3%',
|
|
left: '3%',
|
|
@@ -900,34 +1019,78 @@ const initQxChart = () => {
|
|
xAxis: {
|
|
xAxis: {
|
|
type: 'category',
|
|
type: 'category',
|
|
boundaryGap: false,
|
|
boundaryGap: false,
|
|
- data: chartQxData.xAxis,
|
|
|
|
|
|
+ data: orderSevenData.value.xAxis,
|
|
axisLabel: {
|
|
axisLabel: {
|
|
|
|
+ color: '#B6C8DA',
|
|
formatter: (value) => value.split('-').join('/') // 显示为 2023/01
|
|
formatter: (value) => value.split('-').join('/') // 显示为 2023/01
|
|
|
|
+ },
|
|
|
|
+ axisLine: {
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: '#B6C8DA'
|
|
|
|
+ }
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- yAxis: {
|
|
|
|
- type: 'value',
|
|
|
|
- axisLabel: {
|
|
|
|
- formatter: '{value}'
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- series: chartQxData.series.map((item, index) => ({
|
|
|
|
- name: item.name,
|
|
|
|
- type: 'line',
|
|
|
|
- smooth: true,
|
|
|
|
- symbol: 'circle',
|
|
|
|
- symbolSize: 8,
|
|
|
|
- itemStyle: {
|
|
|
|
- color: ['#5470c6', '#91cc75', '#fac858'][index] // 蓝、绿、黄
|
|
|
|
- },
|
|
|
|
- areaStyle: {
|
|
|
|
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
|
- { offset: 0, color: 'rgba(84,112,198,0.4)' },
|
|
|
|
- { offset: 1, color: 'rgba(84,112,198,0.1)' }
|
|
|
|
- ])
|
|
|
|
|
|
+ yAxis: [
|
|
|
|
+ {
|
|
|
|
+ type: 'value',
|
|
|
|
+ axisLabel: {
|
|
|
|
+ color: '#B6C8DA',
|
|
|
|
+ formatter: '{value}'
|
|
|
|
+ },
|
|
|
|
+ splitLine: {
|
|
|
|
+ show: true, // 显示水平网格线(默认显示)
|
|
|
|
+ lineStyle: {
|
|
|
|
+ // 水平网格线颜色(可设置为纯色或带透明度的颜色)
|
|
|
|
+ color: '#457794', // 浅灰色半透明
|
|
|
|
+ // 可选:设置线条类型(实线/虚线/点线)
|
|
|
|
+ type: 'dashed'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ axisLine: {
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: '#B6C8DA'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ position: 'left' // 左侧 Y 轴
|
|
},
|
|
},
|
|
- data: item.data
|
|
|
|
- }))
|
|
|
|
|
|
+ {
|
|
|
|
+ type: 'value',
|
|
|
|
+ axisLabel: {
|
|
|
|
+ formatter: '{value}'
|
|
|
|
+ },
|
|
|
|
+ axisLine: {
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: '#B6C8DA'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ position: 'right', // 右侧 Y 轴
|
|
|
|
+ splitLine: {
|
|
|
|
+ show: false // 隐藏右侧 Y 轴的分割线
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ ],
|
|
|
|
+ series: orderSevenData.value.series.map((item, index) => {
|
|
|
|
+ // 假设前两条曲线使用左侧 Y 轴,后两条曲线使用右侧 Y 轴
|
|
|
|
+ const yAxisIndex = index < 2 ? 0 : 1
|
|
|
|
+ return {
|
|
|
|
+ name: item.name,
|
|
|
|
+ type: 'line',
|
|
|
|
+ smooth: true,
|
|
|
|
+ symbol: 'circle',
|
|
|
|
+ symbolSize: 8,
|
|
|
|
+ itemStyle: {
|
|
|
|
+ color: ['#5470c6', '#f1d209', '#e14f0f', '#91cc75'][index]
|
|
|
|
+ },
|
|
|
|
+ areaStyle: {
|
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
|
+ { offset: 0, color: 'rgba(84,112,198,0.4)' },
|
|
|
|
+ { offset: 1, color: 'rgba(84,112,198,0.1)' }
|
|
|
|
+ ])
|
|
|
|
+ },
|
|
|
|
+ data: item.data,
|
|
|
|
+ yAxisIndex: yAxisIndex // 指定使用的 Y 轴
|
|
|
|
+ }
|
|
|
|
+ })
|
|
}
|
|
}
|
|
|
|
|
|
qxInstance.setOption(option)
|
|
qxInstance.setOption(option)
|
|
@@ -935,14 +1098,13 @@ const initQxChart = () => {
|
|
|
|
|
|
// 响应式调整
|
|
// 响应式调整
|
|
const resizeQxChart = () => qxInstance?.resize()
|
|
const resizeQxChart = () => qxInstance?.resize()
|
|
-
|
|
|
|
/** 初始化 */
|
|
/** 初始化 */
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
getStats()
|
|
getStats()
|
|
- initChart()
|
|
|
|
|
|
+ // initChart()
|
|
initTopChart()
|
|
initTopChart()
|
|
initActiveChart()
|
|
initActiveChart()
|
|
- initQxChart()
|
|
|
|
|
|
+ // initQxChart()
|
|
window.addEventListener('resize', resizeQxChart)
|
|
window.addEventListener('resize', resizeQxChart)
|
|
// fetchTop()
|
|
// fetchTop()
|
|
window.addEventListener('resize', () => topInstance?.resize())
|
|
window.addEventListener('resize', () => topInstance?.resize())
|
|
@@ -957,4 +1119,74 @@ onBeforeUnmount(() => {
|
|
})
|
|
})
|
|
</script>
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped></style>
|
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.page-container {
|
|
|
|
+ background-color: #3a6fa3;
|
|
|
|
+ min-height: 90vh;
|
|
|
|
+ padding: 20px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.summary {
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+::v-deep .chart-card {
|
|
|
|
+ background-color: rgba(0, 0, 0, 0.3);
|
|
|
|
+ border-radius: 8px;
|
|
|
|
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
+ border: none;
|
|
|
|
+
|
|
|
|
+ &:hover {
|
|
|
|
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.safety-days-card {
|
|
|
|
+ .safety-days-content {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ height: 150px;
|
|
|
|
+ position: relative;
|
|
|
|
+
|
|
|
|
+ .days-number {
|
|
|
|
+ font-size: 58px;
|
|
|
|
+ font-weight: bold;
|
|
|
|
+ color: darkorange;
|
|
|
|
+ line-height: 1;
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .days-number:hover {
|
|
|
|
+ transform: scale(1.05);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .days-label {
|
|
|
|
+ font-size: 20px;
|
|
|
|
+ color: white;
|
|
|
|
+ margin-top: 8px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .safety-desc {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ color: #999;
|
|
|
|
+ position: absolute;
|
|
|
|
+ bottom: 10px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ width: 90%;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+@media (max-width: 768px) {
|
|
|
|
+ .page-container {
|
|
|
|
+ padding: 10px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+::v-deep .el-card__header {
|
|
|
|
+ border-bottom: none !important;
|
|
|
|
+ padding-bottom: 0;
|
|
|
|
+}
|
|
|
|
+</style>
|