Showing
5 changed files
with
99 additions
and
107 deletions
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; |