소스 검색

feat(告警历史): 优化事件信息展示样式并添加折叠功能

- 在告警历史和设备统计抽屉中,为事件信息添加折叠面板功能
- 统一事件信息展示样式,包括背景色、间距和序号标记
- 调整表格列宽设置,优化布局
- 添加加载状态控制折叠面板初始显示
liujia 1 개월 전
부모
커밋
f6c9186

+ 2 - 1
src/views/alarm/history/const.ts

@@ -4,7 +4,7 @@ export const columns = [
     dataIndex: 'createTime',
     key: 'createTime',
     align: 'center',
-    // width: 200,
+    width: 200,
   },
   {
     title: '事件类型',
@@ -18,6 +18,7 @@ export const columns = [
     dataIndex: 'info',
     key: 'info',
     align: 'center',
+    width: 300,
   },
   {
     title: '备注',

+ 71 - 13
src/views/alarm/history/index.vue

@@ -43,19 +43,32 @@
             {{ record.eventTypeName }}
           </template>
           <template v-if="column.key === 'info'">
-            <div v-if="record.info?.start_time">开始时间:{{ record.info?.start_time }}</div>
-            <div v-if="record.info?.end_time">结束时间:{{ record.info?.end_time }}</div>
-            <div v-if="record.info?.stay_time">停留时长:{{ record.info?.stay_time }}(秒)</div>
-            <div v-if="record.info?.count">次数{{ record.info?.count }}</div>
-            <template v-if="record.info?.event_list">
-              事件列表:
-              <div v-for="(event, index) in record.info?.event_list" :key="index">
-                <div>开始时间{{ event.start_time }}</div>
-                <div>结束时间{{ event.end_time }}</div>
-                <div>停留时长{{ event.stay_time }}(秒)</div>
-                <div>消失时长{{ event.absence_time }}(秒)</div>
-              </div>
-            </template>
+            <div class="eventInfo">
+              <div v-if="record.info?.start_time">开始时间:{{ record.info?.start_time }}</div>
+              <div v-if="record.info?.end_time">结束时间:{{ record.info?.end_time }}</div>
+              <div v-if="record.info?.stay_time">停留时长:{{ record.info?.stay_time }}(秒)</div>
+              <div v-if="record.info?.count">次数:{{ record.info?.count }}</div>
+              <a-collapse ghost accordion v-if="record.info?.event_list && !initPanel">
+                <template #expandIcon="{ isActive }">
+                  <caret-right-outlined :rotate="isActive ? 90 : 0" />
+                </template>
+                <a-collapse-panel :header="`事件列表 (${record.info?.event_list?.length ?? 0}条)`">
+                  <ScrollContainer style="max-height: 110px">
+                    <div
+                      v-for="(event, index) in record.info?.event_list"
+                      :key="index"
+                      class="eventInfo-list"
+                    >
+                      <div v-if="event.start_time">开始时间:{{ event.start_time }}</div>
+                      <div v-if="event.end_time">结束时间:{{ event.end_time }}</div>
+                      <div v-if="event.stay_time">停留时长:{{ event.stay_time }}(秒)</div>
+                      <div v-if="event.absence_time">消失时长:{{ event.absence_time }}(秒)</div>
+                      <span class="showIndex">{{ index + 1 }}</span>
+                    </div>
+                  </ScrollContainer>
+                </a-collapse-panel>
+              </a-collapse>
+            </div>
           </template>
         </template>
       </a-table>
@@ -98,6 +111,7 @@ import alarmPlanModal from '@/views/device/detail/components/alarmPlanModal/inde
 import { useDictName } from '@/hooks/useDictName'
 import * as statsApi from '@/api/stats'
 import type { StatsAlarmQueryDataRow } from '@/api/stats/types'
+import { CaretRightOutlined } from '@ant-design/icons-vue'
 
 // const router = useRouter()
 
@@ -165,6 +179,7 @@ const fetchList = async () => {
   console.log('fetchList')
   try {
     loading.value = true
+    initPanel.value = true
     const res = await statsApi.statsAlarmQuery({
       pageNo: current.value,
       pageSize: pageSize.value,
@@ -187,9 +202,11 @@ const fetchList = async () => {
     tableList.value = alarmList.value
     tableTotal.value = Number(total)
     loading.value = false
+    initPanel.value = false
   } catch (error) {
     console.error('❌ 获取告警统计数据失败', error)
     loading.value = false
+    initPanel.value = false
   }
 }
 
@@ -253,6 +270,8 @@ onActivated(async () => {
     console.error('fetchList 失败', err)
   })
 })
+
+const initPanel = ref<boolean>(false)
 </script>
 
 <style scoped lang="less">
@@ -283,6 +302,45 @@ onActivated(async () => {
         font-weight: 600;
       }
     }
+
+    .eventInfo {
+      display: flex;
+      flex-direction: column;
+      align-items: flex-start;
+      padding: 10px;
+      border-radius: 4px;
+      &-list {
+        display: flex;
+        flex-direction: column;
+        align-items: flex-start;
+        background-color: #eee;
+        padding: 12px;
+        border-radius: 5px;
+        margin-bottom: 8px;
+        position: relative;
+
+        .showIndex {
+          position: absolute;
+          right: 0;
+          bottom: 0;
+          font-size: 12px;
+          color: #fff;
+          padding: 0 5px;
+          border-radius: 5px 0 5px 0;
+          background-color: #ccc;
+        }
+      }
+    }
   }
 }
+
+:deep(.ant-collapse > .ant-collapse-item > .ant-collapse-header) {
+  padding: 0 !important;
+}
+:deep(.ant-collapse > .ant-collapse-item > .ant-collapse-header > .ant-collapse-header-text) {
+  flex: none;
+}
+:deep(.ant-collapse .ant-collapse-content > .ant-collapse-content-box) {
+  padding: 0 !important;
+}
 </style>

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

@@ -37,7 +37,7 @@ export const alarmColumns = [
     dataIndex: 'createTime',
     key: 'createTime',
     align: 'center',
-    // width: 150,
+    width: 150,
   },
   {
     title: '事件类型',
@@ -51,7 +51,7 @@ export const alarmColumns = [
     dataIndex: 'info',
     key: 'info',
     align: 'center',
-    // width: 200,
+    width: 300,
   },
   // {
   //   title: '处理状态',

+ 68 - 13
src/views/device/detail/components/deviceStatsDrawer/index.vue

@@ -58,19 +58,32 @@
             {{ record.eventTypeName }}
           </template>
           <template v-if="column.key === 'info'">
-            <div v-if="record.info?.start_time">开始时间:{{ record.info?.start_time }}</div>
-            <div v-if="record.info?.end_time">结束时间:{{ record.info?.end_time }}</div>
-            <div v-if="record.info?.stay_time">停留时长:{{ record.info?.stay_time }}(秒)</div>
-            <div v-if="record.info?.count">次数{{ record.info?.count }}</div>
-            <template v-if="record.info?.event_list">
-              事件列表:
-              <div v-for="(event, index) in record.info?.event_list" :key="index">
-                <div>开始时间{{ event.start_time }}</div>
-                <div>结束时间{{ event.end_time }}</div>
-                <div>停留时长{{ event.stay_time }}(秒)</div>
-                <div>消失时长{{ event.absence_time }}(秒)</div>
-              </div>
-            </template>
+            <div class="eventInfo">
+              <div v-if="record.info?.start_time">开始时间:{{ record.info?.start_time }}</div>
+              <div v-if="record.info?.end_time">结束时间:{{ record.info?.end_time }}</div>
+              <div v-if="record.info?.stay_time">停留时长:{{ record.info?.stay_time }}(秒)</div>
+              <div v-if="record.info?.count">次数:{{ record.info?.count }}</div>
+              <a-collapse ghost accordion v-if="record.info?.event_list && !initPanel">
+                <template #expandIcon="{ isActive }">
+                  <caret-right-outlined :rotate="isActive ? 90 : 0" />
+                </template>
+                <a-collapse-panel :header="`事件列表 (${record.info?.event_list?.length ?? 0}条)`">
+                  <ScrollContainer style="max-height: 110px">
+                    <div
+                      v-for="(event, index) in record.info?.event_list"
+                      :key="index"
+                      class="eventInfo-list"
+                    >
+                      <div v-if="event.start_time">开始时间:{{ event.start_time }}</div>
+                      <div v-if="event.end_time">结束时间:{{ event.end_time }}</div>
+                      <div v-if="event.stay_time">停留时长:{{ event.stay_time }}(秒)</div>
+                      <div v-if="event.absence_time">消失时长:{{ event.absence_time }}(秒)</div>
+                      <span class="showIndex">{{ index + 1 }}</span>
+                    </div>
+                  </ScrollContainer>
+                </a-collapse-panel>
+              </a-collapse>
+            </div>
           </template>
         </template>
       </a-table>
@@ -96,6 +109,7 @@ import type { StatsFallQueryDataRow, StatsAlarmQueryDataRow } from '@/api/stats/
 import { useDict, type DictItem } from '@/hooks/useDict'
 import { useDictName } from '@/hooks/useDictName'
 import * as alarmApi from '@/api/alarm'
+import { CaretRightOutlined } from '@ant-design/icons-vue'
 
 defineOptions({
   name: 'DeviceStatsDrawer',
@@ -318,6 +332,8 @@ watch(
     immediate: true,
   }
 )
+
+const initPanel = ref<boolean>(false)
 </script>
 
 <style scoped lang="less">
@@ -346,5 +362,44 @@ watch(
       font-weight: 600;
     }
   }
+
+  .eventInfo {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    padding: 10px;
+    border-radius: 4px;
+    &-list {
+      display: flex;
+      flex-direction: column;
+      align-items: flex-start;
+      background-color: #eee;
+      padding: 12px;
+      border-radius: 5px;
+      margin-bottom: 8px;
+      position: relative;
+
+      .showIndex {
+        position: absolute;
+        right: 0;
+        bottom: 0;
+        font-size: 12px;
+        color: #fff;
+        padding: 0 5px;
+        border-radius: 5px 0 5px 0;
+        background-color: #ccc;
+      }
+    }
+  }
+}
+
+:deep(.ant-collapse > .ant-collapse-item > .ant-collapse-header) {
+  padding: 0 !important;
+}
+:deep(.ant-collapse > .ant-collapse-item > .ant-collapse-header > .ant-collapse-header-text) {
+  flex: none;
+}
+:deep(.ant-collapse .ant-collapse-content > .ant-collapse-content-box) {
+  padding: 0 !important;
 }
 </style>