|
|
@@ -1,213 +1,161 @@
|
|
|
<template>
|
|
|
- <!-- 第一行:统计卡片行 -->
|
|
|
- <el-row :gutter="16" class="mb-4">
|
|
|
+ <!-- 第一行:统计卡片行 -->
|
|
|
+ <el-row :gutter="16" class="mb-6">
|
|
|
<el-col :span="6">
|
|
|
- <el-card class="stat-card" shadow="never">
|
|
|
- <div class="flex flex-col">
|
|
|
- <div class="flex justify-between items-center text-gray-400">
|
|
|
- <span>MTTR</span>
|
|
|
- <Icon icon="ep:menu" class="text-[32px] text-blue-400" />
|
|
|
+ <el-card class="stat-card stat-card-gradient-1" shadow="hover">
|
|
|
+ <div class="stat-content">
|
|
|
+ <div class="stat-header">
|
|
|
+ <div class="stat-icon-wrapper">
|
|
|
+ <Icon icon="ep:data-line" class="stat-icon" />
|
|
|
+ </div>
|
|
|
+ <div class="stat-title">MTTR</div>
|
|
|
</div>
|
|
|
- <el-divider />
|
|
|
- <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" />-->
|
|
|
+ <el-divider class="stat-divider" />
|
|
|
+ <div class="stat-body">
|
|
|
+ <div class="stat-label">平均解决时间</div>
|
|
|
+ <div class="stat-value">{{ statsData.productCategoryCount }}</div>
|
|
|
</div>
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
- {{ statsData.productCategoryCount }}
|
|
|
- </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">+{{ statsData.productCategoryTodayCount }}</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 text-gray-400">-->
|
|
|
-<!-- <span>昨日工单数量</span>-->
|
|
|
-<!-- </div>-->
|
|
|
-<!-- <el-divider />-->
|
|
|
-<!-- <div class="flex justify-between items-center mb-1">-->
|
|
|
-<!-- <span class="text-gray-500 text-base font-medium" style="font-size: 14px"-->
|
|
|
-<!-- >故障上报</span-->
|
|
|
-<!-- >-->
|
|
|
-<!-- <span class="text-gray-500 text-base font-medium" style="font-size: 14px"-->
|
|
|
-<!-- >维修工单</span-->
|
|
|
-<!-- >-->
|
|
|
-<!-- </div>-->
|
|
|
-<!-- <div class="flex justify-between items-center mb-1">-->
|
|
|
-<!-- <span class="text-3xl font-bold text-gray-700">-->
|
|
|
-<!-- {{ day.failureDay }}-->
|
|
|
-<!-- </span>-->
|
|
|
-<!-- <span class="text-3xl font-bold text-gray-700">-->
|
|
|
-<!-- {{ day.maintainDay }}-->
|
|
|
-<!-- </span>-->
|
|
|
-<!-- </div>-->
|
|
|
-<!-- <!– <el-divider class="my-2" />–>-->
|
|
|
-<!-- <!– <div class="flex justify-between items-center text-gray-400 text-sm">–>-->
|
|
|
-<!-- <!– <span>今日新增</span>–>-->
|
|
|
-<!-- <!– <span class="text-green-500">+{{ statsData.productCategoryTodayCount }}</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 text-gray-400">
|
|
|
- <span>近一周工单数量</span>
|
|
|
- <Icon icon="ep:menu" class="text-[32px] text-blue-400" />
|
|
|
- </div>
|
|
|
- <el-divider />
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
- <span class="text-gray-500 text-base font-medium" style="font-size: 14px"
|
|
|
- >故障上报</span
|
|
|
- >
|
|
|
- <span class="text-gray-500 text-base font-medium" style="font-size: 14px"
|
|
|
- >维修工单</span
|
|
|
- >
|
|
|
+ <el-card class="stat-card stat-card-gradient-2" shadow="hover">
|
|
|
+ <div class="stat-content">
|
|
|
+ <div class="stat-header">
|
|
|
+ <div class="stat-icon-wrapper">
|
|
|
+ <Icon icon="ep:trend-charts" class="stat-icon" />
|
|
|
+ </div>
|
|
|
+ <div class="stat-title">近一周工单数量</div>
|
|
|
</div>
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
- {{ week.failureWeek }}
|
|
|
- </span>
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
- {{ week.maintainWeek }}
|
|
|
- </span>
|
|
|
+ <el-divider class="stat-divider" />
|
|
|
+ <div class="stat-body">
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-sub-label">故障上报</div>
|
|
|
+ <div class="stat-sub-value text-blue-500">{{ week.failureWeek }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-sub-label">维修工单</div>
|
|
|
+ <div class="stat-sub-value text-white">{{ week.maintainWeek }}</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <!-- <el-divider class="my-2" />-->
|
|
|
- <!-- <div class="flex justify-between items-center text-gray-400 text-sm">-->
|
|
|
- <!-- <span>今日新增</span>-->
|
|
|
- <!-- <span class="text-green-500">+{{ statsData.productCategoryTodayCount }}</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 text-gray-400">
|
|
|
- <span>近一月工单数量</span>
|
|
|
- <Icon icon="ep:menu" class="text-[32px] text-blue-400" />
|
|
|
- </div>
|
|
|
- <el-divider />
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
- <span class="text-gray-500 text-base font-medium" style="font-size: 14px"
|
|
|
- >故障上报</span
|
|
|
- >
|
|
|
- <span class="text-gray-500 text-base font-medium" style="font-size: 14px"
|
|
|
- >维修工单</span
|
|
|
- >
|
|
|
+ <el-card class="stat-card stat-card-gradient-3" shadow="hover">
|
|
|
+ <div class="stat-content">
|
|
|
+ <div class="stat-header">
|
|
|
+ <div class="stat-icon-wrapper">
|
|
|
+ <Icon icon="ep:calendar" class="stat-icon" />
|
|
|
+ </div>
|
|
|
+ <div class="stat-title">近一月工单数量</div>
|
|
|
</div>
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
- {{ month.failureMonth }}
|
|
|
- </span>
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
- {{ month.maintainMonth }}
|
|
|
- </span>
|
|
|
+ <el-divider class="stat-divider" />
|
|
|
+ <div class="stat-body">
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-sub-label">故障上报</div>
|
|
|
+ <div class="stat-sub-value text-blue-500">{{ month.failureMonth }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-sub-label">维修工单</div>
|
|
|
+ <div class="stat-sub-value text-white">{{ month.maintainMonth }}</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <!-- <el-divider class="my-2" />-->
|
|
|
- <!-- <div class="flex justify-between items-center text-gray-400 text-sm">-->
|
|
|
- <!-- <span>今日新增</span>-->
|
|
|
- <!-- <span class="text-green-500">+{{ statsData.productCategoryTodayCount }}</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 text-gray-400">
|
|
|
- <span>工单总数量</span>
|
|
|
- <Icon icon="ep:menu" class="text-[32px] text-blue-400" />
|
|
|
- </div>
|
|
|
- <el-divider />
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
- <span class="text-gray-500 text-base font-medium" style="font-size: 14px"
|
|
|
- >故障上报</span
|
|
|
- >
|
|
|
- <span class="text-gray-500 text-base font-medium" style="font-size: 14px"
|
|
|
- >维修工单</span
|
|
|
- >
|
|
|
+ <el-card class="stat-card stat-card-gradient-4" shadow="hover">
|
|
|
+ <div class="stat-content">
|
|
|
+ <div class="stat-header">
|
|
|
+ <div class="stat-icon-wrapper">
|
|
|
+ <Icon icon="ep:pie-chart" class="stat-icon" />
|
|
|
+ </div>
|
|
|
+ <div class="stat-title">工单总数量</div>
|
|
|
</div>
|
|
|
- <div class="flex justify-between items-center mb-1">
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
- {{ total.failureTotal }}
|
|
|
- </span>
|
|
|
- <span class="text-3xl font-bold text-gray-700">
|
|
|
- {{ total.maintainTotal }}
|
|
|
- </span>
|
|
|
+ <el-divider class="stat-divider" />
|
|
|
+ <div class="stat-body">
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-sub-label">故障上报</div>
|
|
|
+ <div class="stat-sub-value text-blue-500">{{ total.failureTotal }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-sub-label">维修工单</div>
|
|
|
+ <div class="stat-sub-value text-white">{{ total.maintainTotal }}</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <!-- <el-divider class="my-2" />-->
|
|
|
- <!-- <div class="flex justify-between items-center text-gray-400 text-sm">-->
|
|
|
- <!-- <span>今日新增</span>-->
|
|
|
- <!-- <span class="text-green-500">+{{ statsData.productCategoryTodayCount }}</span>-->
|
|
|
- <!-- </div>-->
|
|
|
</div>
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
|
|
|
- <!-- 第二行:图表行 -->
|
|
|
- <el-row :gutter="16" class="mb-4">
|
|
|
+ <!-- 第二行:图表行 -->
|
|
|
+ <el-row :gutter="16" class="mb-6">
|
|
|
<el-col :span="12">
|
|
|
- <el-card class="chart-card" shadow="never">
|
|
|
+ <el-card class="chart-card-enhanced" shadow="hover" style="border: none">
|
|
|
<template #header>
|
|
|
- <div class="flex items-center">
|
|
|
- <span class="text-base font-medium text-gray-600">故障上报状态统计</span>
|
|
|
+ <div class="chart-header">
|
|
|
+ <div class="chart-title-wrapper">
|
|
|
+ <div class="chart-title-dot"></div>
|
|
|
+ <span class="chart-title">故障上报状态统计</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
- <el-row class="h-[220px]">
|
|
|
- <el-col :span="6" class="flex flex-col items-center">
|
|
|
- <div ref="reportingChartRef" class="h-[160px] w-full"></div>
|
|
|
- <div class="text-center mt-2">
|
|
|
- <span class="text-sm text-gray-600">上报中</span>
|
|
|
+ <el-row class="chart-grid">
|
|
|
+ <el-col :span="6" class="chart-item">
|
|
|
+ <div ref="reportingChartRef" class="gauge-chart"></div>
|
|
|
+ <div class="chart-label">
|
|
|
+ <span class="label-dot label-dot-blue"></span>
|
|
|
+ <span class="label-text">上报中</span>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
- <el-col :span="6" class="flex flex-col items-center">
|
|
|
- <div ref="dealFinishedChartRef" class="h-[160px] w-full"></div>
|
|
|
- <div class="text-center mt-2">
|
|
|
- <span class="text-sm text-gray-600">处理完成</span>
|
|
|
+ <el-col :span="6" class="chart-item">
|
|
|
+ <div ref="dealFinishedChartRef" class="gauge-chart"></div>
|
|
|
+ <div class="chart-label">
|
|
|
+ <span class="label-dot label-dot-orange"></span>
|
|
|
+ <span class="label-text">处理完成</span>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
- <el-col :span="6" class="flex flex-col items-center">
|
|
|
- <div ref="transOrderChartRef" class="h-[160px] w-full"></div>
|
|
|
- <div class="text-center mt-2">
|
|
|
- <span class="text-sm text-gray-600">转工单</span>
|
|
|
+ <el-col :span="6" class="chart-item">
|
|
|
+ <div ref="transOrderChartRef" class="gauge-chart"></div>
|
|
|
+ <div class="chart-label">
|
|
|
+ <span class="label-dot label-dot-purple"></span>
|
|
|
+ <span class="label-text">转工单</span>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
- <el-col :span="6" class="flex flex-col items-center">
|
|
|
- <div ref="orderFinishChartRef" class="h-[160px] w-full"></div>
|
|
|
- <div class="text-center mt-2">
|
|
|
- <span class="text-sm text-gray-600">工单处理完成</span>
|
|
|
+ <el-col :span="6" class="chart-item">
|
|
|
+ <div ref="orderFinishChartRef" class="gauge-chart"></div>
|
|
|
+ <div class="chart-label">
|
|
|
+ <span class="label-dot label-dot-cyan"></span>
|
|
|
+ <span class="label-text">工单处理完成</span>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
|
- <el-card class="chart-card" shadow="never">
|
|
|
+ <el-card class="chart-card-enhanced" shadow="hover" style="border: none">
|
|
|
<template #header>
|
|
|
- <div class="flex items-center">
|
|
|
- <span class="text-base font-medium text-gray-600">维修工单状态统计</span>
|
|
|
+ <div class="chart-header">
|
|
|
+ <div class="chart-title-wrapper">
|
|
|
+ <div class="chart-title-dot"></div>
|
|
|
+ <span class="chart-title">维修工单状态统计</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
- <el-row class="h-[220px]">
|
|
|
- <el-col :span="12" class="flex flex-col items-center">
|
|
|
- <div ref="writeChartRef" class="h-[160px] w-full"></div>
|
|
|
- <div class="text-center mt-2">
|
|
|
- <span class="text-sm text-gray-600">待填写</span>
|
|
|
+ <el-row class="chart-grid">
|
|
|
+ <el-col :span="12" class="chart-item">
|
|
|
+ <div ref="writeChartRef" class="gauge-chart"></div>
|
|
|
+ <div class="chart-label">
|
|
|
+ <span class="label-dot label-dot-indigo"></span>
|
|
|
+ <span class="label-text">待填写</span>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
- <el-col :span="12" class="flex flex-col items-center">
|
|
|
- <div ref="finishedChartRef" class="h-[160px] w-full"></div>
|
|
|
- <div class="text-center mt-2">
|
|
|
- <span class="text-sm text-gray-600">已完成</span>
|
|
|
+ <el-col :span="12" class="chart-item">
|
|
|
+ <div ref="finishedChartRef" class="gauge-chart"></div>
|
|
|
+ <div class="chart-label">
|
|
|
+ <span class="label-dot label-dot-emerald"></span>
|
|
|
+ <span class="label-text">已完成</span>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
@@ -215,26 +163,29 @@
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
|
|
|
- <!-- 第三行:消息统计行 -->
|
|
|
+ <!-- 第三行:消息统计行 -->
|
|
|
<el-row>
|
|
|
<el-col :span="24">
|
|
|
- <el-card class="chart-card" shadow="never">
|
|
|
+ <el-card class="chart-card-enhanced" shadow="hover" style="border: none">
|
|
|
<template #header>
|
|
|
- <div class="flex items-center justify-between">
|
|
|
- <span class="text-base font-medium text-gray-600">近一年数量统计</span>
|
|
|
+ <div class="chart-header">
|
|
|
+ <div class="chart-title-wrapper">
|
|
|
+ <div class="chart-title-dot"></div>
|
|
|
+ <span class="chart-title">近一年数量统计</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
- <div ref="chartContainer" class="h-[300px]"></div>
|
|
|
+ <div ref="chartContainer" class="bar-chart-container"></div>
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
|
|
|
- <!-- TODO 第四行:地图 -->
|
|
|
+ <!-- TODO 第四行:地图 -->
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts" name="Index">
|
|
|
import * as echarts from 'echarts/core'
|
|
|
-import { BarChart } from 'echarts/charts'; // 显式导入柱状图模块
|
|
|
+import { BarChart } from 'echarts/charts' // 显式导入柱状图模块
|
|
|
|
|
|
import {
|
|
|
GridComponent,
|
|
|
@@ -691,8 +642,8 @@ const fetchChartData = async () => {
|
|
|
setTimeout(() => {
|
|
|
resolve({
|
|
|
months: generateMonthLabels(),
|
|
|
- faults: [20,30,100,40,20,50,70,80,60,90,100,100],
|
|
|
- repairs: [10,30,90,30,10,20,60,50,22,34,70,85],
|
|
|
+ faults: [20, 30, 100, 40, 20, 50, 70, 80, 60, 90, 100, 100],
|
|
|
+ repairs: [10, 30, 90, 30, 10, 20, 60, 50, 22, 34, 70, 85]
|
|
|
})
|
|
|
}, 300)
|
|
|
})
|
|
|
@@ -801,4 +752,273 @@ onUnmounted(() => {
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+// 统计卡片基础样式
|
|
|
+.stat-card {
|
|
|
+ border-radius: 12px;
|
|
|
+ border: none;
|
|
|
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ transform: translateY(-4px);
|
|
|
+ box-shadow: 0 12px 24px -8px rgba(0, 0, 0, 0.15);
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-card__body) {
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 渐变色背景
|
|
|
+.stat-card-gradient-1 {
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.stat-card-gradient-2 {
|
|
|
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.stat-card-gradient-3 {
|
|
|
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.stat-card-gradient-4 {
|
|
|
+ background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
|
|
+}
|
|
|
+
|
|
|
+// 统计内容区域
|
|
|
+.stat-content {
|
|
|
+ padding: 20px;
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-icon-wrapper {
|
|
|
+ width: 48px;
|
|
|
+ height: 48px;
|
|
|
+ background: rgba(255, 255, 255, 0.2);
|
|
|
+ border-radius: 12px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
+}
|
|
|
+
|
|
|
+.stat-icon {
|
|
|
+ font-size: 24px;
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: rgba(255, 255, 255, 0.95);
|
|
|
+}
|
|
|
+
|
|
|
+.stat-divider {
|
|
|
+ border-color: rgba(255, 255, 255, 0.2);
|
|
|
+ margin: 12px 0;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-body {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-label {
|
|
|
+ font-size: 13px;
|
|
|
+ color: rgba(255, 255, 255, 0.8);
|
|
|
+ margin-bottom: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-value {
|
|
|
+ font-size: 36px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: white;
|
|
|
+ line-height: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-sub-label {
|
|
|
+ font-size: 13px;
|
|
|
+ color: rgba(255, 255, 255, 0.85);
|
|
|
+}
|
|
|
+
|
|
|
+.stat-sub-value {
|
|
|
+ font-size: 28px;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 1;
|
|
|
+}
|
|
|
+
|
|
|
+// 图表卡片增强样式
|
|
|
+.chart-card-enhanced {
|
|
|
+ border-radius: 12px;
|
|
|
+ border: 1px solid #e5e7eb;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
|
|
|
+ border-color: #d1d5db;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-card__header) {
|
|
|
+ padding: 16px 20px;
|
|
|
+ border-bottom: 1px solid #f3f4f6;
|
|
|
+ background: linear-gradient(to right, #fafafa, #ffffff);
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-card__body) {
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.chart-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-title-wrapper {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-title-dot {
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ box-shadow: 0 2px 4px rgba(102, 126, 234, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.chart-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #1f2937;
|
|
|
+ letter-spacing: 0.3px;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-grid {
|
|
|
+ min-height: 220px;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ padding: 12px;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: rgba(102, 126, 234, 0.03);
|
|
|
+ border-radius: 8px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.gauge-chart {
|
|
|
+ width: 100%;
|
|
|
+ height: 160px;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-label {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+ margin-top: 8px;
|
|
|
+ padding: 6px 12px;
|
|
|
+ background: #f9fafb;
|
|
|
+ border-radius: 20px;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+
|
|
|
+ .chart-item:hover & {
|
|
|
+ background: #f3f4f6;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.label-dot {
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ border-radius: 50%;
|
|
|
+ display: inline-block;
|
|
|
+}
|
|
|
+
|
|
|
+.label-dot-blue {
|
|
|
+ background: #3b82f6;
|
|
|
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.label-dot-orange {
|
|
|
+ background: #f97316;
|
|
|
+ box-shadow: 0 0 0 2px rgba(249, 115, 22, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.label-dot-purple {
|
|
|
+ background: #8b5cf6;
|
|
|
+ box-shadow: 0 0 0 2px rgba(139, 92, 246, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.label-dot-cyan {
|
|
|
+ background: #06b6d4;
|
|
|
+ box-shadow: 0 0 0 2px rgba(6, 182, 212, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.label-dot-indigo {
|
|
|
+ background: #6366f1;
|
|
|
+ box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.label-dot-emerald {
|
|
|
+ background: #10b981;
|
|
|
+ box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.label-text {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #6b7280;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.bar-chart-container {
|
|
|
+ height: 350px;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+// 响应式优化
|
|
|
+@media (max-width: 1200px) {
|
|
|
+ .stat-value {
|
|
|
+ font-size: 28px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .stat-sub-value {
|
|
|
+ font-size: 24px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 768px) {
|
|
|
+ .stat-card {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .chart-item {
|
|
|
+ padding: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .gauge-chart {
|
|
|
+ height: 140px;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|