Commit d26b3c5210a234d256810e2330c4e4d60827afd4

Authored by ww
1 parent e36c83fa

perf: 优化告警列表

1 import { cloneDeep } from 'lodash-es' 1 import { cloneDeep } from 'lodash-es'
2 -import { TableColumnFieldEnum } from './types'  
3 import { AlarmListConfig } from '.' 2 import { AlarmListConfig } from '.'
4 import { ModeEnum } from '@/enums/modeEnum' 3 import { ModeEnum } from '@/enums/modeEnum'
5 import type { 4 import type {
6 CreateComponentParamsType, 5 CreateComponentParamsType,
7 CreateComponentType, 6 CreateComponentType,
8 } from '@/core/Library/types' 7 } from '@/core/Library/types'
9 -import type { BasicColumn } from '@/components/Table'  
10 -import type { CodeTypeEnum, ContentDataFieldsEnum } from '@/enums/datasource'  
11 8
12 -export const tableColumns: BasicColumn[] = [  
13 - {  
14 - title: '设备',  
15 - width: 200,  
16 - key: TableColumnFieldEnum.DEVICE_ID,  
17 - dataIndex: TableColumnFieldEnum.DEVICE_ID,  
18 - },  
19 - {  
20 - title: '操作',  
21 - key: 'action',  
22 - },  
23 -]  
24 -  
25 -export interface TableRecordItemType {  
26 - uuid: string  
27 - [TableColumnFieldEnum.DEVICE_ID]?: Nullable<string>  
28 - [ContentDataFieldsEnum.CODE_TYPE]?: Nullable<CodeTypeEnum>  
29 -}  
30 -  
31 -// 告警状态  
32 -export const alarmStatus = [  
33 - {  
34 - label: '清除未确认',  
35 - value: 'CLEARED_UNACK',  
36 - color: 'red',  
37 - },  
38 - {  
39 - label: '激活未确认',  
40 - value: 'ACTIVE_UNACK',  
41 - color: 'orange',  
42 - },  
43 - {  
44 - label: '清除已确认',  
45 - value: 'CLEARED_ACK',  
46 - color: 'cyan',  
47 - },  
48 - {  
49 - label: '激活已确认',  
50 - value: 'ACTIVE_ACK',  
51 - color: 'green',  
52 - },  
53 -]  
54 -  
55 -export interface alarmListInterface {  
56 - deviceName: string  
57 - deviceAlias: string  
58 - status: string  
59 - startTs: string  
60 -}  
61 -  
62 -// 模拟假数据  
63 -const alarmList = Array.from({ length: 20 }, (_, index) => ({  
64 - deviceName: `示例设备${index + 1}`,  
65 - deviceAlias: `示例设备${index + 1}`,  
66 - startTs: `2023-10-1${index + 1} 11:19:41`,  
67 - status: alarmStatus.map(item => item.value)[  
68 - Math.floor(Math.random() * alarmStatus.length)  
69 - ],  
70 -}))  
71 -  
72 -// 组件配置项  
73 export const options = { 9 export const options = {
74 - alarmList,  
75 - scroll: false,  
76 - interval: 0, 10 +
77 } 11 }
78 12
79 export default class Config implements CreateComponentType { 13 export default class Config implements CreateComponentType {
80 public key: string = AlarmListConfig.key 14 public key: string = AlarmListConfig.key
81 15
82 - public presetOption = cloneDeep(options as any) 16 + public presetOption = cloneDeep(options)
83 17
84 public mode = ModeEnum.EDIT 18 public mode = ModeEnum.EDIT
85 19
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { Button, Divider } from 'ant-design-vue' 2 import { Button, Divider } from 'ant-design-vue'
3 -import { onMounted, unref } from 'vue' 3 +import { onMounted, ref, unref } from 'vue'
4 import { AlarmListFieldsEnum, formSchemas } from './form.config' 4 import { AlarmListFieldsEnum, formSchemas } from './form.config'
5 import { FormLayoutEnum } from '@/components/Form/src/enum' 5 import { FormLayoutEnum } from '@/components/Form/src/enum'
6 import { BasicForm, useForm } from '@/components/Form' 6 import { BasicForm, useForm } from '@/components/Form'
@@ -10,6 +10,7 @@ import type { ConfigComponentProps } from '@/core/Library/types' @@ -10,6 +10,7 @@ import type { ConfigComponentProps } from '@/core/Library/types'
10 import { dateUtil } from '@/utils/dateUtil' 10 import { dateUtil } from '@/utils/dateUtil'
11 import { DateFormatEnum } from '@/enums/timeEnum' 11 import { DateFormatEnum } from '@/enums/timeEnum'
12 import type { AlarmListOptionType } from '@/api/node/model' 12 import type { AlarmListOptionType } from '@/api/node/model'
  13 +import { useSavePageContent } from '@/core/Library/hook/useSavePageContent'
13 14
14 const props = defineProps<ConfigComponentProps>() 15 const props = defineProps<ConfigComponentProps>()
15 16
@@ -17,6 +18,8 @@ defineEmits(['register']) @@ -17,6 +18,8 @@ defineEmits(['register'])
17 18
18 const { createMessage } = useMessage() 19 const { createMessage } = useMessage()
19 20
  21 +const loading = ref(false)
  22 +
20 const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: true }) 23 const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: true })
21 24
22 const { getNodeData, getNodeAllData, saveNodeAllData } = nodeDataActinType 25 const { getNodeData, getNodeAllData, saveNodeAllData } = nodeDataActinType
@@ -52,14 +55,23 @@ const setFieldsValue = (value: Recordable) => { @@ -52,14 +55,23 @@ const setFieldsValue = (value: Recordable) => {
52 }) 55 })
53 } 56 }
54 57
  58 +const { savePageContent } = useSavePageContent()
  59 +
55 const handleSave = async () => { 60 const handleSave = async () => {
56 - const validateFail = await validate()  
57 - if (!validateFail) return  
58 - const value = getFieldsValue() as AlarmListOptionType  
59 - await saveNodeAllData({  
60 - dataSourceJson: { alarmListOption: value },  
61 - })  
62 - createMessage.success('保存成功') 61 + try {
  62 + loading.value = true
  63 + const validateFail = await validate()
  64 + if (!validateFail) return
  65 + const value = getFieldsValue() as AlarmListOptionType
  66 + await saveNodeAllData({
  67 + dataSourceJson: { alarmListOption: value },
  68 + })
  69 + createMessage.success('保存成功')
  70 + savePageContent()
  71 + }
  72 + finally {
  73 + loading.value = false
  74 + }
63 } 75 }
64 76
65 onMounted(async () => { 77 onMounted(async () => {
@@ -76,7 +88,7 @@ onMounted(async () => { @@ -76,7 +88,7 @@ onMounted(async () => {
76 </Divider> 88 </Divider>
77 <div class="m-4"> 89 <div class="m-4">
78 <BasicForm @register="registerForm" /> 90 <BasicForm @register="registerForm" />
79 - <Button class="w-full" type="primary" @click="handleSave"> 91 + <Button class="w-full" type="primary" :loading="loading" @click="handleSave">
80 保存 92 保存
81 </Button> 93 </Button>
82 </div> 94 </div>
1 import { unref } from 'vue' 1 import { unref } from 'vue'
2 import dayjs from 'dayjs' 2 import dayjs from 'dayjs'
  3 +import { TableColumnFieldEnum } from './types'
3 import { getListByDeviceProfileIds } from '@/api/device' 4 import { getListByDeviceProfileIds } from '@/api/device'
4 import type { DeviceItemType } from '@/api/device/model' 5 import type { DeviceItemType } from '@/api/device/model'
5 import type { FormSchema } from '@/components/Form' 6 import type { FormSchema } from '@/components/Form'
6 import { ComponentEnum } from '@/components/Form/src/enum' 7 import { ComponentEnum } from '@/components/Form/src/enum'
7 import { useContentDataStoreWithOut } from '@/store/modules/contentData' 8 import { useContentDataStoreWithOut } from '@/store/modules/contentData'
8 import { DateFormatEnum } from '@/enums/timeEnum' 9 import { DateFormatEnum } from '@/enums/timeEnum'
  10 +import type { BasicColumn } from '@/components/Table'
  11 +import type { CodeTypeEnum, ContentDataFieldsEnum } from '@/enums/datasource'
9 12
10 const contentDataStore = useContentDataStoreWithOut() 13 const contentDataStore = useContentDataStoreWithOut()
11 14
  15 +export const tableColumns: BasicColumn[] = [
  16 + {
  17 + title: '设备',
  18 + width: 200,
  19 + key: TableColumnFieldEnum.DEVICE_ID,
  20 + dataIndex: TableColumnFieldEnum.DEVICE_ID,
  21 + },
  22 + {
  23 + title: '操作',
  24 + key: 'action',
  25 + },
  26 +]
  27 +
  28 +export interface TableRecordItemType {
  29 + uuid: string
  30 + [TableColumnFieldEnum.DEVICE_ID]?: Nullable<string>
  31 + [ContentDataFieldsEnum.CODE_TYPE]?: Nullable<CodeTypeEnum>
  32 +}
  33 +
  34 +// 告警状态
  35 +export const alarmStatus = [
  36 + {
  37 + label: '清除未确认',
  38 + value: 'CLEARED_UNACK',
  39 + color: 'red',
  40 + },
  41 + {
  42 + label: '激活未确认',
  43 + value: 'ACTIVE_UNACK',
  44 + color: 'orange',
  45 + },
  46 + {
  47 + label: '清除已确认',
  48 + value: 'CLEARED_ACK',
  49 + color: 'cyan',
  50 + },
  51 + {
  52 + label: '激活已确认',
  53 + value: 'ACTIVE_ACK',
  54 + color: 'green',
  55 + },
  56 +]
  57 +
  58 +export interface alarmListInterface {
  59 + deviceName: string
  60 + deviceAlias: string
  61 + status: string
  62 + startTs: string
  63 +}
  64 +
12 /** 65 /**
13 * 告警列表相关枚举 66 * 告警列表相关枚举
14 */ 67 */
@@ -2,13 +2,13 @@ @@ -2,13 +2,13 @@
2 import { computed, nextTick, onMounted, reactive, unref } from 'vue' 2 import { computed, nextTick, onMounted, reactive, unref } from 'vue'
3 import { Divider, Tag } from 'ant-design-vue' 3 import { Divider, Tag } from 'ant-design-vue'
4 import Vue3SeamlessScroll from 'vue3-seamless-scroll/package/Vue3SeamlessScroll' 4 import Vue3SeamlessScroll from 'vue3-seamless-scroll/package/Vue3SeamlessScroll'
5 -import type { alarmListInterface } from './config'  
6 -import { options } from './config'  
7 import { useAlarmList } from './useAlarmList.hook' 5 import { useAlarmList } from './useAlarmList.hook'
  6 +import { type alarmListInterface, alarmStatus } from './form.config'
8 import { fetchAlarmList } from '@/api/alarm' 7 import { fetchAlarmList } from '@/api/alarm'
9 import type { CreateComponentType } from '@/core/Library/types' 8 import type { CreateComponentType } from '@/core/Library/types'
10 import { useContentDataStore } from '@/store/modules/contentData' 9 import { useContentDataStore } from '@/store/modules/contentData'
11 import { isLightboxMode } from '@/utils/env' 10 import { isLightboxMode } from '@/utils/env'
  11 +import { formatToDateTime } from '@/utils/dateUtil'
12 12
13 const props = defineProps<{ 13 const props = defineProps<{
14 config: CreateComponentType 14 config: CreateComponentType
@@ -47,7 +47,7 @@ const initFetchAlarmList = async () => { @@ -47,7 +47,7 @@ const initFetchAlarmList = async () => {
47 const { alarmListOption } = dataSourceJson 47 const { alarmListOption } = dataSourceJson
48 if (!alarmListOption) return 48 if (!alarmListOption) return
49 const { startTime, endTime, deviceId, interval, autoPlay, polling } 49 const { startTime, endTime, deviceId, interval, autoPlay, polling }
50 - = alarmListOption 50 + = alarmListOption
51 51
52 const resp = (await fetchAlarmList({ 52 const resp = (await fetchAlarmList({
53 startTime, 53 startTime,
@@ -72,44 +72,39 @@ onMounted(async () => { @@ -72,44 +72,39 @@ onMounted(async () => {
72 setInterval(initFetchAlarmList, initOptions.polling * 1000) 72 setInterval(initFetchAlarmList, initOptions.polling * 1000)
73 } 73 }
74 else { 74 else {
75 - // 设计模式  
76 - for (const i in options) Reflect.set(initOptions, i, (options as any)[i]) 75 + Object.assign(initOptions, {
  76 + scroll: false,
  77 + interval: 0,
  78 + // 模拟假数据
  79 + alarmList: Array.from({ length: 20 }, (_, index) => ({
  80 + deviceName: `示例设备${index + 1}`,
  81 + deviceAlias: `示例设备${index + 1}`,
  82 + startTs: formatToDateTime(),
  83 + status: alarmStatus.map(item => item.value)[
  84 + Math.floor(Math.random() * alarmStatus.length)
  85 + ],
  86 + })),
  87 + })
77 } 88 }
78 }) 89 })
79 </script> 90 </script>
80 91
81 <template> 92 <template>
82 - <div  
83 - class="seamless-scroll w-full h-full flex justify-center items-center overflow-y-scroll"  
84 - > 93 + <div class="seamless-scroll w-full h-full flex justify-center items-center overflow-y-scroll">
85 <Vue3SeamlessScroll 94 <Vue3SeamlessScroll
86 - v-model="initOptions.scroll"  
87 - :single-wait-time="initOptions.interval"  
88 - :list="initOptions.alarmList"  
89 - :limit-scroll-num="10"  
90 - :is-rem-unit="true"  
91 - :delay="10"  
92 - :wheel="true"  
93 - hover  
94 - :style="{ 95 + v-model="initOptions.scroll" :single-wait-time="initOptions.interval"
  96 + :list="initOptions.alarmList" :limit-scroll-num="10" :is-rem-unit="true" :delay="10" :wheel="true" hover :style="{
95 width: `${getCellBounds.width}px`, 97 width: `${getCellBounds.width}px`,
96 height: `${getCellBounds.height}px`, 98 height: `${getCellBounds.height}px`,
97 }" 99 }"
98 > 100 >
99 - <div  
100 - v-for="(item, index) in initOptions.alarmList"  
101 - :key="index"  
102 - class="flex flex-col items-start h-15 px-2"  
103 - > 101 + <div v-for="(item, index) in initOptions.alarmList" :key="index" class="flex flex-col items-start h-15 px-2">
104 <p class="text-xs"> 102 <p class="text-xs">
105 设备:{{ item.deviceAlias || item.deviceName }} 103 设备:{{ item.deviceAlias || item.deviceName }}
106 </p> 104 </p>
107 <div class="flex items-center justify-between -mt-2"> 105 <div class="flex items-center justify-between -mt-2">
108 <span class="text-xs">时间:{{ item.startTs }}</span> 106 <span class="text-xs">时间:{{ item.startTs }}</span>
109 - <Tag  
110 - class="ml-2 text-xs"  
111 - :color="byStatusFindLabel(item.status, 'color')"  
112 - > 107 + <Tag class="ml-2 text-xs" :color="byStatusFindLabel(item.status, 'color')">
113 {{ byStatusFindLabel(item.status, "") }} 108 {{ byStatusFindLabel(item.status, "") }}
114 </Tag> 109 </Tag>
115 </div> 110 </div>
@@ -122,6 +117,7 @@ onMounted(async () => { @@ -122,6 +117,7 @@ onMounted(async () => {
122 <style scoped lang="less"> 117 <style scoped lang="less">
123 .seamless-scroll::-webkit-scrollbar { 118 .seamless-scroll::-webkit-scrollbar {
124 display: none; 119 display: none;
  120 +
125 .divider { 121 .divider {
126 height: 0.3px; 122 height: 0.3px;
127 background-color: black; 123 background-color: black;
1 -/**  
2 - * 告警列表相关hook  
3 - */  
4 -import { alarmStatus } from './config' 1 +import { alarmStatus } from './form.config'
5 2
6 export const useAlarmList = () => { 3 export const useAlarmList = () => {
7 // 映射label 4 // 映射label