【代码评审】IoT:首页统计
							parent
							
								
									cc1a025a4e
								
							
						
					
					
						commit
						ca791df4de
					
				|  | @ -1,172 +1,177 @@ | |||
| <template> | ||||
|   <div class="min-h-full bg-gray-50"> | ||||
|     <el-space direction="vertical" :fill="true" size="small" class="w-full p-2"> | ||||
|       <!-- 统计卡片行 --> | ||||
|       <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">{{ 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 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">{{ statsData.productCount }}</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.productTodayCount }}</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">{{ statsData.deviceCount }}</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.deviceTodayCount }}</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:message" class="text-[32px] text-teal-400" /> | ||||
|               </div> | ||||
|               <span class="text-3xl font-bold text-gray-700">{{ statsData.deviceMessageCount }}</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.deviceMessageTodayCount }}</span> | ||||
|               </div> | ||||
|             </div> | ||||
|           </el-card> | ||||
|         </el-col> | ||||
|       </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"> | ||||
|             {{ 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 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">{{ statsData.productCount }}</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.productTodayCount }}</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">{{ statsData.deviceCount }}</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.deviceTodayCount }}</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:message" class="text-[32px] text-teal-400" /> | ||||
|           </div> | ||||
|           <span class="text-3xl font-bold text-gray-700"> | ||||
|             {{ statsData.deviceMessageCount }} | ||||
|           </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.deviceMessageTodayCount }}</span> | ||||
|           </div> | ||||
|         </div> | ||||
|       </el-card> | ||||
|     </el-col> | ||||
|   </el-row> | ||||
| 
 | ||||
|       <!-- 图表行 --> | ||||
|       <el-row :gutter="16" class="mb-4"> | ||||
|         <el-col :span="12"> | ||||
|           <el-card class="chart-card" shadow="never"> | ||||
|             <template #header> | ||||
|               <div class="flex items-center"> | ||||
|                 <span class="text-base font-medium text-gray-600">设备数量统计</span> | ||||
|               </div> | ||||
|             </template> | ||||
|             <div ref="chartDeviceNumStat" class="h-[240px]"></div> | ||||
|           </el-card> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-card class="chart-card" shadow="never"> | ||||
|             <template #header> | ||||
|               <div class="flex items-center"> | ||||
|                 <span class="text-base font-medium text-gray-600">设备状态统计</span> | ||||
|               </div> | ||||
|             </template> | ||||
|             <el-row class="h-[240px]"> | ||||
|               <el-col :span="8" class="flex flex-col items-center"> | ||||
|                 <div ref="chartDeviceOnline" class="h-[160px] w-full"></div> | ||||
|                 <div class="text-center mt-2"> | ||||
|                   <span class="text-sm text-gray-600">在线设备</span> | ||||
|                 </div> | ||||
|               </el-col> | ||||
|               <el-col :span="8" class="flex flex-col items-center"> | ||||
|                 <div ref="chartDeviceOffline" class="h-[160px] w-full"></div> | ||||
|                 <div class="text-center mt-2"> | ||||
|                   <span class="text-sm text-gray-600">离线设备</span> | ||||
|                 </div> | ||||
|               </el-col> | ||||
|               <el-col :span="8" class="flex flex-col items-center"> | ||||
|                 <div ref="chartDeviceActive" class="h-[160px] w-full"></div> | ||||
|                 <div class="text-center mt-2"> | ||||
|                   <span class="text-sm text-gray-600">待激活设备</span> | ||||
|                 </div> | ||||
|               </el-col> | ||||
|             </el-row> | ||||
|           </el-card> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|   <!-- 第二行:图表行 --> | ||||
|   <el-row :gutter="16" class="mb-4"> | ||||
|     <el-col :span="12"> | ||||
|       <el-card class="chart-card" shadow="never"> | ||||
|         <template #header> | ||||
|           <div class="flex items-center"> | ||||
|             <span class="text-base font-medium text-gray-600">设备数量统计</span> | ||||
|           </div> | ||||
|         </template> | ||||
|         <div ref="deviceCountChartRef" class="h-[240px]"></div> | ||||
|       </el-card> | ||||
|     </el-col> | ||||
|     <el-col :span="12"> | ||||
|       <el-card class="chart-card" shadow="never"> | ||||
|         <template #header> | ||||
|           <div class="flex items-center"> | ||||
|             <span class="text-base font-medium text-gray-600">设备状态统计</span> | ||||
|           </div> | ||||
|         </template> | ||||
|         <el-row class="h-[240px]"> | ||||
|           <el-col :span="8" class="flex flex-col items-center"> | ||||
|             <div ref="deviceOnlineCountChartRef" class="h-[160px] w-full"></div> | ||||
|             <div class="text-center mt-2"> | ||||
|               <span class="text-sm text-gray-600">在线设备</span> | ||||
|             </div> | ||||
|           </el-col> | ||||
|           <el-col :span="8" class="flex flex-col items-center"> | ||||
|             <div ref="deviceOfflineChartRef" class="h-[160px] w-full"></div> | ||||
|             <div class="text-center mt-2"> | ||||
|               <span class="text-sm text-gray-600">离线设备</span> | ||||
|             </div> | ||||
|           </el-col> | ||||
|           <el-col :span="8" class="flex flex-col items-center"> | ||||
|             <div ref="deviceActiveChartRef" class="h-[160px] w-full"></div> | ||||
|             <div class="text-center mt-2"> | ||||
|               <span class="text-sm text-gray-600">待激活设备</span> | ||||
|             </div> | ||||
|           </el-col> | ||||
|         </el-row> | ||||
|       </el-card> | ||||
|     </el-col> | ||||
|   </el-row> | ||||
| 
 | ||||
|       <!-- 消息统计行 --> | ||||
|       <el-row> | ||||
|         <el-col :span="24"> | ||||
|           <el-card class="chart-card" shadow="never"> | ||||
|             <template #header> | ||||
|               <div class="flex items-center justify-between"> | ||||
|                 <span class="text-base font-medium text-gray-600">上下行消息量统计</span> | ||||
|                 <div class="flex items-center space-x-2"> | ||||
|                   <el-radio-group v-model="timeRange"  @change="handleTimeRangeChange"> | ||||
|                     <el-radio-button label="1h">最近1小时</el-radio-button> | ||||
|                     <el-radio-button label="24h">最近24小时</el-radio-button> | ||||
|                     <el-radio-button label="7d">近一周</el-radio-button> | ||||
|                   </el-radio-group> | ||||
|                   <el-date-picker | ||||
|                     v-model="dateRange" | ||||
|                     type="datetimerange" | ||||
|                      | ||||
|                     range-separator="至" | ||||
|                     start-placeholder="开始时间" | ||||
|                     end-placeholder="结束时间" | ||||
|                     :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" | ||||
|                     @change="handleDateRangeChange" | ||||
|                   /> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </template> | ||||
|             <div ref="chartMsgStat" class="h-[300px]"></div> | ||||
|           </el-card> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|     </el-space> | ||||
|   </div> | ||||
|   <!-- 第三行:消息统计行 --> | ||||
|   <el-row> | ||||
|     <el-col :span="24"> | ||||
|       <el-card class="chart-card" shadow="never"> | ||||
|         <template #header> | ||||
|           <div class="flex items-center justify-between"> | ||||
|             <span class="text-base font-medium text-gray-600">上下行消息量统计</span> | ||||
|             <div class="flex items-center space-x-2"> | ||||
|               <el-radio-group v-model="timeRange" @change="handleTimeRangeChange"> | ||||
|                 <el-radio-button label="1h">最近1小时</el-radio-button> | ||||
|                 <el-radio-button label="24h">最近24小时</el-radio-button> | ||||
|                 <el-radio-button label="7d">近一周</el-radio-button> | ||||
|               </el-radio-group> | ||||
|               <el-date-picker | ||||
|                 v-model="dateRange" | ||||
|                 type="datetimerange" | ||||
|                 range-separator="至" | ||||
|                 start-placeholder="开始时间" | ||||
|                 end-placeholder="结束时间" | ||||
|                 :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" | ||||
|                 @change="handleDateRangeChange" | ||||
|               /> | ||||
|             </div> | ||||
|           </div> | ||||
|         </template> | ||||
|         <div ref="deviceMessageCountChartRef" class="h-[300px]"></div> | ||||
|       </el-card> | ||||
|     </el-col> | ||||
|   </el-row> | ||||
| 
 | ||||
|   <!-- TODO 第四行:地图 --> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="ts" name="Index"> | ||||
| import * as echarts from 'echarts/core' | ||||
| import { TooltipComponent, LegendComponent, TitleComponent, ToolboxComponent, GridComponent } from 'echarts/components' | ||||
| import { PieChart, LineChart, GaugeChart } from 'echarts/charts' | ||||
| import { | ||||
|   GridComponent, | ||||
|   LegendComponent, | ||||
|   TitleComponent, | ||||
|   ToolboxComponent, | ||||
|   TooltipComponent | ||||
| } from 'echarts/components' | ||||
| import { GaugeChart, LineChart, PieChart } from 'echarts/charts' | ||||
| import { LabelLayout, UniversalTransition } from 'echarts/features' | ||||
| import { CanvasRenderer } from 'echarts/renderers' | ||||
| import { ProductCategoryApi,IotStatisticsSummaryRespVO, IotStatisticsDeviceMessageSummaryRespVO} from '@/api/iot/statistics' | ||||
| import { | ||||
|   IotStatisticsDeviceMessageSummaryRespVO, | ||||
|   IotStatisticsSummaryRespVO, | ||||
|   ProductCategoryApi | ||||
| } from '@/api/iot/statistics' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import { Icon } from '@/components/Icon' | ||||
| 
 | ||||
| // TODO @super:参考下 /Users/yunai/Java/yudao-ui-admin-vue3/src/views/mall/home/index.vue,拆一拆组件 | ||||
| 
 | ||||
| /** IoT 首页 */ | ||||
| defineOptions({ name: 'IotHome' }) | ||||
| 
 | ||||
| const timeRange = ref('7d') // 修改默认选择为近一周 | ||||
| const dateRange = ref<[Date, Date] | null>(null) | ||||
| 
 | ||||
| const queryParams = reactive({ | ||||
|   startTime: Date.now() - 7 * 24 * 60 * 60 * 1000, // 设置默认开始时间为7天前 | ||||
|   endTime: Date.now() // 设置默认结束时间为当前时间 | ||||
| }) | ||||
| defineOptions({ name: 'IoTHome' }) | ||||
| 
 | ||||
| // TODO @super:使用下 Echart 组件,参考 yudao-ui-admin-vue3/src/views/mall/home/components/TradeTrendCard.vue 等 | ||||
| echarts.use([ | ||||
|   TooltipComponent, | ||||
|   LegendComponent, | ||||
|  | @ -181,14 +186,22 @@ echarts.use([ | |||
|   GaugeChart | ||||
| ]) | ||||
| 
 | ||||
| const chartDeviceNumStat = ref() | ||||
| const chartDeviceOnline = ref() | ||||
| const chartDeviceOffline = ref() | ||||
| const chartDeviceActive = ref() | ||||
| const chartMsgStat = ref() | ||||
| const timeRange = ref('7d') // 修改默认选择为近一周 | ||||
| const dateRange = ref<[Date, Date] | null>(null) | ||||
| 
 | ||||
| const queryParams = reactive({ | ||||
|   startTime: Date.now() - 7 * 24 * 60 * 60 * 1000, // 设置默认开始时间为 7 天前 | ||||
|   endTime: Date.now() // 设置默认结束时间为当前时间 | ||||
| }) | ||||
| 
 | ||||
| const deviceCountChartRef = ref() // 设备数量统计的图表 | ||||
| const deviceOnlineCountChartRef = ref() // 在线设备统计的图表 | ||||
| const deviceOfflineChartRef = ref() // 离线设备统计的图表 | ||||
| const deviceActiveChartRef = ref() // 待激活设备统计的图表 | ||||
| const deviceMessageCountChartRef = ref() // 上下行消息量统计的图表 | ||||
| 
 | ||||
| // 基础统计数据 | ||||
| // TODO @super:初始为 -1,然后界面展示先是加载中?试试用 cursor 改哈 | ||||
| const statsData = ref<IotStatisticsSummaryRespVO>({ | ||||
|   productCategoryCount: 0, | ||||
|   productCount: 0, | ||||
|  | @ -211,11 +224,12 @@ const messageStats = ref<IotStatisticsDeviceMessageSummaryRespVO>({ | |||
| }) | ||||
| 
 | ||||
| /** 处理快捷时间范围选择 */ | ||||
| const handleTimeRangeChange = (value: string) => { | ||||
| const handleTimeRangeChange = (timeRange: string) => { | ||||
|   const now = Date.now() | ||||
|   let startTime: number | ||||
| 
 | ||||
|   switch (value) { | ||||
|   // TODO @super:这个的计算,看看能不能结合 dayjs 简化。因为 1h、24h、7d 感觉是比较标准的。如果没有,抽到 utils/formatTime.ts 作为一个工具方法 | ||||
|   switch (timeRange) { | ||||
|     case '1h': | ||||
|       startTime = now - 60 * 60 * 1000 | ||||
|       break | ||||
|  | @ -231,11 +245,11 @@ const handleTimeRangeChange = (value: string) => { | |||
| 
 | ||||
|   // 清空日期选择器 | ||||
|   dateRange.value = null | ||||
|    | ||||
| 
 | ||||
|   // 更新查询参数 | ||||
|   queryParams.startTime = startTime | ||||
|   queryParams.endTime = now | ||||
|    | ||||
| 
 | ||||
|   // 重新获取数据 | ||||
|   getStats() | ||||
| } | ||||
|  | @ -245,11 +259,11 @@ const handleDateRangeChange = (value: [Date, Date] | null) => { | |||
|   if (value) { | ||||
|     // 清空快捷选项 | ||||
|     timeRange.value = '' | ||||
|      | ||||
| 
 | ||||
|     // 更新查询参数 | ||||
|     queryParams.startTime = value[0].getTime() | ||||
|     queryParams.endTime = value[1].getTime() | ||||
|      | ||||
| 
 | ||||
|     // 重新获取数据 | ||||
|     getStats() | ||||
|   } | ||||
|  | @ -258,13 +272,11 @@ const handleDateRangeChange = (value: [Date, Date] | null) => { | |||
| /** 获取统计数据 */ | ||||
| const getStats = async () => { | ||||
|   // 获取基础统计数据 | ||||
|   const summaryRes = await ProductCategoryApi.getIotStatisticsSummary() | ||||
|   statsData.value = summaryRes | ||||
|    | ||||
|   statsData.value = await ProductCategoryApi.getIotStatisticsSummary() | ||||
| 
 | ||||
|   // 获取消息统计数据 | ||||
|   const messageRes = await ProductCategoryApi.getIotStatisticsDeviceMessageSummary(queryParams) | ||||
|   messageStats.value = messageRes | ||||
|    | ||||
|   messageStats.value = await ProductCategoryApi.getIotStatisticsDeviceMessageSummary(queryParams) | ||||
| 
 | ||||
|   // 初始化图表 | ||||
|   initCharts() | ||||
| } | ||||
|  | @ -272,7 +284,7 @@ const getStats = async () => { | |||
| /** 初始化图表 */ | ||||
| const initCharts = () => { | ||||
|   // 设备数量统计 | ||||
|   echarts.init(chartDeviceNumStat.value).setOption({ | ||||
|   echarts.init(deviceCountChartRef.value).setOption({ | ||||
|     tooltip: { | ||||
|       trigger: 'item' | ||||
|     }, | ||||
|  | @ -313,13 +325,11 @@ const initCharts = () => { | |||
|   }) | ||||
| 
 | ||||
|   // 在线设备统计 | ||||
|   initGaugeChart(chartDeviceOnline.value, statsData.value.deviceOnlineCount, '#0d9') | ||||
| 
 | ||||
|   initGaugeChart(deviceOnlineCountChartRef.value, statsData.value.deviceOnlineCount, '#0d9') | ||||
|   // 离线设备统计 | ||||
|   initGaugeChart(chartDeviceOffline.value, statsData.value.deviceOfflineCount, '#f50') | ||||
| 
 | ||||
|   initGaugeChart(deviceOfflineChartRef.value, statsData.value.deviceOfflineCount, '#f50') | ||||
|   // 待激活设备统计 | ||||
|   initGaugeChart(chartDeviceActive.value, statsData.value.deviceInactiveCount, '#05b') | ||||
|   initGaugeChart(deviceActiveChartRef.value, statsData.value.deviceInactiveCount, '#05b') | ||||
| 
 | ||||
|   // 消息量统计 | ||||
|   initMessageChart() | ||||
|  | @ -362,7 +372,7 @@ const initGaugeChart = (el: any, value: number, color: string) => { | |||
|           color: color, | ||||
|           offsetCenter: [0, '0'], | ||||
|           formatter: (value: number) => { | ||||
|             return `${value}个` | ||||
|             return `${value} 个` | ||||
|           } | ||||
|         }, | ||||
|         data: [{ value: value }] | ||||
|  | @ -374,30 +384,31 @@ const initGaugeChart = (el: any, value: number, color: string) => { | |||
| /** 初始化消息统计图表 */ | ||||
| const initMessageChart = () => { | ||||
|   // 获取所有时间戳并排序 | ||||
|   // TODO @super:一些 idea 里的红色报错,要去处理掉噢。 | ||||
|   const timestamps = Array.from( | ||||
|     new Set([ | ||||
|       ...messageStats.value.upstreamCounts.map(item => Number(Object.keys(item)[0])), | ||||
|       ...messageStats.value.downstreamCounts.map(item => Number(Object.keys(item)[0])) | ||||
|       ...messageStats.value.upstreamCounts.map((item) => Number(Object.keys(item)[0])), | ||||
|       ...messageStats.value.downstreamCounts.map((item) => Number(Object.keys(item)[0])) | ||||
|     ]) | ||||
|   ).sort((a, b) => a - b) // 确保时间戳从小到大排序 | ||||
| 
 | ||||
|   // 准备数据 | ||||
|   const xdata = timestamps.map(ts => formatDate(ts, 'YYYY-MM-DD HH:mm')) | ||||
|   const upData = timestamps.map(ts => { | ||||
|   const xdata = timestamps.map((ts) => formatDate(ts, 'YYYY-MM-DD HH:mm')) | ||||
|   const upData = timestamps.map((ts) => { | ||||
|     const item = messageStats.value.upstreamCounts.find( | ||||
|       count => Number(Object.keys(count)[0]) === ts | ||||
|       (count) => Number(Object.keys(count)[0]) === ts | ||||
|     ) | ||||
|     return item ? Object.values(item)[0] : 0 | ||||
|   }) | ||||
|   const downData = timestamps.map(ts => { | ||||
|   const downData = timestamps.map((ts) => { | ||||
|     const item = messageStats.value.downstreamCounts.find( | ||||
|       count => Number(Object.keys(count)[0]) === ts | ||||
|       (count) => Number(Object.keys(count)[0]) === ts | ||||
|     ) | ||||
|     return item ? Object.values(item)[0] : 0 | ||||
|   }) | ||||
| 
 | ||||
|   // 配置图表 | ||||
|   echarts.init(chartMsgStat.value).setOption({ | ||||
|   echarts.init(deviceMessageCountChartRef.value).setOption({ | ||||
|     tooltip: { | ||||
|       trigger: 'axis', | ||||
|       backgroundColor: 'rgba(255, 255, 255, 0.9)', | ||||
|  | @ -491,59 +502,8 @@ const initMessageChart = () => { | |||
| 
 | ||||
| /** 初始化 */ | ||||
| onMounted(() => { | ||||
|   if (document.getElementById('breadcrumb-container')) { | ||||
|     document.getElementById('breadcrumb-container')!.style.display = 'none' | ||||
|   } | ||||
|   getStats() | ||||
| }) | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
| .stat-card { | ||||
|   @apply bg-white rounded overflow-hidden; | ||||
|    | ||||
|   :deep(.el-card__body) { | ||||
|     @apply p-3; | ||||
|   } | ||||
| 
 | ||||
|   .el-divider { | ||||
|     @apply my-2; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .chart-card { | ||||
|   @apply bg-white rounded overflow-hidden; | ||||
|    | ||||
|   :deep(.el-card__header) { | ||||
|     @apply py-2 px-3 border-b border-gray-100 bg-white; | ||||
|   } | ||||
| 
 | ||||
|   :deep(.el-card__body) { | ||||
|     @apply p-3; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // 修改图表配色方案,使其更加柔和 | ||||
| :deep(.echarts) { | ||||
|   .tooltip { | ||||
|     @apply bg-white/90 border border-gray-200 shadow-sm; | ||||
|   } | ||||
|    | ||||
|   .axis-line { | ||||
|     @apply text-gray-300; | ||||
|   } | ||||
|    | ||||
|   .split-line { | ||||
|     @apply text-gray-100; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // 添加时间选择器样式 | ||||
| :deep(.el-radio-group) { | ||||
|   @apply mr-4; | ||||
| } | ||||
| 
 | ||||
| :deep(.el-date-editor) { | ||||
|   @apply w-[360px]; | ||||
| } | ||||
| </style> | ||||
| <style lang="scss" scoped></style> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 YunaiV
						YunaiV