Showing
10 changed files
with
698 additions
and
73 deletions
... | ... | @@ -68,9 +68,6 @@ dependencies: |
68 | 68 | vue: |
69 | 69 | specifier: ^3.3.4 |
70 | 70 | version: 3.3.4 |
71 | - vue3-seamless-scroll: | |
72 | - specifier: ^2.0.1 | |
73 | - version: 2.0.1 | |
74 | 71 | |
75 | 72 | devDependencies: |
76 | 73 | '@iconify/vue': |
... | ... | @@ -6412,12 +6409,6 @@ packages: |
6412 | 6409 | vue: 3.3.4 |
6413 | 6410 | dev: false |
6414 | 6411 | |
6415 | - /vue3-seamless-scroll@2.0.1: | |
6416 | - resolution: {integrity: sha512-mI3BaDU3pjcPUhVSw3/xNKdfPBDABTi/OdZaZqKysx4cSdNfGRbVvGNDzzptBbJ5S7imv5T55l6x/SqgnxKreg==} | |
6417 | - dependencies: | |
6418 | - throttle-debounce: 5.0.0 | |
6419 | - dev: false | |
6420 | - | |
6421 | 6412 | /vue@3.3.4: |
6422 | 6413 | resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} |
6423 | 6414 | dependencies: | ... | ... |
1 | +import type { AlarmStatusEnum } from '@/enums/datasource' | |
2 | + | |
1 | 3 | /** |
2 | 4 | * 告警列表 |
3 | 5 | */ |
... | ... | @@ -28,7 +30,7 @@ export interface AlarmListItemType { |
28 | 30 | deviceName: string |
29 | 31 | type: string |
30 | 32 | severity: string |
31 | - status: string | |
33 | + status: AlarmStatusEnum | |
32 | 34 | startTs: string |
33 | 35 | endTs: string |
34 | 36 | ackTs: string | ... | ... |
src/core/Library/hook/useComponentStyle.ts
0 → 100644
1 | +import type { CSSProperties } from 'vue' | |
2 | +import type { RenderComponentProps } from '../types' | |
3 | +import { NodeUtils } from '@/hooks/business/useNodeUtils' | |
4 | +import { EnableEnum, GradientDirectionEnum, type MxShapeStyleType } from '@/fitCore/types' | |
5 | + | |
6 | +const gradientDirectionMap = { | |
7 | + [GradientDirectionEnum.NORTH]: 'to top', | |
8 | + [GradientDirectionEnum.EAST]: 'to right', | |
9 | + [GradientDirectionEnum.SOUTH]: 'to bottom', | |
10 | + [GradientDirectionEnum.WEST]: 'to left', | |
11 | +} | |
12 | + | |
13 | +export interface UseComponentStyleReturnType { | |
14 | + style: CSSProperties | |
15 | + textAalign?: string | |
16 | + borderColor?: string | |
17 | + borderWidth?: number | |
18 | + borderStyle?: string | |
19 | + backgroundColor?: string | |
20 | + fontFamily?: string | |
21 | + color?: string | |
22 | + fontSize?: number | |
23 | + gradientBackgroundColor?: string | |
24 | + gradientDirection?: GradientDirectionEnum | |
25 | + opacity?: number | |
26 | +} | |
27 | + | |
28 | +export function useComponentStyle(props: RenderComponentProps): UseComponentStyleReturnType { | |
29 | + const result: UseComponentStyleReturnType = { style: {} } | |
30 | + | |
31 | + const nodeUtils = new NodeUtils() | |
32 | + const { cellInfo } = props.config | |
33 | + const { id } = cellInfo || {} | |
34 | + if (!id) return result | |
35 | + const cell = nodeUtils.getCellById(id) | |
36 | + | |
37 | + if (!cell) return result | |
38 | + | |
39 | + const cellState = nodeUtils.getCellState(cell) | |
40 | + | |
41 | + const { | |
42 | + align, | |
43 | + dashed, | |
44 | + fillColor, | |
45 | + fontColor, | |
46 | + fontFamily, | |
47 | + fontSize, | |
48 | + gradientColor, | |
49 | + gradientDirection, | |
50 | + opacity, | |
51 | + // shadow, | |
52 | + strokeColor, | |
53 | + // sketch, | |
54 | + strokeWidth = 1, | |
55 | + } = cellState.style as MxShapeStyleType | |
56 | + | |
57 | + const getBackgroundColor = () => { | |
58 | + return { | |
59 | + background: gradientColor !== 'none' | |
60 | + ? gradientDirection === GradientDirectionEnum.RADIAL | |
61 | + ? `radial-gradient(${fillColor}, ${gradientColor})` | |
62 | + : `linear-gradient(${gradientDirectionMap[gradientDirection]}, ${fillColor}, ${gradientColor})` | |
63 | + : fillColor, | |
64 | + } as CSSProperties | |
65 | + } | |
66 | + | |
67 | + const getBorderStyle = () => { | |
68 | + return { | |
69 | + borderColor: strokeColor, | |
70 | + borderWidth: strokeWidth, | |
71 | + borderStyle: strokeColor | |
72 | + ? dashed === EnableEnum.ENABLE | |
73 | + ? 'dashed' | |
74 | + : 'solid' | |
75 | + : 'none', | |
76 | + } as CSSProperties | |
77 | + } | |
78 | + | |
79 | + return { | |
80 | + style: { | |
81 | + textAlign: align, | |
82 | + opacity, | |
83 | + fontSize, | |
84 | + fontFamily, | |
85 | + color: fontColor, | |
86 | + ...getBorderStyle(), | |
87 | + ...getBackgroundColor(), | |
88 | + }, | |
89 | + textAalign: align, | |
90 | + borderColor: strokeColor, | |
91 | + borderWidth: strokeWidth, | |
92 | + borderStyle: dashed === EnableEnum.ENABLE ? 'dashed' : 'solid', | |
93 | + backgroundColor: fillColor, | |
94 | + fontFamily, | |
95 | + color: fontColor, | |
96 | + fontSize, | |
97 | + gradientBackgroundColor: gradientColor, | |
98 | + gradientDirection, | |
99 | + opacity, | |
100 | + } | |
101 | +} | ... | ... |
1 | +import type { CSSProperties } from 'vue' | |
2 | +import { | |
3 | + computed, | |
4 | + defineComponent, | |
5 | + getCurrentInstance, | |
6 | + nextTick, | |
7 | + onBeforeMount, | |
8 | + onMounted, | |
9 | + ref, | |
10 | + watch, | |
11 | +} from 'vue' | |
12 | +import { useThrottleFn } from '@vueuse/core' | |
13 | + | |
14 | +interface PropsType { | |
15 | + modelValue: boolean | |
16 | + list: Array<unknown> | |
17 | + step: number | |
18 | + limitScrollNum: number | |
19 | + hover: boolean | |
20 | + direction: String | |
21 | + singleHeight: number | |
22 | + singleWidth: number | |
23 | + singleWaitTime: number | |
24 | + isRemUnit: boolean | |
25 | + isWatch: boolean | |
26 | + delay: number | |
27 | + ease: any | |
28 | + count: number | |
29 | + copyNum: number | |
30 | + wheel: boolean | |
31 | + singleLine: boolean | |
32 | +} | |
33 | + | |
34 | +function useExpose(apis: Record<string, any>) { | |
35 | + const instance = getCurrentInstance() | |
36 | + if (instance) | |
37 | + Object.assign(instance.proxy as Object, apis) | |
38 | +} | |
39 | + | |
40 | +const Props = { | |
41 | + // 是否开启自动滚动 | |
42 | + modelValue: { | |
43 | + type: Boolean, | |
44 | + default: true, | |
45 | + }, | |
46 | + // 原始数据列表 | |
47 | + list: { | |
48 | + type: Array, | |
49 | + required: true, | |
50 | + default: [], | |
51 | + }, | |
52 | + // 步进速度,step 需是单步大小的约数 | |
53 | + step: { | |
54 | + type: Number, | |
55 | + default: 1, | |
56 | + }, | |
57 | + // 开启滚动的数据量 | |
58 | + limitScrollNum: { | |
59 | + type: Number, | |
60 | + default: 3, | |
61 | + }, | |
62 | + // 是否开启鼠标悬停 | |
63 | + hover: { | |
64 | + type: Boolean, | |
65 | + default: false, | |
66 | + }, | |
67 | + // 控制滚动方向 | |
68 | + direction: { | |
69 | + type: String, | |
70 | + default: 'up', | |
71 | + }, | |
72 | + // 单步运动停止的高度 | |
73 | + singleHeight: { | |
74 | + type: Number, | |
75 | + default: 0, | |
76 | + }, | |
77 | + // 单步运动停止的宽度 | |
78 | + singleWidth: { | |
79 | + type: Number, | |
80 | + default: 0, | |
81 | + }, | |
82 | + // 单步停止等待时间 (默认值 1000ms) | |
83 | + singleWaitTime: { | |
84 | + type: Number, | |
85 | + default: 1000, | |
86 | + }, | |
87 | + // 是否开启 rem 度量 | |
88 | + isRemUnit: { | |
89 | + type: Boolean, | |
90 | + default: false, | |
91 | + }, | |
92 | + // 开启数据更新监听 | |
93 | + isWatch: { | |
94 | + type: Boolean, | |
95 | + default: true, | |
96 | + }, | |
97 | + // 动画时间 | |
98 | + delay: { | |
99 | + type: Number, | |
100 | + default: 0, | |
101 | + }, | |
102 | + // 动画方式 | |
103 | + ease: { | |
104 | + type: [String, Object], | |
105 | + default: 'ease-in', | |
106 | + }, | |
107 | + // 动画循环次数,-1 表示一直动画 | |
108 | + count: { | |
109 | + type: Number, | |
110 | + default: -1, | |
111 | + }, | |
112 | + // 拷贝几份滚动列表 | |
113 | + copyNum: { | |
114 | + type: Number, | |
115 | + default: 1, | |
116 | + }, | |
117 | + // 开启鼠标悬停时支持滚轮滚动 | |
118 | + wheel: { | |
119 | + type: Boolean, | |
120 | + default: false, | |
121 | + }, | |
122 | + // 启用单行滚动 | |
123 | + singleLine: { | |
124 | + type: Boolean, | |
125 | + default: false, | |
126 | + }, | |
127 | +} | |
128 | + | |
129 | +globalThis.window.cancelAnimationFrame = (function () { | |
130 | + return ( | |
131 | + globalThis.window.cancelAnimationFrame | |
132 | + || function (id) { | |
133 | + return globalThis.window.clearTimeout(id) | |
134 | + } | |
135 | + ) | |
136 | +})() | |
137 | +globalThis.window.requestAnimationFrame = (function () { | |
138 | + return ( | |
139 | + globalThis.window.requestAnimationFrame | |
140 | + || function (callback) { | |
141 | + return globalThis.window.setTimeout(callback, 1000 / 60) | |
142 | + } | |
143 | + ) | |
144 | +})() | |
145 | + | |
146 | +function dataWarm(list: any[]) { | |
147 | + if (list && typeof list !== 'boolean' && list.length > 100) { | |
148 | + console.warn( | |
149 | + `数据达到了${list.length}条有点多哦~,可能会造成部分老旧浏览器卡顿。`, | |
150 | + ) | |
151 | + } | |
152 | +} | |
153 | + | |
154 | +const ScrollList = defineComponent({ | |
155 | + name: 'ScrollList', | |
156 | + inheritAttrs: false, | |
157 | + props: Props, | |
158 | + emits: ['stop', 'count', 'move'], | |
159 | + setup(_props, { slots, emit, attrs }) { | |
160 | + const props = _props as unknown as PropsType | |
161 | + const scrollRef = ref(null) | |
162 | + const slotListRef = ref<HTMLDivElement | null>(null) | |
163 | + const realBoxRef = ref<HTMLDivElement | null>(null) | |
164 | + const reqFrame = ref<number | null>(null) | |
165 | + const singleWaitTimeout = ref<NodeJS.Timeout | null>(null) | |
166 | + const realBoxWidth = ref(0) | |
167 | + const realBoxHeight = ref(0) | |
168 | + const xPos = ref(0) | |
169 | + const yPos = ref(0) | |
170 | + const isHover = ref(false) | |
171 | + const _count = ref(0) | |
172 | + | |
173 | + const isScroll = computed(() => props.list ? (props.list.length >= props.limitScrollNum) : false) | |
174 | + | |
175 | + const realBoxStyle = computed(() => { | |
176 | + return { | |
177 | + width: realBoxWidth.value ? `${realBoxWidth.value}px` : 'auto', | |
178 | + transform: `translate(${xPos.value}px,${yPos.value}px)`, | |
179 | + | |
180 | + transition: `all ${typeof props.ease === 'string' | |
181 | + ? props.ease | |
182 | + : `cubic-bezier(${ | |
183 | + props.ease.x1 | |
184 | + },${ | |
185 | + props.ease.y1 | |
186 | + },${ | |
187 | + props.ease.x2 | |
188 | + },${ | |
189 | + props.ease.y2 | |
190 | + })` | |
191 | + } ${props.delay}ms`, | |
192 | + overflow: 'hidden', | |
193 | + display: props.singleLine ? 'flex' : 'block', | |
194 | + } | |
195 | + }) | |
196 | + | |
197 | + const isHorizontal = computed( | |
198 | + () => props.direction === 'left' || props.direction === 'right', | |
199 | + ) | |
200 | + | |
201 | + const floatStyle = computed<CSSProperties>(() => { | |
202 | + return isHorizontal.value | |
203 | + ? { | |
204 | + float: 'left', | |
205 | + overflow: 'hidden', | |
206 | + display: props.singleLine ? 'flex' : 'block', | |
207 | + flexShrink: props.singleLine ? 0 : 1, | |
208 | + } | |
209 | + : { overflow: 'hidden' } | |
210 | + }) | |
211 | + | |
212 | + const baseFontSize = computed(() => { | |
213 | + return props.isRemUnit | |
214 | + ? parseInt( | |
215 | + globalThis.window.getComputedStyle( | |
216 | + globalThis.document.documentElement, | |
217 | + null, | |
218 | + ).fontSize, | |
219 | + ) | |
220 | + : 1 | |
221 | + }) | |
222 | + | |
223 | + const realSingleStopWidth = computed( | |
224 | + () => props.singleWidth * baseFontSize.value, | |
225 | + ) | |
226 | + | |
227 | + const realSingleStopHeight = computed( | |
228 | + () => props.singleHeight * baseFontSize.value, | |
229 | + ) | |
230 | + | |
231 | + const step = computed(() => { | |
232 | + let singleStep: number | |
233 | + const _step = props.step | |
234 | + if (isHorizontal.value) | |
235 | + singleStep = realSingleStopWidth.value | |
236 | + | |
237 | + else | |
238 | + singleStep = realSingleStopHeight.value | |
239 | + | |
240 | + if (singleStep > 0 && singleStep % _step > 0) { | |
241 | + console.error( | |
242 | + '如果设置了单步滚动, step 需是单步大小的约数,否则无法保证单步滚动结束的位置是否准确。~~~~~', | |
243 | + ) | |
244 | + } | |
245 | + return _step | |
246 | + }) | |
247 | + | |
248 | + const cancel = () => { | |
249 | + cancelAnimationFrame(reqFrame.value as number) | |
250 | + reqFrame.value = null | |
251 | + } | |
252 | + | |
253 | + const animation = ( | |
254 | + _direction: 'up' | 'down' | 'left' | 'right', | |
255 | + _step: number, | |
256 | + isWheel?: boolean, | |
257 | + ) => { | |
258 | + reqFrame.value = requestAnimationFrame(() => { | |
259 | + const h = realBoxHeight.value / 2 | |
260 | + const w = realBoxWidth.value / 2 | |
261 | + if (_direction === 'up') { | |
262 | + if (Math.abs(yPos.value) >= h) { | |
263 | + yPos.value = 0 | |
264 | + _count.value += 1 | |
265 | + emit('count', _count.value) | |
266 | + } | |
267 | + yPos.value -= _step | |
268 | + } | |
269 | + else if (_direction === 'down') { | |
270 | + if (yPos.value >= 0) { | |
271 | + yPos.value = h * -1 | |
272 | + _count.value += 1 | |
273 | + emit('count', _count.value) | |
274 | + } | |
275 | + yPos.value += _step | |
276 | + } | |
277 | + else if (_direction === 'left') { | |
278 | + if (Math.abs(xPos.value) >= w) { | |
279 | + xPos.value = 0 | |
280 | + _count.value += 1 | |
281 | + emit('count', _count.value) | |
282 | + } | |
283 | + xPos.value -= _step | |
284 | + } | |
285 | + else if (_direction === 'right') { | |
286 | + if (xPos.value >= 0) { | |
287 | + xPos.value = w * -1 | |
288 | + _count.value += 1 | |
289 | + emit('count', _count.value) | |
290 | + } | |
291 | + xPos.value += _step | |
292 | + } | |
293 | + if (isWheel) | |
294 | + return | |
295 | + | |
296 | + const { singleWaitTime } = props | |
297 | + if (singleWaitTimeout.value) | |
298 | + clearTimeout(singleWaitTimeout.value) | |
299 | + | |
300 | + if (realSingleStopHeight.value) { | |
301 | + if (Math.abs(yPos.value) % realSingleStopHeight.value < _step) { | |
302 | + singleWaitTimeout.value = setTimeout(() => { | |
303 | + move() | |
304 | + }, singleWaitTime) | |
305 | + } | |
306 | + else { | |
307 | + move() | |
308 | + } | |
309 | + } | |
310 | + else if (realSingleStopWidth.value) { | |
311 | + if (Math.abs(xPos.value) % realSingleStopWidth.value < _step) { | |
312 | + singleWaitTimeout.value = setTimeout(() => { | |
313 | + move() | |
314 | + }, singleWaitTime) | |
315 | + } | |
316 | + else { | |
317 | + move() | |
318 | + } | |
319 | + } | |
320 | + else { | |
321 | + move() | |
322 | + } | |
323 | + }) | |
324 | + } | |
325 | + | |
326 | + function move() { | |
327 | + cancel() | |
328 | + if (isHover.value || !isScroll.value || _count.value === props.count) { | |
329 | + emit('stop', _count.value) | |
330 | + _count.value = 0 | |
331 | + return | |
332 | + } | |
333 | + animation( | |
334 | + props.direction as 'up' | 'down' | 'left' | 'right', | |
335 | + step.value, | |
336 | + false, | |
337 | + ) | |
338 | + } | |
339 | + | |
340 | + const initMove = () => { | |
341 | + dataWarm(props.list) | |
342 | + if (isHorizontal.value) { | |
343 | + let slotListWidth = (slotListRef.value as HTMLDivElement).offsetWidth | |
344 | + slotListWidth = slotListWidth * 2 + 1 | |
345 | + realBoxWidth.value = slotListWidth | |
346 | + } | |
347 | + | |
348 | + if (isScroll.value) { | |
349 | + realBoxHeight.value = (realBoxRef.value as HTMLDivElement).offsetHeight | |
350 | + if (props.modelValue) | |
351 | + move() | |
352 | + } | |
353 | + else { | |
354 | + cancel() | |
355 | + yPos.value = xPos.value = 0 | |
356 | + } | |
357 | + } | |
358 | + | |
359 | + const startMove = () => { | |
360 | + isHover.value = false | |
361 | + move() | |
362 | + } | |
363 | + | |
364 | + const stopMove = () => { | |
365 | + isHover.value = true | |
366 | + if (singleWaitTimeout.value) | |
367 | + clearTimeout(singleWaitTimeout.value) | |
368 | + | |
369 | + cancel() | |
370 | + } | |
371 | + | |
372 | + const hoverStop = computed( | |
373 | + () => props.hover && props.modelValue && isScroll.value, | |
374 | + ) | |
375 | + | |
376 | + const throttleFunc = useThrottleFn((e: WheelEvent) => { | |
377 | + cancel() | |
378 | + const singleHeight = realSingleStopHeight.value | |
379 | + ? realSingleStopHeight.value | |
380 | + : 15 | |
381 | + if (e.deltaY < 0) | |
382 | + animation('down', singleHeight, true) | |
383 | + | |
384 | + if (e.deltaY > 0) | |
385 | + animation('up', singleHeight, true) | |
386 | + }, 30) | |
387 | + | |
388 | + const onWheel = (e: WheelEvent) => { | |
389 | + throttleFunc(e) | |
390 | + } | |
391 | + | |
392 | + const reset = () => { | |
393 | + cancel() | |
394 | + isHover.value = false | |
395 | + initMove() | |
396 | + } | |
397 | + | |
398 | + const Reset = () => { | |
399 | + reset() | |
400 | + } | |
401 | + | |
402 | + useExpose({ Reset }) | |
403 | + | |
404 | + watch( | |
405 | + () => props.list, | |
406 | + () => { | |
407 | + if (props.isWatch) { | |
408 | + nextTick(() => { | |
409 | + reset() | |
410 | + }) | |
411 | + } | |
412 | + }, | |
413 | + { | |
414 | + deep: true, | |
415 | + }, | |
416 | + ) | |
417 | + | |
418 | + watch( | |
419 | + () => props.modelValue, | |
420 | + (newValue) => { | |
421 | + if (newValue) | |
422 | + startMove() | |
423 | + | |
424 | + else | |
425 | + stopMove() | |
426 | + }, | |
427 | + ) | |
428 | + | |
429 | + watch( | |
430 | + () => props.count, | |
431 | + (newValue) => { | |
432 | + if (newValue !== 0) | |
433 | + startMove() | |
434 | + }, | |
435 | + ) | |
436 | + | |
437 | + onBeforeMount(() => { | |
438 | + cancel() | |
439 | + clearTimeout(singleWaitTimeout.value as unknown as number) | |
440 | + }) | |
441 | + | |
442 | + onMounted(() => { | |
443 | + if (isScroll.value) | |
444 | + initMove() | |
445 | + }) | |
446 | + | |
447 | + const { default: $default, html } = slots | |
448 | + const copyNum = new Array(props.copyNum).fill(null) | |
449 | + | |
450 | + const getHtml = () => { | |
451 | + return ( | |
452 | + <> | |
453 | + <div ref={slotListRef} style={floatStyle.value}> | |
454 | + {$default && $default()} | |
455 | + </div> | |
456 | + {isScroll.value | |
457 | + ? copyNum.map(() => { | |
458 | + if (html && typeof html === 'function') | |
459 | + return <div style={floatStyle.value}>{html()}</div> | |
460 | + | |
461 | + else | |
462 | + return <div style={floatStyle.value}>{$default && $default()}</div> | |
463 | + }) | |
464 | + : null} | |
465 | + </> | |
466 | + ) | |
467 | + } | |
468 | + | |
469 | + return () => ( | |
470 | + <div ref={scrollRef} class={attrs.class}> | |
471 | + {props.wheel && props.hover | |
472 | + ? ( | |
473 | + <div | |
474 | + ref={realBoxRef} | |
475 | + style={realBoxStyle.value} | |
476 | + onMouseenter={() => { | |
477 | + if (hoverStop.value) | |
478 | + stopMove() | |
479 | + }} | |
480 | + onMouseleave={() => { | |
481 | + if (hoverStop.value) | |
482 | + startMove() | |
483 | + }} | |
484 | + onWheel={(e) => { | |
485 | + if (hoverStop.value) | |
486 | + onWheel(e) | |
487 | + }} | |
488 | + > | |
489 | + {getHtml()} | |
490 | + </div> | |
491 | + ) | |
492 | + : ( | |
493 | + <div | |
494 | + ref={realBoxRef} | |
495 | + style={realBoxStyle.value} | |
496 | + onMouseenter={() => { | |
497 | + if (hoverStop.value) | |
498 | + stopMove() | |
499 | + }} | |
500 | + onMouseleave={() => { | |
501 | + if (hoverStop.value) | |
502 | + startMove() | |
503 | + }} | |
504 | + > | |
505 | + {getHtml()} | |
506 | + </div> | |
507 | + )} | |
508 | + </div> | |
509 | + ) | |
510 | + }, | |
511 | +}) | |
512 | + | |
513 | +export default ScrollList | |
514 | + | |
515 | +export { ScrollList } | ... | ... |
... | ... | @@ -8,7 +8,7 @@ import { ComponentEnum } from '@/components/Form/src/enum' |
8 | 8 | import { useContentDataStoreWithOut } from '@/store/modules/contentData' |
9 | 9 | import { DateFormatEnum } from '@/enums/timeEnum' |
10 | 10 | import type { BasicColumn } from '@/components/Table' |
11 | -import type { CodeTypeEnum, ContentDataFieldsEnum } from '@/enums/datasource' | |
11 | +import { AlarmStatusEnum, type CodeTypeEnum, type ContentDataFieldsEnum } from '@/enums/datasource' | |
12 | 12 | |
13 | 13 | const contentDataStore = useContentDataStoreWithOut() |
14 | 14 | |
... | ... | @@ -31,37 +31,12 @@ export interface TableRecordItemType { |
31 | 31 | [ContentDataFieldsEnum.CODE_TYPE]?: Nullable<CodeTypeEnum> |
32 | 32 | } |
33 | 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 | |
34 | +export const AlarmColorMap = { | |
35 | + [AlarmStatusEnum.CLEARED_UN_ACK]: 'red', | |
36 | + [AlarmStatusEnum.ACTIVE_UN_ACK]: 'orange', | |
37 | + [AlarmStatusEnum.CLEARED_ACK]: 'cyan', | |
38 | + [AlarmStatusEnum.ACTIVE_ACK]: 'green', | |
63 | 39 | } |
64 | - | |
65 | 40 | /** |
66 | 41 | * 告警列表相关枚举 |
67 | 42 | */ | ... | ... |
1 | 1 | <script setup lang="ts"> |
2 | 2 | import { computed, nextTick, onMounted, reactive, unref } from 'vue' |
3 | 3 | import { Divider, Tag } from 'ant-design-vue' |
4 | -import Vue3SeamlessScroll from 'vue3-seamless-scroll/package/Vue3SeamlessScroll' | |
5 | -import { useAlarmList } from './useAlarmList.hook' | |
6 | -import { type alarmListInterface, alarmStatus } from './form.config' | |
4 | +import { ScrollList } from './ScrollList' | |
7 | 5 | import { fetchAlarmList } from '@/api/alarm' |
6 | +import type { AlarmListItemType } from '@/api/alarm/model' | |
8 | 7 | import type { CreateComponentType } from '@/core/Library/types' |
9 | 8 | import { useContentDataStore } from '@/store/modules/contentData' |
10 | 9 | import { isLightboxMode } from '@/utils/env' |
10 | +import { AlarmStatusColorEnum, AlarmStatusEnum, AlarmStatusNameEnum } from '@/enums/datasource' | |
11 | 11 | import { formatToDateTime } from '@/utils/dateUtil' |
12 | 12 | |
13 | 13 | const props = defineProps<{ |
... | ... | @@ -20,10 +20,8 @@ const getCellBounds = computed( |
20 | 20 | |
21 | 21 | const contentDataStore = useContentDataStore() |
22 | 22 | |
23 | -const { byStatusFindLabel } = useAlarmList() | |
24 | - | |
25 | 23 | const initOptions = reactive<{ |
26 | - alarmList: alarmListInterface[] | |
24 | + alarmList: AlarmListItemType[] | |
27 | 25 | scroll: boolean |
28 | 26 | interval: number |
29 | 27 | polling: number |
... | ... | @@ -72,6 +70,7 @@ onMounted(async () => { |
72 | 70 | setInterval(initFetchAlarmList, initOptions.polling * 1000) |
73 | 71 | } |
74 | 72 | else { |
73 | + const statusList = Object.values(AlarmStatusEnum) | |
75 | 74 | Object.assign(initOptions, { |
76 | 75 | scroll: false, |
77 | 76 | interval: 0, |
... | ... | @@ -80,9 +79,7 @@ onMounted(async () => { |
80 | 79 | deviceName: `示例设备${index + 1}`, |
81 | 80 | deviceAlias: `示例设备${index + 1}`, |
82 | 81 | startTs: formatToDateTime(), |
83 | - status: alarmStatus.map(item => item.value)[ | |
84 | - Math.floor(Math.random() * alarmStatus.length) | |
85 | - ], | |
82 | + status: statusList[index % 4], | |
86 | 83 | })), |
87 | 84 | }) |
88 | 85 | } |
... | ... | @@ -91,26 +88,28 @@ onMounted(async () => { |
91 | 88 | |
92 | 89 | <template> |
93 | 90 | <div class="seamless-scroll w-full h-full flex justify-center items-center overflow-y-scroll"> |
94 | - <Vue3SeamlessScroll | |
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="{ | |
91 | + <ScrollList | |
92 | + v-model="initOptions.scroll" :single-wait-time="initOptions.interval" :list="initOptions.alarmList" | |
93 | + :limit-scroll-num="10" :is-rem-unit="true" :delay="10" :wheel="true" hover :style="{ | |
97 | 94 | width: `${getCellBounds.width}px`, |
98 | 95 | height: `${getCellBounds.height}px`, |
99 | 96 | }" |
100 | 97 | > |
101 | 98 | <div v-for="(item, index) in initOptions.alarmList" :key="index" class="flex flex-col items-start h-15 px-2"> |
102 | 99 | <p class="text-xs"> |
103 | - 设备:{{ item.deviceAlias || item.deviceName }} | |
100 | + <span>设备:</span> | |
101 | + <span class="ml-1">{{ item.deviceAlias || item.deviceName }}</span> | |
104 | 102 | </p> |
105 | - <div class="flex items-center justify-between -mt-2"> | |
106 | - <span class="text-xs">时间:{{ item.startTs }}</span> | |
107 | - <Tag class="ml-2 text-xs" :color="byStatusFindLabel(item.status, 'color')"> | |
108 | - {{ byStatusFindLabel(item.status, "") }} | |
103 | + <div class="flex items-center justify-between -mt-2 text-xs"> | |
104 | + <span>时间:</span> | |
105 | + <span class="ml-1">{{ item.startTs }}</span> | |
106 | + <Tag class="ml-2" :color="AlarmStatusColorEnum[item.status]"> | |
107 | + {{ AlarmStatusNameEnum[item.status] }} | |
109 | 108 | </Tag> |
110 | 109 | </div> |
111 | 110 | <Divider class="mt-2 divider" /> |
112 | 111 | </div> |
113 | - </Vue3SeamlessScroll> | |
112 | + </ScrollList> | |
114 | 113 | </div> |
115 | 114 | </template> |
116 | 115 | ... | ... |
src/core/Library/packages/Basic/AlarmList/useAlarmList.hook.ts
deleted
100644 → 0
1 | -import { alarmStatus } from './form.config' | |
2 | - | |
3 | -export const useAlarmList = () => { | |
4 | - // 映射label | |
5 | - const byStatusFindLabel = (status: string, color: string) => { | |
6 | - if (!color) return alarmStatus.find(item => item.value === status)?.label | |
7 | - return alarmStatus.find(item => item.value === status)?.color | |
8 | - } | |
9 | - return { | |
10 | - byStatusFindLabel, | |
11 | - } | |
12 | -} |
... | ... | @@ -335,3 +335,25 @@ export enum SocketSubscriberEnum { |
335 | 335 | TS_SUB_CMDS = 'tsSubCmds', |
336 | 336 | HISTORY_CMDS = 'historyCmds', |
337 | 337 | } |
338 | + | |
339 | +export enum AlarmStatusEnum { | |
340 | + CLEARED_UN_ACK = 'CLEARED_UNACK', | |
341 | + ACTIVE_UN_ACK = 'ACTIVE_UNACK', | |
342 | + CLEARED_ACK = 'CLEARED_ACK', | |
343 | + ACTIVE_ACK = 'ACTIVE_ACK', | |
344 | +} | |
345 | + | |
346 | +export enum AlarmStatusColorEnum { | |
347 | + CLEARED_UNACK = 'red', | |
348 | + ACTIVE_UNACK = 'orange', | |
349 | + CLEARED_ACK = 'cyan', | |
350 | + ACTIVE_ACK = 'green', | |
351 | +} | |
352 | + | |
353 | +export enum AlarmStatusNameEnum { | |
354 | + CLEARED_UNACK = '清除未确认', | |
355 | + ACTIVE_UNACK = '激活未确认', | |
356 | + CLEARED_ACK = '清除已确认', | |
357 | + ACTIVE_ACK = '激活已确认', | |
358 | +} | |
359 | + | ... | ... |
... | ... | @@ -18,6 +18,39 @@ export type MxState = mxgraph.mxCellState |
18 | 18 | |
19 | 19 | export type MxEditor = mxgraph.mxEditor |
20 | 20 | |
21 | +export enum EnableEnum { | |
22 | + ENABLE = 1, | |
23 | + CLOSE = 0, | |
24 | +} | |
25 | + | |
26 | +export enum GradientDirectionEnum { | |
27 | + WEST = 'west', | |
28 | + NORTH = 'north', | |
29 | + EAST = 'east', | |
30 | + SOUTH = 'south', | |
31 | + RADIAL = 'radial', | |
32 | +} | |
33 | + | |
34 | +export interface MxShapeStyleType { | |
35 | + align: 'center' | |
36 | + dashed: EnableEnum | |
37 | + fillColor: string | |
38 | + fontColor: string | |
39 | + fontFamily: string | |
40 | + fontSize: number | |
41 | + gradientColor: string | |
42 | + gradientDirection: GradientDirectionEnum | |
43 | + opacity: number | |
44 | + shadow: EnableEnum | |
45 | + strokeColor: string | |
46 | + // fillStyle: | |
47 | + /** | |
48 | + * @description 草图模式 | |
49 | + */ | |
50 | + sketch: EnableEnum | |
51 | + strokeWidth: number | |
52 | +} | |
53 | + | |
21 | 54 | interface Entries { |
22 | 55 | title: string |
23 | 56 | key?: string | ... | ... |