Selaa lähdekoodia

feat: 设备详情添加上下线记录查看功能;

liujia 1 kuukausi sitten
vanhempi
commit
a0d09d1

+ 7 - 0
src/api/stats/index.ts

@@ -37,3 +37,10 @@ export const statsHomeScreenAlarmHistory = (params: {
 }): Promise<ResponseData<TYPE.StatsHomeScreenAlarmHistory>> => {
   return request.post('/stats/alarm', params)
 }
+
+// 设备上下线统计
+export const statsDeviceOnlineQuery = (
+  params: TYPE.StatsDeviceOnlineQueryParams
+): Promise<ResponseData<TYPE.StatsDeviceOnlineQueryData>> => {
+  return request.post('/stats/OnoffRecord', params)
+}

+ 29 - 0
src/api/stats/types.ts

@@ -164,3 +164,32 @@ export interface StatsHomeScreenAlarmHistory {
     alarmCount: number
   }[]
 }
+
+/**
+ * 设备上下线统计入参
+
+ */
+export interface StatsDeviceOnlineQueryParams {
+  pageNo: number // 页码
+  pageSize: number // 每页条数
+  devId?: ID // 设备ID
+  createTimeStart: string // 起始时间 格式yyyy-MM-dd
+  createTimeEnd: string // 结束时间 格式yyyy-MM-dd
+}
+
+export type StatsDeviceOnlineQueryDataRow = {
+  type: string // 类型 on-上线 off-离线
+  createTime: string // 上下线时间
+}
+
+/**
+ * 设备上下线统计出参
+ */
+export interface StatsDeviceOnlineQueryData {
+  rows: StatsDeviceOnlineQueryDataRow[]
+  total: number
+  pageNum: number
+  pageSize: number
+  outTotalPageNum: boolean
+  totalPageNum: number
+}

+ 18 - 0
src/views/device/detail/components/deviceStatsDrawer/const.ts

@@ -68,3 +68,21 @@ export const alarmColumns = [
     width: 150,
   },
 ]
+
+// 上下线记录
+export const onlineColumns = [
+  {
+    title: '发生时间',
+    dataIndex: 'createTime',
+    key: 'createTime',
+    align: 'center',
+    width: 150,
+  },
+  {
+    title: '事件类型',
+    dataIndex: 'onlineType',
+    key: 'onlineType',
+    align: 'center',
+    width: 150,
+  },
+]

+ 48 - 11
src/views/device/detail/components/deviceStatsDrawer/index.vue

@@ -12,6 +12,7 @@
       <a-radio-group v-model:value="tableType" button-style="solid" size="small">
         <a-radio-button value="fall">跌倒统计</a-radio-button>
         <a-radio-button value="alarm">告警统计</a-radio-button>
+        <a-radio-button value="online">上下线记录</a-radio-button>
       </a-radio-group>
     </template>
 
@@ -47,13 +48,6 @@
     <div class="tableCard">
       <a-table :columns="columns" :data-source="tableList" :loading="loading" :pagination="false">
         <template #bodyCell="{ column, record }">
-          <!-- <template v-if="column.key === 'pose'">
-            {{ record.poseName }}
-          </template> -->
-          <!-- <template v-if="column.key === 'isHandle'">
-            <a-tag v-if="record.isHandle === 0" :bordered="false" color="red">未处理</a-tag>
-            <a-tag v-if="record.isHandle === 1" :bordered="false" color="green">已处理</a-tag>
-          </template> -->
           <template v-if="column.key === 'eventType'">
             {{ record.eventTypeName }}
           </template>
@@ -85,6 +79,11 @@
               </a-collapse>
             </div>
           </template>
+
+          <template v-if="column.key === 'onlineType'">
+            <a-tag v-if="record.type === 'on'" :bordered="false" color="green">上线</a-tag>
+            <a-tag v-if="record.type === 'off'" :bordered="false" color="red">离线</a-tag>
+          </template>
         </template>
       </a-table>
 
@@ -103,9 +102,13 @@
 <script setup lang="ts">
 import { computed, ref, watch } from 'vue'
 import { useSearch } from '@/hooks/useSearch'
-import { fallColumns, alarmColumns } from './const'
+import { fallColumns, alarmColumns, onlineColumns } from './const'
 import * as statsApi from '@/api/stats'
-import type { StatsFallQueryDataRow, StatsAlarmQueryDataRow } from '@/api/stats/types'
+import type {
+  StatsFallQueryDataRow,
+  StatsAlarmQueryDataRow,
+  StatsDeviceOnlineQueryDataRow,
+} from '@/api/stats/types'
 import { useDict, type DictItem } from '@/hooks/useDict'
 import { useDictName } from '@/hooks/useDictName'
 import * as alarmApi from '@/api/alarm'
@@ -120,6 +123,7 @@ type Props = {
   devId: string
   title?: string
   width?: number
+  type?: 'fall' | 'alarm' | 'online'
 }
 
 const emit = defineEmits<{
@@ -131,14 +135,17 @@ const props = withDefaults(defineProps<Props>(), {
   devId: '',
   title: '设备历史统计',
   width: 900,
+  type: 'fall',
 })
 
 // 表格统计类型展示 跌倒、一般滞留、异常滞留
-const tableType = ref<'fall' | 'alarm'>('fall')
+const tableType = ref<'fall' | 'alarm' | 'online'>('fall')
 
 const columns = computed(() => {
   if (tableType.value === 'alarm') {
     return alarmColumns
+  } else if (tableType.value === 'online') {
+    return onlineColumns
   } else {
     return fallColumns
   }
@@ -216,13 +223,15 @@ const alarmEventTypeOptions = computed(() => [
   })),
 ])
 
-const tableList = ref<(StatsFallQueryDataRow | StatsAlarmQueryDataRow)[]>([])
+type TableList = StatsFallQueryDataRow | StatsAlarmQueryDataRow | StatsDeviceOnlineQueryDataRow
+const tableList = ref<TableList[]>([])
 const tableTotal = ref<number>(0)
 const current = ref<number>(1)
 const pageSize = ref<number>(10)
 
 const fallList = ref<StatsFallQueryDataRow[]>([])
 const alarmList = ref<StatsAlarmQueryDataRow[]>([])
+const onlineList = ref<StatsDeviceOnlineQueryDataRow[]>([])
 
 // 搜索
 const searchHandler = async () => {
@@ -303,6 +312,30 @@ const fetchAlarmList = async () => {
   }
 }
 
+// 获取上下线统计数据
+const fetchOnlineList = async () => {
+  console.log('🚀🚀🚀fetchOnlineList')
+  try {
+    loading.value = true
+    const res = await statsApi.statsDeviceOnlineQuery({
+      pageNo: current.value,
+      pageSize: pageSize.value,
+      devId: props.devId,
+      createTimeStart: searchState.createTimeStart,
+      createTimeEnd: searchState.createTimeEnd,
+    })
+    console.log('✅ 获取上下线统计数据成功', res)
+    const { rows, total } = res.data
+    onlineList.value = rows as StatsDeviceOnlineQueryDataRow[]
+    tableList.value = onlineList.value
+    tableTotal.value = Number(total)
+    loading.value = false
+  } catch (error) {
+    console.error('❌ 获取上下线统计数据失败', error)
+    loading.value = false
+  }
+}
+
 const fetchList = () => {
   if (tableType.value === 'fall') {
     fetchFallList()
@@ -310,6 +343,9 @@ const fetchList = () => {
   if (tableType.value === 'alarm') {
     fetchAlarmList()
   }
+  if (tableType.value === 'online') {
+    fetchOnlineList()
+  }
 }
 
 watch(
@@ -325,6 +361,7 @@ watch(
   (newVal) => {
     if (newVal) {
       console.log('🌸🌸 DeviceStatsDrawer PROPS 🌸🌸', props)
+      tableType.value = props.type || 'fall'
       fetchList()
     }
   },

+ 31 - 10
src/views/device/detail/index.vue

@@ -94,14 +94,32 @@
           </info-item>
           <info-item label="归属租户">{{ detailState.tenantName }}</info-item>
           <info-item label="统计信息">
-            <a-button
-              v-if="detailState.clientId"
-              type="link"
-              size="small"
-              @click="viewDeviceHistoryInfo"
-            >
-              查看详情
-            </a-button>
+            <a-space>
+              <a-button
+                v-if="detailState.clientId"
+                type="link"
+                size="small"
+                @click="viewDeviceHistoryInfo('fall')"
+              >
+                跌倒
+              </a-button>
+              <a-button
+                v-if="detailState.clientId"
+                type="link"
+                size="small"
+                @click="viewDeviceHistoryInfo('alarm')"
+              >
+                告警
+              </a-button>
+              <a-button
+                v-if="detailState.clientId"
+                type="link"
+                size="small"
+                @click="viewDeviceHistoryInfo('online')"
+              >
+                上下线
+              </a-button>
+            </a-space>
           </info-item>
         </info-item-group>
 
@@ -211,6 +229,7 @@
         v-model:open="statsDrawerOpen"
         :dev-id="`${detailState.devId as string}`"
         :title="`${detailState.devName || ''} 统计信息`"
+        :type="statsDrawerType"
       ></deviceStatsDrawer>
 
       <alarmPlanModal
@@ -436,11 +455,13 @@ const roomConfigHandler = (type: 'base' | 'area') => {
   configDrawerOpen.value = true
 }
 
-const statsDrawerOpen = ref(false)
+const statsDrawerOpen = ref<boolean>(false)
+const statsDrawerType = ref<'online' | 'fall' | 'alarm'>('fall')
 // 查看设备历史信息
-const viewDeviceHistoryInfo = () => {
+const viewDeviceHistoryInfo = (type: 'online' | 'fall' | 'alarm') => {
   console.log('viewDeviceHistoryInfo')
   statsDrawerOpen.value = true
+  statsDrawerType.value = type
 }
 
 interface TargetInfo {