alwayssuper 1 anno fa
parent
commit
89a8b25f17

+ 7 - 2
src/api/iot/statistics/index.ts

@@ -16,10 +16,15 @@ export interface IotStatisticsSummaryRespVO {
   productCategoryDeviceCounts: Record<string, number>
 }
 
+/** 时间戳-数值的键值对类型 */
+interface TimeValueItem {
+  [key: string]: number
+}
+
 /** IoT 消息统计数据类型 */
 export interface IotStatisticsDeviceMessageSummaryRespVO {
-  upstreamCounts: Record<number, number>
-  downstreamCounts: Record<number, number>
+  upstreamCounts: TimeValueItem[]
+  downstreamCounts: TimeValueItem[]
 }
 
 // IoT 数据统计 API

+ 27 - 0
src/utils/formatTime.ts

@@ -330,3 +330,30 @@ export function getDateRange(
     dayjs(endDate).endOf('d').format('YYYY-MM-DD HH:mm:ss')
   ]
 }
+
+/**
+ * 获取指定小时前的时间戳
+ * @param hours 小时数
+ * @returns 返回指定小时前的时间戳(毫秒)
+ */
+export function getHoursAgo(hours: number): number {
+  return dayjs().subtract(hours, 'hour').valueOf()
+}
+
+/**
+ * 获取标准时间范围的时间戳
+ * @param range 时间范围,支持 '8h' | '24h' | '7d'
+ * @returns 返回开始时间戳(毫秒)
+ */
+export function getTimeRangeStart(range: '8h' | '24h' | '7d'): number {
+  switch (range) {
+    case '8h':
+      return getHoursAgo(8)
+    case '24h':
+      return getHoursAgo(24)
+    case '7d':
+      return dayjs().subtract(7, 'day').valueOf()
+    default:
+      return dayjs().valueOf()
+  }
+}

+ 71 - 39
src/views/iot/home/components/MessageTrendCard.vue

@@ -32,8 +32,9 @@ import { CanvasRenderer } from 'echarts/renderers'
 import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
 import { UniversalTransition } from 'echarts/features'
 import { IotStatisticsDeviceMessageSummaryRespVO } from '@/api/iot/statistics'
-import { formatDate } from '@/utils/formatTime'
+import { formatDate, getTimeRangeStart } from '@/utils/formatTime'
 import type { PropType } from 'vue'
+import dayjs from 'dayjs'
 
 /** 消息趋势统计卡片 */
 defineOptions({ name: 'MessageTrendCard' })
@@ -48,27 +49,14 @@ const props = defineProps({
 const emit = defineEmits(['timeRangeChange'])
 
 const timeRange = ref('7d')
-const dateRange = ref<[Date, Date] | null>(null)
+const dateRange = ref<any>(null)
 const messageChartRef = ref()
 
+// TODO @super:这个的计算,看看能不能结合 dayjs 简化。因为 1h、24h、7d 感觉是比较标准的。如果没有,抽到 utils/formatTime.ts 作为一个工具方法
 // 处理快捷时间范围选择
 const handleTimeRangeChange = (range: string) => {
-  const now = Date.now()
-  let startTime: number
-
-  switch (range) {
-    case '8h':
-      startTime = now - 8 * 60 * 60 * 1000
-      break
-    case '24h':
-      startTime = now - 24 * 60 * 60 * 1000
-      break
-    case '7d':
-      startTime = now - 7 * 24 * 60 * 60 * 1000
-      break
-    default:
-      return
-  }
+  const now = dayjs().valueOf()
+  const startTime = getTimeRangeStart(range as '8h' | '24h' | '7d')
 
   dateRange.value = null
   emit('timeRangeChange', { startTime, endTime: now })
@@ -96,31 +84,75 @@ const initChart = () => {
     UniversalTransition
   ])
 
-  const timestamps = Array.from(
-    new Set([
-      ...props.messageStats.upstreamCounts.map((item) => Number(Object.keys(item)[0])),
-      ...props.messageStats.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 item = props.messageStats.upstreamCounts.find(
-      (count) => Number(Object.keys(count)[0]) === ts
-    )
-    return item ? Object.values(item)[0] : 0
-  })
-  const downData = timestamps.map((ts) => {
-    const item = props.messageStats.downstreamCounts.find(
-      (count) => Number(Object.keys(count)[0]) === ts
-    )
-    return item ? Object.values(item)[0] : 0
-  })
+  // 检查数据格式并转换
+  const upstreamCounts = Array.isArray(props.messageStats.upstreamCounts) 
+    ? props.messageStats.upstreamCounts 
+    : Object.entries(props.messageStats.upstreamCounts || {}).map(([key, value]) => ({ [key]: value }))
+  
+  const downstreamCounts = Array.isArray(props.messageStats.downstreamCounts) 
+    ? props.messageStats.downstreamCounts 
+    : Object.entries(props.messageStats.downstreamCounts || {}).map(([key, value]) => ({ [key]: value }))
 
   // 获取所有时间戳并排序
+  let timestamps: number[] = []
+  
+  try {
+    // 尝试从数组中提取时间戳
+    if (Array.isArray(upstreamCounts) && upstreamCounts.length > 0) {
+      timestamps = Array.from(
+        new Set([
+          ...upstreamCounts.map(item => Number(Object.keys(item)[0])),
+          ...downstreamCounts.map(item => Number(Object.keys(item)[0]))
+        ])
+      ).sort((a, b) => a - b)
+    } else {
+      // 如果数组为空或不是数组,尝试从对象中提取时间戳
+      const upKeys = Object.keys(props.messageStats.upstreamCounts || {}).map(Number)
+      const downKeys = Object.keys(props.messageStats.downstreamCounts || {}).map(Number)
+      timestamps = Array.from(new Set([...upKeys, ...downKeys])).sort((a, b) => a - b)
+    }
+  } catch (error) {
+    console.error('提取时间戳出错:', error)
+    timestamps = []
+  }
+
+
+  // 准备数据
+  const xdata = timestamps.map((ts) => formatDate(dayjs(ts).toDate(), 'YYYY-MM-DD HH:mm'))
+  
+  let upData: number[] = []
+  let downData: number[] = []
+  
+  try {
+    // 尝试从数组中提取数据
+    if (Array.isArray(upstreamCounts) && upstreamCounts.length > 0) {
+      upData = timestamps.map((ts) => {
+        const item = upstreamCounts.find(count => 
+          Number(Object.keys(count)[0]) === ts
+        )
+        return item ? Number(Object.values(item)[0]) : 0
+      })
+      
+      downData = timestamps.map((ts) => {
+        const item = downstreamCounts.find(count => 
+          Number(Object.keys(count)[0]) === ts
+        )
+        return item ? Number(Object.values(item)[0]) : 0
+      })
+    } else {
+      // 如果数组为空或不是数组,尝试从对象中提取数据
+      const upstreamObj = props.messageStats.upstreamCounts || {}
+      const downstreamObj = props.messageStats.downstreamCounts || {}
+      upData = timestamps.map((ts) => Number(upstreamObj[ts as keyof typeof upstreamObj] || 0))
+      downData = timestamps.map((ts) => Number(downstreamObj[ts as keyof typeof downstreamObj] || 0))
+    }
+  } catch (error) {
+    console.error('提取数据出错:', error)
+    upData = []
+    downData = []
+  }
 
-  console.log(xdata, upData, downData)
 
   // 配置图表
   const chart = echarts.init(messageChartRef.value)

+ 2 - 0
src/views/iot/home/index.vue

@@ -124,6 +124,8 @@ const getStats = async () => {
   statsData.value = await ProductCategoryApi.getIotStatisticsSummary()
   // 获取消息统计数据
   messageStats.value = await ProductCategoryApi.getIotStatisticsDeviceMessageSummary(queryParams)
+  console.log('statsData', statsData.value)
+  console.log('messageStats', messageStats.value)
 }
 
 /** 初始化 */