Showing
5 changed files
with
99 additions
and
107 deletions
1 | 1 | import { cloneDeep } from 'lodash-es' |
2 | -import { TableColumnFieldEnum } from './types' | |
3 | 2 | import { AlarmListConfig } from '.' |
4 | 3 | import { ModeEnum } from '@/enums/modeEnum' |
5 | 4 | import type { |
6 | 5 | CreateComponentParamsType, |
7 | 6 | CreateComponentType, |
8 | 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 | 9 | export const options = { |
74 | - alarmList, | |
75 | - scroll: false, | |
76 | - interval: 0, | |
10 | + | |
77 | 11 | } |
78 | 12 | |
79 | 13 | export default class Config implements CreateComponentType { |
80 | 14 | public key: string = AlarmListConfig.key |
81 | 15 | |
82 | - public presetOption = cloneDeep(options as any) | |
16 | + public presetOption = cloneDeep(options) | |
83 | 17 | |
84 | 18 | public mode = ModeEnum.EDIT |
85 | 19 | ... | ... |
1 | 1 | <script setup lang="ts"> |
2 | 2 | import { Button, Divider } from 'ant-design-vue' |
3 | -import { onMounted, unref } from 'vue' | |
3 | +import { onMounted, ref, unref } from 'vue' | |
4 | 4 | import { AlarmListFieldsEnum, formSchemas } from './form.config' |
5 | 5 | import { FormLayoutEnum } from '@/components/Form/src/enum' |
6 | 6 | import { BasicForm, useForm } from '@/components/Form' |
... | ... | @@ -10,6 +10,7 @@ import type { ConfigComponentProps } from '@/core/Library/types' |
10 | 10 | import { dateUtil } from '@/utils/dateUtil' |
11 | 11 | import { DateFormatEnum } from '@/enums/timeEnum' |
12 | 12 | import type { AlarmListOptionType } from '@/api/node/model' |
13 | +import { useSavePageContent } from '@/core/Library/hook/useSavePageContent' | |
13 | 14 | |
14 | 15 | const props = defineProps<ConfigComponentProps>() |
15 | 16 | |
... | ... | @@ -17,6 +18,8 @@ defineEmits(['register']) |
17 | 18 | |
18 | 19 | const { createMessage } = useMessage() |
19 | 20 | |
21 | +const loading = ref(false) | |
22 | + | |
20 | 23 | const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: true }) |
21 | 24 | |
22 | 25 | const { getNodeData, getNodeAllData, saveNodeAllData } = nodeDataActinType |
... | ... | @@ -52,14 +55,23 @@ const setFieldsValue = (value: Recordable) => { |
52 | 55 | }) |
53 | 56 | } |
54 | 57 | |
58 | +const { savePageContent } = useSavePageContent() | |
59 | + | |
55 | 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 | 77 | onMounted(async () => { |
... | ... | @@ -76,7 +88,7 @@ onMounted(async () => { |
76 | 88 | </Divider> |
77 | 89 | <div class="m-4"> |
78 | 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 | 93 | </Button> |
82 | 94 | </div> | ... | ... |
1 | 1 | import { unref } from 'vue' |
2 | 2 | import dayjs from 'dayjs' |
3 | +import { TableColumnFieldEnum } from './types' | |
3 | 4 | import { getListByDeviceProfileIds } from '@/api/device' |
4 | 5 | import type { DeviceItemType } from '@/api/device/model' |
5 | 6 | import type { FormSchema } from '@/components/Form' |
6 | 7 | import { ComponentEnum } from '@/components/Form/src/enum' |
7 | 8 | import { useContentDataStoreWithOut } from '@/store/modules/contentData' |
8 | 9 | import { DateFormatEnum } from '@/enums/timeEnum' |
10 | +import type { BasicColumn } from '@/components/Table' | |
11 | +import type { CodeTypeEnum, ContentDataFieldsEnum } from '@/enums/datasource' | |
9 | 12 | |
10 | 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 | 2 | import { computed, nextTick, onMounted, reactive, unref } from 'vue' |
3 | 3 | import { Divider, Tag } from 'ant-design-vue' |
4 | 4 | import Vue3SeamlessScroll from 'vue3-seamless-scroll/package/Vue3SeamlessScroll' |
5 | -import type { alarmListInterface } from './config' | |
6 | -import { options } from './config' | |
7 | 5 | import { useAlarmList } from './useAlarmList.hook' |
6 | +import { type alarmListInterface, alarmStatus } from './form.config' | |
8 | 7 | import { fetchAlarmList } from '@/api/alarm' |
9 | 8 | import type { CreateComponentType } from '@/core/Library/types' |
10 | 9 | import { useContentDataStore } from '@/store/modules/contentData' |
11 | 10 | import { isLightboxMode } from '@/utils/env' |
11 | +import { formatToDateTime } from '@/utils/dateUtil' | |
12 | 12 | |
13 | 13 | const props = defineProps<{ |
14 | 14 | config: CreateComponentType |
... | ... | @@ -47,7 +47,7 @@ const initFetchAlarmList = async () => { |
47 | 47 | const { alarmListOption } = dataSourceJson |
48 | 48 | if (!alarmListOption) return |
49 | 49 | const { startTime, endTime, deviceId, interval, autoPlay, polling } |
50 | - = alarmListOption | |
50 | + = alarmListOption | |
51 | 51 | |
52 | 52 | const resp = (await fetchAlarmList({ |
53 | 53 | startTime, |
... | ... | @@ -72,44 +72,39 @@ onMounted(async () => { |
72 | 72 | setInterval(initFetchAlarmList, initOptions.polling * 1000) |
73 | 73 | } |
74 | 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 | 90 | </script> |
80 | 91 | |
81 | 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 | 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 | 97 | width: `${getCellBounds.width}px`, |
96 | 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 | 102 | <p class="text-xs"> |
105 | 103 | 设备:{{ item.deviceAlias || item.deviceName }} |
106 | 104 | </p> |
107 | 105 | <div class="flex items-center justify-between -mt-2"> |
108 | 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 | 108 | {{ byStatusFindLabel(item.status, "") }} |
114 | 109 | </Tag> |
115 | 110 | </div> |
... | ... | @@ -122,6 +117,7 @@ onMounted(async () => { |
122 | 117 | <style scoped lang="less"> |
123 | 118 | .seamless-scroll::-webkit-scrollbar { |
124 | 119 | display: none; |
120 | + | |
125 | 121 | .divider { |
126 | 122 | height: 0.3px; |
127 | 123 | background-color: black; | ... | ... |