Showing
31 changed files
with
1417 additions
and
189 deletions
... | ... | @@ -6,6 +6,7 @@ import { RuleChainType } from '/@/views/rule/designer/types/ruleNode'; |
6 | 6 | enum Api { |
7 | 7 | SAVE = '/ruleChain/metadata', |
8 | 8 | GET_RULE_CHAINES = '/ruleChains', |
9 | + GET_RULE_NODE_EVENTS = '/events/RULE_NODE', | |
9 | 10 | } |
10 | 11 | |
11 | 12 | export const getRuleChainData = (id: string) => { |
... | ... | @@ -38,3 +39,18 @@ export const getRuleChains = (params: Recordable) => { |
38 | 39 | } |
39 | 40 | ); |
40 | 41 | }; |
42 | + | |
43 | +export const getRuleNodeEventList = ( | |
44 | + ruleNodeId: string, | |
45 | + params: Recordable, | |
46 | + data: Recordable & Record<'eventType', string> | |
47 | +) => { | |
48 | + return defHttp.post<TBPaginationResult>( | |
49 | + { | |
50 | + url: `${Api.GET_RULE_NODE_EVENTS}/${ruleNodeId}`, | |
51 | + params, | |
52 | + data, | |
53 | + }, | |
54 | + { joinPrefix: false } | |
55 | + ); | |
56 | +}; | ... | ... |
... | ... | @@ -10,6 +10,11 @@ interface OptionsType { |
10 | 10 | type: ElementsTypeEnum; |
11 | 11 | } |
12 | 12 | |
13 | +export interface ElementInfo { | |
14 | + id: string; | |
15 | + type: ElementsTypeEnum; | |
16 | +} | |
17 | + | |
13 | 18 | export function useAwaitPopupWindowBindData( |
14 | 19 | options: OptionsType = { mode: DataActionModeEnum.CREATE, type: ElementsTypeEnum.NODE } |
15 | 20 | ) { |
... | ... | @@ -29,6 +34,8 @@ export function useAwaitPopupWindowBindData( |
29 | 34 | |
30 | 35 | const shadowComponent = shallowRef<Nullable<Component>>(); |
31 | 36 | |
37 | + const elementInfo = ref<ElementInfo>(); | |
38 | + | |
32 | 39 | const getNodeSetValue = computed(() => { |
33 | 40 | return unref(mode) === DataActionModeEnum.CREATE |
34 | 41 | ? unref(nodeData)?.config?.configurationDescriptor.nodeDefinition.defaultConfiguration |
... | ... | @@ -68,8 +75,10 @@ export function useAwaitPopupWindowBindData( |
68 | 75 | |
69 | 76 | const open = async ( |
70 | 77 | nodeData: NodeData, |
71 | - edgeData?: EdgeData | |
78 | + edgeData?: EdgeData, | |
79 | + _elementInfo?: ElementInfo | |
72 | 80 | ): Promise<AwaitPopupWindowReturnDataType> => { |
81 | + elementInfo.value = _elementInfo; | |
73 | 82 | await handleFetchComponent(nodeData, edgeData); |
74 | 83 | return new Promise((_resolve) => { |
75 | 84 | visible.value = true; |
... | ... | @@ -113,6 +122,7 @@ export function useAwaitPopupWindowBindData( |
113 | 122 | visible, |
114 | 123 | nodeData, |
115 | 124 | spinning, |
125 | + elementInfo, | |
116 | 126 | shadowComponent, |
117 | 127 | createComponentEl, |
118 | 128 | getComponentKey, | ... | ... |
... | ... | @@ -10,7 +10,7 @@ import type { Ref } from 'vue'; |
10 | 10 | import { markRaw, toRaw, unref } from 'vue'; |
11 | 11 | import { isFunction } from 'lodash-es'; |
12 | 12 | import type { CreateNodeModal } from '../src/components/CreateNodeModal'; |
13 | -import { EdgeTypeEnum, NodeTypeEnum } from '../enum'; | |
13 | +import { EdgeTypeEnum, ElementsTypeEnum, NodeTypeEnum } from '../enum'; | |
14 | 14 | import { BasicEdge, BasicNode } from '../src/components'; |
15 | 15 | import type { EdgeData, NodeData } from '../types/node'; |
16 | 16 | import type { CreateEdgeModal } from '../src/components/CreateEdgeModal'; |
... | ... | @@ -126,10 +126,11 @@ export function useRuleFlow(options: UseRuleFlowOptionsType) { |
126 | 126 | |
127 | 127 | onNodeDoubleClick(async ({ node }) => { |
128 | 128 | if ((node.data as NodeData).config?.disableAction) return; |
129 | - | |
130 | 129 | const { flag, data } = |
131 | 130 | (await unref(updateNodeDrawerActionType)?.open( |
132 | - toRaw((node as NodeData)?.data as unknown as NodeData) | |
131 | + toRaw((node as NodeData)?.data as unknown as NodeData), | |
132 | + void 0, | |
133 | + { id: node.id, type: ElementsTypeEnum.NODE } | |
133 | 134 | )) || {}; |
134 | 135 | |
135 | 136 | if (!flag) return; |
... | ... | @@ -146,7 +147,8 @@ export function useRuleFlow(options: UseRuleFlowOptionsType) { |
146 | 147 | const { flag, data } = |
147 | 148 | (await unref(updateEdgeDrawerActionType)?.open( |
148 | 149 | toRaw(unref(edge.sourceNode?.data as unknown as NodeData)), |
149 | - toRaw(unref(edge.data as EdgeData)) | |
150 | + toRaw(unref(edge.data as EdgeData)), | |
151 | + { id: edge.id, type: ElementsTypeEnum.EDGE } | |
150 | 152 | )) || {}; |
151 | 153 | |
152 | 154 | if (!flag) return; | ... | ... |
1 | 1 | <script setup lang="ts"> |
2 | + import { Spin } from 'ant-design-vue'; | |
2 | 3 | import { Background, BackgroundVariant } from '@vue-flow/background'; |
3 | 4 | import { Controls } from '@vue-flow/controls'; |
4 | 5 | import { Panel, PanelPosition, VueFlow } from '@vue-flow/core'; |
... | ... | @@ -34,6 +35,7 @@ |
34 | 35 | const elements = ref([]); |
35 | 36 | |
36 | 37 | const { |
38 | + loading, | |
37 | 39 | changeMarker, |
38 | 40 | getCurrentPageMetaData, |
39 | 41 | triggerChange, |
... | ... | @@ -88,66 +90,68 @@ |
88 | 90 | <main ref="rootElRef" class="w-full h-full flex relative" @drop="handleOnDrop"> |
89 | 91 | <Sidebar /> |
90 | 92 | |
91 | - <VueFlow | |
92 | - :id="getId" | |
93 | - ref="flowElRef" | |
94 | - v-model="elements" | |
95 | - class="w-full h-full" | |
96 | - @dragover="handleOnDragOver" | |
97 | - > | |
98 | - <template #connection-line="props"> | |
99 | - <BasicConnectionLine v-bind="props" /> | |
100 | - </template> | |
101 | - <template #edge-custom="props"> | |
102 | - <BasicEdge v-bind="props" /> | |
103 | - </template> | |
104 | - | |
105 | - <BasicConnectionArrow /> | |
106 | - | |
107 | - <Background :variant="BackgroundVariant.Lines" :gap="25" pattern-color="#cfcfcf" /> | |
108 | - | |
109 | - <Controls :position="PanelPosition.BottomLeft" /> | |
110 | - | |
111 | - <Panel position="bottom-right" class="controls"> | |
112 | - <section class="flex gap-4"> | |
113 | - <button | |
114 | - :style="{ transform: `translateY(${getDeleteDisplayState ? 0 : '72px'})` }" | |
115 | - class="button-box-shadow w-14 h-14 flex justify-center items-center bg-orange-600 rounded-full transition-transform transform" | |
116 | - @click="handleDeleteSelectionElements" | |
117 | - > | |
118 | - <Icon class="!text-3xl !text-light-50" icon="mdi:delete" /> | |
119 | - </button> | |
120 | - <button | |
121 | - class="button-box-shadow w-14 h-14 flex justify-center items-center bg-gray-400 rounded-full opacity-50" | |
122 | - > | |
123 | - <Icon class="!text-3xl !text-light-50" icon="carbon:debug" /> | |
124 | - </button> | |
125 | - <button | |
126 | - :class="changeMarker ? '!bg-orange-600 !opacity-100' : 'opacity-50'" | |
127 | - class="button-box-shadow w-14 h-14 flex justify-center items-center bg-gray-400 rounded-full" | |
128 | - @click="handleApplyChange(flowActionType)" | |
129 | - > | |
130 | - <Icon class="!text-3xl !text-light-50" icon="mdi:tick" /> | |
131 | - </button> | |
93 | + <Spin :spinning="loading" wrapperClassName="w-full h-ful rule-chain-designer-loading-container"> | |
94 | + <VueFlow | |
95 | + :id="getId" | |
96 | + ref="flowElRef" | |
97 | + v-model="elements" | |
98 | + class="w-full h-full" | |
99 | + @dragover="handleOnDragOver" | |
100 | + > | |
101 | + <template #connection-line="props"> | |
102 | + <BasicConnectionLine v-bind="props" /> | |
103 | + </template> | |
104 | + <template #edge-custom="props"> | |
105 | + <BasicEdge v-bind="props" /> | |
106 | + </template> | |
107 | + | |
108 | + <BasicConnectionArrow /> | |
109 | + | |
110 | + <Background :variant="BackgroundVariant.Lines" :gap="25" pattern-color="#cfcfcf" /> | |
111 | + | |
112 | + <Controls :position="PanelPosition.BottomLeft" /> | |
113 | + | |
114 | + <Panel position="bottom-right" class="controls"> | |
115 | + <section class="flex gap-4"> | |
116 | + <button | |
117 | + :style="{ transform: `translateY(${getDeleteDisplayState ? 0 : '72px'})` }" | |
118 | + class="button-box-shadow w-14 h-14 flex justify-center items-center bg-orange-600 rounded-full transition-transform transform" | |
119 | + @click="handleDeleteSelectionElements" | |
120 | + > | |
121 | + <Icon class="!text-3xl !text-light-50" icon="mdi:delete" /> | |
122 | + </button> | |
123 | + <button | |
124 | + class="button-box-shadow w-14 h-14 flex justify-center items-center bg-gray-400 rounded-full opacity-50" | |
125 | + > | |
126 | + <Icon class="!text-3xl !text-light-50" icon="carbon:debug" /> | |
127 | + </button> | |
128 | + <button | |
129 | + :class="changeMarker ? '!bg-orange-600 !opacity-100' : 'opacity-50'" | |
130 | + class="button-box-shadow w-14 h-14 flex justify-center items-center bg-gray-400 rounded-full" | |
131 | + @click="handleApplyChange(flowActionType)" | |
132 | + > | |
133 | + <Icon class="!text-3xl !text-light-50" icon="mdi:tick" /> | |
134 | + </button> | |
135 | + <button | |
136 | + :class="changeMarker ? '!bg-orange-600 !opacity-100' : 'opacity-50'" | |
137 | + class="button-box-shadow w-14 h-14 flex justify-center items-center bg-gray-400 rounded-full" | |
138 | + @click="handleRedoChange(flowActionType)" | |
139 | + > | |
140 | + <Icon class="!text-3xl !text-light-50" icon="ic:baseline-close" /> | |
141 | + </button> | |
142 | + </section> | |
143 | + </Panel> | |
144 | + | |
145 | + <Panel position="top-right"> | |
132 | 146 | <button |
133 | - :class="changeMarker ? '!bg-orange-600 !opacity-100' : 'opacity-50'" | |
134 | - class="button-box-shadow w-14 h-14 flex justify-center items-center bg-gray-400 rounded-full" | |
135 | - @click="handleRedoChange(flowActionType)" | |
147 | + class="w-10 h-10 bg-gray-300 flex justify-center items-center rounded-full dark:bg-dark-50" | |
148 | + @click="handleFullScreen" | |
136 | 149 | > |
137 | - <Icon class="!text-3xl !text-light-50" icon="ic:baseline-close" /> | |
150 | + <Icon class="!text-2xl dark:text-light-50" :icon="getFullScreenIcon" /> | |
138 | 151 | </button> |
139 | - </section> | |
140 | - </Panel> | |
141 | - | |
142 | - <Panel position="top-right"> | |
143 | - <button | |
144 | - class="w-10 h-10 bg-gray-300 flex justify-center items-center rounded-full dark:bg-dark-50" | |
145 | - @click="handleFullScreen" | |
146 | - > | |
147 | - <Icon class="!text-2xl dark:text-light-50" :icon="getFullScreenIcon" /> | |
148 | - </button> | |
149 | - </Panel> | |
150 | - </VueFlow> | |
152 | + </Panel> | |
153 | + </VueFlow> | |
154 | + </Spin> | |
151 | 155 | |
152 | 156 | <CreateNodeModal ref="createNodeModalActionType" :get-container="handleGetContainer" /> |
153 | 157 | <CreateEdgeModal ref="createEdgeModalActionType" :get-container="handleGetContainer" /> |
... | ... | @@ -162,3 +166,11 @@ |
162 | 166 | box-shadow: 0 3px 5px -1px #0003, 0 6px 10px 0 #00000024, 0 1px 18px 0 #0000001f; |
163 | 167 | } |
164 | 168 | </style> |
169 | + | |
170 | +<style lang="less"> | |
171 | + .rule-chain-designer-loading-container { | |
172 | + .ant-spin-container { | |
173 | + @apply w-full h-full; | |
174 | + } | |
175 | + } | |
176 | +</style> | ... | ... |
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | import { useConnectionFocus } from '../../../hook/useConnectionFocus'; |
7 | 7 | import { useFlowContext } from '../../../hook/useFlowContext'; |
8 | 8 | import { useTextWidth } from '../../../hook/useTextWidth'; |
9 | + import { ElementsTypeEnum } from '../../../enum'; | |
9 | 10 | |
10 | 11 | const props = defineProps<EdgeProps>(); |
11 | 12 | |
... | ... | @@ -31,7 +32,8 @@ |
31 | 32 | const { flag, data } = |
32 | 33 | (await unref(updateEdgeDrawerActionType)?.open( |
33 | 34 | toRaw(unref(props.sourceNode?.data as unknown as NodeData)), |
34 | - toRaw(unref(props.data as EdgeData)) | |
35 | + toRaw(unref(props.data as EdgeData)), | |
36 | + { id: props.id, type: ElementsTypeEnum.EDGE } | |
35 | 37 | )) || {}; |
36 | 38 | |
37 | 39 | if (!flag) return; | ... | ... |
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | import { computed, toRaw, unref } from 'vue'; |
6 | 6 | import { useFlowContext } from '../../../hook/useFlowContext'; |
7 | 7 | import type { NodeData } from '../../../types/node'; |
8 | + import { ElementsTypeEnum } from '../../../enum'; | |
8 | 9 | |
9 | 10 | const props = defineProps<NodeProps>(); |
10 | 11 | |
... | ... | @@ -14,7 +15,10 @@ |
14 | 15 | |
15 | 16 | const handleOpenEdit = async () => { |
16 | 17 | const { flag, data } = |
17 | - (await unref(updateNodeDrawerActionType)?.open(toRaw(unref(getData)))) || {}; | |
18 | + (await unref(updateNodeDrawerActionType)?.open(toRaw(unref(getData)), void 0, { | |
19 | + id: props.id, | |
20 | + type: ElementsTypeEnum.NODE, | |
21 | + })) || {}; | |
18 | 22 | |
19 | 23 | if (!flag) return; |
20 | 24 | ... | ... |
src/views/rule/designer/src/components/BasicEvents/DebugEvent.vue
deleted
100644 → 0
1 | -<script lang="ts" setup> | |
2 | - import { useTable, BasicTable } from '/@/components/Table'; | |
3 | - import { columns, formSchemas } from './debugEvent.config'; | |
4 | - | |
5 | - const [register] = useTable({ | |
6 | - columns, | |
7 | - showIndexColumn: false, | |
8 | - useSearchForm: true, | |
9 | - formConfig: { | |
10 | - layout: 'inline', | |
11 | - baseColProps: { | |
12 | - span: 12, | |
13 | - }, | |
14 | - labelWidth: 80, | |
15 | - schemas: formSchemas, | |
16 | - }, | |
17 | - }); | |
18 | -</script> | |
19 | - | |
20 | -<template> | |
21 | - <BasicTable @register="register" /> | |
22 | -</template> |
src/views/rule/designer/src/components/BasicEvents/debugEvent.config.ts
deleted
100644 → 0
1 | -import { BasicColumn, FormSchema } from '/@/components/Table'; | |
2 | - | |
3 | -export const columns: BasicColumn[] = [ | |
4 | - { | |
5 | - title: '事件时间', | |
6 | - dataIndex: '', | |
7 | - }, | |
8 | - { | |
9 | - title: '服务器', | |
10 | - dataIndex: '', | |
11 | - }, | |
12 | - { | |
13 | - title: '类型', | |
14 | - dataIndex: '', | |
15 | - }, | |
16 | - { | |
17 | - title: '实体类型', | |
18 | - dataIndex: '', | |
19 | - }, | |
20 | - { | |
21 | - title: '消息ID', | |
22 | - dataIndex: '', | |
23 | - }, | |
24 | - { | |
25 | - title: '消息类型', | |
26 | - dataIndex: '', | |
27 | - }, | |
28 | - { | |
29 | - title: '关联类型', | |
30 | - dataIndex: '', | |
31 | - }, | |
32 | - { | |
33 | - title: '数据', | |
34 | - dataIndex: '', | |
35 | - }, | |
36 | - { | |
37 | - title: '原数据', | |
38 | - dataIndex: '', | |
39 | - }, | |
40 | - { | |
41 | - title: '错误', | |
42 | - dataIndex: '', | |
43 | - }, | |
44 | -]; | |
45 | - | |
46 | -export const formSchemas: FormSchema[] = [ | |
47 | - { | |
48 | - field: '', | |
49 | - label: '服务器', | |
50 | - component: 'Input', | |
51 | - }, | |
52 | - { | |
53 | - field: '', | |
54 | - label: '类型', | |
55 | - component: 'Select', | |
56 | - }, | |
57 | - { | |
58 | - field: '', | |
59 | - label: '实体ID', | |
60 | - component: 'Input', | |
61 | - }, | |
62 | - { | |
63 | - field: '', | |
64 | - label: '实体类型', | |
65 | - component: 'Select', | |
66 | - }, | |
67 | - { | |
68 | - field: '', | |
69 | - label: '消息类型', | |
70 | - component: 'Input', | |
71 | - }, | |
72 | - { | |
73 | - field: '', | |
74 | - label: '关联类型', | |
75 | - component: 'Input', | |
76 | - }, | |
77 | - { | |
78 | - field: '', | |
79 | - label: '数据', | |
80 | - component: 'Input', | |
81 | - }, | |
82 | - { | |
83 | - field: '', | |
84 | - label: '元数据', | |
85 | - component: 'Input', | |
86 | - }, | |
87 | - { | |
88 | - field: '', | |
89 | - label: '有错误', | |
90 | - component: 'Checkbox', | |
91 | - }, | |
92 | -]; |
src/views/rule/designer/src/components/BasicEvents/index.vue
deleted
100644 → 0
1 | +<script setup lang="ts"> | |
2 | + import AceEditor, { Ace } from 'ace-builds'; | |
3 | + import githubTheme from 'ace-builds/src-noconflict/theme-github?url'; | |
4 | + import 'ace-builds/src-noconflict/mode-java'; | |
5 | + import { ref, unref } from 'vue'; | |
6 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
7 | + | |
8 | + withDefaults( | |
9 | + defineProps<{ | |
10 | + content?: string; | |
11 | + }>(), | |
12 | + {} | |
13 | + ); | |
14 | + | |
15 | + defineEmits(['register']); | |
16 | + | |
17 | + const content = ref(); | |
18 | + | |
19 | + const [register] = useModalInner((params: ModalParamsType<string>) => { | |
20 | + content.value = params.record; | |
21 | + initEditor(); | |
22 | + unref(aceEditorRef)?.setValue(params.record, -1); | |
23 | + }); | |
24 | + | |
25 | + const javaEditorElRef = ref(); | |
26 | + | |
27 | + const aceEditorRef = ref<Ace.Editor>(); | |
28 | + | |
29 | + const initEditor = () => { | |
30 | + AceEditor.config.setModuleUrl('ace/theme/github', githubTheme); | |
31 | + const editor = AceEditor.edit(unref(javaEditorElRef)!, { | |
32 | + mode: 'ace/mode/java', | |
33 | + }); | |
34 | + editor.setTheme('ace/theme/github'); | |
35 | + editor.setOptions({ | |
36 | + fontSize: 14, | |
37 | + showLineNumbers: false, | |
38 | + showGutter: false, | |
39 | + }); | |
40 | + editor.setReadOnly(true); | |
41 | + aceEditorRef.value = editor; | |
42 | + }; | |
43 | +</script> | |
44 | + | |
45 | +<template> | |
46 | + <BasicModal @register="register" title="错误" :showOkBtn="false" cancelText="关闭" width="80%"> | |
47 | + <div ref="javaEditorElRef" class="w-full h-full min-h-96"></div> | |
48 | + </BasicModal> | |
49 | +</template> | ... | ... |
1 | +import { EventTypeEnum } from '../EventSelect/config'; | |
2 | +import { columns as debugColumns } from './debug.config'; | |
3 | +import { columns as errorColumns } from './error.config'; | |
4 | +import { columns as liveColumns } from './live.config'; | |
5 | +import { columns as statsColumns } from './stats.config'; | |
6 | + | |
7 | +export function getColumns(type: EventTypeEnum) { | |
8 | + const mapping = { | |
9 | + [EventTypeEnum.ERROR]: errorColumns, | |
10 | + [EventTypeEnum.LC_EVENT]: liveColumns, | |
11 | + [EventTypeEnum.STATS]: statsColumns, | |
12 | + [EventTypeEnum.DEBUG_RULE_NODE]: debugColumns, | |
13 | + }; | |
14 | + return mapping?.[type] || []; | |
15 | +} | ... | ... |
1 | +import { BasicColumn } from '/@/components/Table'; | |
2 | + | |
3 | +export const columns: BasicColumn[] = [ | |
4 | + { | |
5 | + title: '事件时间', | |
6 | + dataIndex: 'createdTime', | |
7 | + }, | |
8 | + { | |
9 | + title: '服务器', | |
10 | + dataIndex: 'body.server', | |
11 | + }, | |
12 | + { | |
13 | + title: '类型', | |
14 | + dataIndex: 'type', | |
15 | + }, | |
16 | + { | |
17 | + title: '实体类型', | |
18 | + dataIndex: 'entityId.entityType', | |
19 | + }, | |
20 | + { | |
21 | + title: '消息ID', | |
22 | + dataIndex: 'id.id', | |
23 | + }, | |
24 | + { | |
25 | + title: '消息类型', | |
26 | + dataIndex: 'msgtype', | |
27 | + }, | |
28 | + { | |
29 | + title: '关联类型', | |
30 | + dataIndex: 'relatedType', | |
31 | + }, | |
32 | + { | |
33 | + title: '数据', | |
34 | + dataIndex: 'data', | |
35 | + }, | |
36 | + { | |
37 | + title: '元数据', | |
38 | + dataIndex: 'metadaeta', | |
39 | + }, | |
40 | + { | |
41 | + title: '错误', | |
42 | + dataIndex: 'error', | |
43 | + }, | |
44 | +]; | ... | ... |
1 | +import { BasicColumn } from '/@/components/Table'; | |
2 | +import { dateUtil } from '/@/utils/dateUtil'; | |
3 | + | |
4 | +export const columns: BasicColumn[] = [ | |
5 | + { | |
6 | + title: '事件时间', | |
7 | + dataIndex: 'createdTime', | |
8 | + ellipsis: true, | |
9 | + width: 200, | |
10 | + format(text) { | |
11 | + return dateUtil(text).format('YYYY-MM-DD HH:mm:ss'); | |
12 | + }, | |
13 | + }, | |
14 | + { | |
15 | + title: '服务器', | |
16 | + dataIndex: 'body.server', | |
17 | + ellipsis: true, | |
18 | + }, | |
19 | + { | |
20 | + title: '方法', | |
21 | + dataIndex: 'body.method', | |
22 | + ellipsis: true, | |
23 | + }, | |
24 | + { | |
25 | + title: '错误', | |
26 | + dataIndex: 'body.error', | |
27 | + ellipsis: true, | |
28 | + width: 100, | |
29 | + slots: { | |
30 | + customRender: 'error', | |
31 | + }, | |
32 | + }, | |
33 | +]; | ... | ... |
src/views/rule/designer/src/components/UpdateNodeDrawer/BasicEvents/index.ts
renamed from
src/views/rule/designer/src/components/BasicEvents/index.ts
1 | +<script lang="ts" setup> | |
2 | + import { useTable, BasicTable } from '/@/components/Table'; | |
3 | + import { getColumns } from './config'; | |
4 | + import { getRuleNodeEventList } from '/@/api/ruleDesigner'; | |
5 | + import { BasicNodeFormData, NodeData } from '../../../../types/node'; | |
6 | + import { computed, reactive, ref, unref, watch } from 'vue'; | |
7 | + import { useUserStore } from '/@/store/modules/user'; | |
8 | + import { EventSelect } from '../EventSelect'; | |
9 | + import { Icon } from '/@/components/Icon'; | |
10 | + import { Tooltip } from 'ant-design-vue'; | |
11 | + import { EventTypeEnum } from '../EventSelect/config'; | |
12 | + import { FilterForm } from '../FilterForm'; | |
13 | + import { useModal } from '/@/components/Modal'; | |
14 | + import { DataActionModeEnum } from '/@/enums/toolEnum'; | |
15 | + import { ElementInfo } from '../../../../hook/useAwaitPopupWindowBindData'; | |
16 | + import ShowDetailModal from './ShowDetailModal.vue'; | |
17 | + | |
18 | + const props = defineProps<{ | |
19 | + nodeData?: NodeData<BasicNodeFormData>; | |
20 | + elementInfo?: ElementInfo; | |
21 | + }>(); | |
22 | + | |
23 | + const userStore = useUserStore(); | |
24 | + const getNodeId = computed(() => props.elementInfo?.id); | |
25 | + const getTenantId = computed(() => unref(userStore.getUserInfo).tenantId); | |
26 | + const eventType = ref(EventTypeEnum.DEBUG_RULE_NODE); | |
27 | + const filterFormElRef = ref<Nullable<InstanceType<typeof FilterForm>>>(null); | |
28 | + | |
29 | + const searchParams = reactive({ | |
30 | + params: {} as Recordable, | |
31 | + data: {} as Recordable, | |
32 | + }); | |
33 | + | |
34 | + const [register, { reload, setColumns, setPagination }] = useTable({ | |
35 | + columns: getColumns(EventTypeEnum.DEBUG_RULE_NODE), | |
36 | + showIndexColumn: false, | |
37 | + useSearchForm: false, | |
38 | + canResize: true, | |
39 | + resizeHeightOffset: 76, | |
40 | + fetchSetting: { | |
41 | + totalField: 'totalElements', | |
42 | + listField: 'data', | |
43 | + }, | |
44 | + showTableSetting: true, | |
45 | + api: async (params: Record<'page' | 'pageSize', number>) => { | |
46 | + const result = await getRuleNodeEventList( | |
47 | + unref(getNodeId)!, | |
48 | + { | |
49 | + page: params.page - 1, | |
50 | + pageSize: params.pageSize, | |
51 | + tenantId: unref(getTenantId), | |
52 | + ...searchParams.params, | |
53 | + }, | |
54 | + { ...searchParams.data, eventType: unref(eventType) } | |
55 | + ); | |
56 | + | |
57 | + return result; | |
58 | + }, | |
59 | + }); | |
60 | + | |
61 | + const [registerModal, { openModal }] = useModal(); | |
62 | + | |
63 | + const handleOpenFilterForm = () => { | |
64 | + openModal(true, { | |
65 | + mode: DataActionModeEnum.READ, | |
66 | + record: { type: unref(eventType) }, | |
67 | + } as ModalParamsType<{ type: EventTypeEnum }>); | |
68 | + }; | |
69 | + | |
70 | + const handleRemoveFilterQueue = () => { | |
71 | + unref(filterFormElRef)?.resetFields(); | |
72 | + handleReset(); | |
73 | + }; | |
74 | + | |
75 | + const handleFilterChange = (searchValue: Record<'data' | 'params', Recordable>) => { | |
76 | + const { data, params } = searchValue; | |
77 | + handleReset(data, params); | |
78 | + }; | |
79 | + | |
80 | + const handleReset = (data: Recordable = {}, params: Recordable = {}) => { | |
81 | + searchParams.data = data; | |
82 | + searchParams.params = params; | |
83 | + setPagination({ current: 1 }); | |
84 | + reload(); | |
85 | + }; | |
86 | + | |
87 | + const handleEventTypeChange = () => { | |
88 | + setColumns(getColumns(unref(eventType))); | |
89 | + handleReset(); | |
90 | + }; | |
91 | + | |
92 | + const [registerDetailModal, { openModal: openDetailModal }] = useModal(); | |
93 | + | |
94 | + const handleOpenDetailModal = (text: string) => { | |
95 | + openDetailModal(true, { | |
96 | + mode: DataActionModeEnum.READ, | |
97 | + record: text, | |
98 | + } as ModalParamsType<string>); | |
99 | + }; | |
100 | + | |
101 | + watch( | |
102 | + () => props.elementInfo?.id, | |
103 | + () => { | |
104 | + reload(); | |
105 | + } | |
106 | + ); | |
107 | +</script> | |
108 | + | |
109 | +<template> | |
110 | + <section class="bg-gray-100 dark:bg-dark-200 p-4 h-full"> | |
111 | + <BasicTable @register="register" class="debug-table h-full"> | |
112 | + <template #tableTitle> | |
113 | + <EventSelect v-model:type="eventType" @change="handleEventTypeChange" /> | |
114 | + </template> | |
115 | + <template #toolbar> | |
116 | + <Tooltip title="过滤器"> | |
117 | + <Icon | |
118 | + icon="material-symbols:filter-list" | |
119 | + class="cursor-pointer svg:text-2xl" | |
120 | + @click="handleOpenFilterForm" | |
121 | + /> | |
122 | + </Tooltip> | |
123 | + <Tooltip title="重置"> | |
124 | + <Icon | |
125 | + icon="mdi:filter-variant-remove" | |
126 | + class="cursor-pointer svg:text-2xl" | |
127 | + @click="handleRemoveFilterQueue" | |
128 | + /> | |
129 | + </Tooltip> | |
130 | + </template> | |
131 | + <template #error="{ text }"> | |
132 | + <Icon | |
133 | + icon="material-symbols:more-horiz" | |
134 | + class="cursor-pointer svg:text-2xl" | |
135 | + @click="handleOpenDetailModal(text)" | |
136 | + /> | |
137 | + </template> | |
138 | + </BasicTable> | |
139 | + | |
140 | + <FilterForm | |
141 | + ref="filterFormElRef" | |
142 | + @register="registerModal" | |
143 | + @filterChange="handleFilterChange" | |
144 | + /> | |
145 | + | |
146 | + <ShowDetailModal @register="registerDetailModal" /> | |
147 | + </section> | |
148 | +</template> | |
149 | + | |
150 | +<style lang="less" scoped></style> | ... | ... |
1 | +import { BasicColumn } from '/@/components/Table'; | |
2 | +import { dateUtil } from '/@/utils/dateUtil'; | |
3 | + | |
4 | +export const columns: BasicColumn[] = [ | |
5 | + { | |
6 | + title: '事件时间', | |
7 | + dataIndex: 'createdTime', | |
8 | + ellipsis: true, | |
9 | + width: 200, | |
10 | + format(text) { | |
11 | + return dateUtil(text).format('YYYY-MM-DD HH:mm:ss'); | |
12 | + }, | |
13 | + }, | |
14 | + { | |
15 | + title: '服务器', | |
16 | + dataIndex: 'body.server', | |
17 | + ellipsis: true, | |
18 | + }, | |
19 | + { | |
20 | + title: '事件', | |
21 | + dataIndex: 'body.event', | |
22 | + ellipsis: true, | |
23 | + }, | |
24 | + { | |
25 | + title: '状态', | |
26 | + dataIndex: 'body.success', | |
27 | + ellipsis: true, | |
28 | + format(text) { | |
29 | + return text ? '成功' : '失败'; | |
30 | + }, | |
31 | + }, | |
32 | + { | |
33 | + title: '错误', | |
34 | + dataIndex: 'body.error', | |
35 | + ellipsis: true, | |
36 | + width: 100, | |
37 | + slots: { | |
38 | + customRender: 'error', | |
39 | + }, | |
40 | + }, | |
41 | +]; | ... | ... |
1 | +import { BasicColumn } from '/@/components/Table'; | |
2 | +import { dateUtil } from '/@/utils/dateUtil'; | |
3 | + | |
4 | +export const columns: BasicColumn[] = [ | |
5 | + { | |
6 | + title: '事件时间', | |
7 | + dataIndex: 'createdTime', | |
8 | + ellipsis: true, | |
9 | + width: 200, | |
10 | + format(text) { | |
11 | + return dateUtil(text).format('YYYY-MM-DD HH:mm:ss'); | |
12 | + }, | |
13 | + }, | |
14 | + { | |
15 | + title: '服务器', | |
16 | + dataIndex: 'body.server', | |
17 | + ellipsis: true, | |
18 | + }, | |
19 | + { | |
20 | + title: '消息处理', | |
21 | + dataIndex: 'body.event', | |
22 | + ellipsis: true, | |
23 | + }, | |
24 | + { | |
25 | + title: '错误发生', | |
26 | + dataIndex: 'body.event', | |
27 | + ellipsis: true, | |
28 | + }, | |
29 | +]; | ... | ... |
1 | +export enum EventTypeEnum { | |
2 | + ERROR = 'ERROR', | |
3 | + LC_EVENT = 'LC_EVENT', | |
4 | + STATS = 'STATS', | |
5 | + DEBUG_RULE_NODE = 'DEBUG_RULE_NODE', | |
6 | +} | |
7 | + | |
8 | +export enum EventTypeNameEnum { | |
9 | + ERROR = '错误', | |
10 | + LC_EVENT = '生命周期事件', | |
11 | + STATS = '类型统计', | |
12 | + DEBUG_RULE_NODE = '调试', | |
13 | +} | |
14 | + | |
15 | +export const eventTypeOptions = Object.keys(EventTypeEnum).map((value) => ({ | |
16 | + label: EventTypeNameEnum[value], | |
17 | + value, | |
18 | +})); | ... | ... |
1 | +export { default as EventSelect } from './index.vue'; | ... | ... |
1 | +<script setup lang="ts"> | |
2 | + import { Select } from 'ant-design-vue'; | |
3 | + import { eventTypeOptions, EventTypeEnum } from './config'; | |
4 | + import { unref } from 'vue'; | |
5 | + | |
6 | + withDefaults( | |
7 | + defineProps<{ | |
8 | + type?: EventTypeEnum; | |
9 | + }>(), | |
10 | + { | |
11 | + type: EventTypeEnum.DEBUG_RULE_NODE, | |
12 | + } | |
13 | + ); | |
14 | + | |
15 | + const emit = defineEmits<{ | |
16 | + (eventName: 'update:type', value: EventTypeEnum): void; | |
17 | + (eventName: 'change', value: EventTypeEnum): void; | |
18 | + }>(); | |
19 | + | |
20 | + const handleChange = (value: EventTypeEnum) => { | |
21 | + emit('update:type', unref(value)); | |
22 | + emit('change', unref(value)); | |
23 | + }; | |
24 | +</script> | |
25 | + | |
26 | +<template> | |
27 | + <Select | |
28 | + :value="type" | |
29 | + :options="eventTypeOptions" | |
30 | + :bordered="false" | |
31 | + class="border-b w-40" | |
32 | + @change="handleChange" | |
33 | + /> | |
34 | +</template> | ... | ... |
1 | +import { EventTypeEnum } from '../EventSelect/config'; | |
2 | +import { | |
3 | + formSchemas as debugFormSchemas, | |
4 | + generateSearchParams as transformDebugSearchParams, | |
5 | +} from './debug.config'; | |
6 | +import { | |
7 | + formSchemas as errorFormSchemas, | |
8 | + generateSearchParams as transformErrorSearchParams, | |
9 | +} from './error.config'; | |
10 | +import { | |
11 | + formSchemas as liveFormSchemas, | |
12 | + generateSearchParams as transformLiveSearchParams, | |
13 | +} from './live.config'; | |
14 | +import { | |
15 | + formSchemas as statsFormSchemas, | |
16 | + generateSearchParams as transformStatsSearchParams, | |
17 | +} from './stats.config'; | |
18 | +import { FormSchema } from '/@/components/Form'; | |
19 | + | |
20 | +export function getFormSchemas(type: EventTypeEnum): FormSchema[] { | |
21 | + const mapping = { | |
22 | + [EventTypeEnum.ERROR]: errorFormSchemas, | |
23 | + [EventTypeEnum.LC_EVENT]: liveFormSchemas, | |
24 | + [EventTypeEnum.STATS]: statsFormSchemas, | |
25 | + [EventTypeEnum.DEBUG_RULE_NODE]: debugFormSchemas, | |
26 | + }; | |
27 | + | |
28 | + return mapping?.[type] || []; | |
29 | +} | |
30 | + | |
31 | +export function transformFilterValue( | |
32 | + type: EventTypeEnum, | |
33 | + value: Recordable | |
34 | +): Record<'data' | 'params', Recordable> { | |
35 | + const mapping = { | |
36 | + [EventTypeEnum.ERROR]: transformErrorSearchParams, | |
37 | + [EventTypeEnum.LC_EVENT]: transformLiveSearchParams, | |
38 | + [EventTypeEnum.STATS]: transformStatsSearchParams, | |
39 | + [EventTypeEnum.DEBUG_RULE_NODE]: transformDebugSearchParams, | |
40 | + }; | |
41 | + return mapping?.[type]?.(value as any) || { data: {}, params: {} }; | |
42 | +} | ... | ... |
1 | +import { h } from 'vue'; | |
2 | +import { RangePickerExtra } from '../RangePickerExtra'; | |
3 | +import { FormSchema } from '/@/components/Form'; | |
4 | + | |
5 | +export enum FormFieldsEnum { | |
6 | + SERVER = 'server', | |
7 | + MSG_DIRECTION_TYPE = 'msgDirectionType', | |
8 | + ENTITY_ID = 'entityId', | |
9 | + ENTITY_NAME = 'entityName', | |
10 | + MSG_TYPE = 'msgType', | |
11 | + RELATION_TYPE = 'relationType', | |
12 | + DATA_SEARCH = 'dataSearch', | |
13 | + METADATA_SEARCH = 'metadataSearch', | |
14 | + IS_ERROR = 'isError', | |
15 | + ERROR_STR = 'errorStr', | |
16 | + EVENT_TYPE = 'eventType', | |
17 | + START_TIME = 'startTime', | |
18 | + END_TIME = 'endTime', | |
19 | + | |
20 | + TIME_INTERVAL = 'timeInterval', | |
21 | +} | |
22 | + | |
23 | +export enum MessageDirectionTypeEnum { | |
24 | + IN = 'IN', | |
25 | + OUT = 'OUT', | |
26 | +} | |
27 | + | |
28 | +export enum EntityNameEnum { | |
29 | + TENANT = 'TENANT', | |
30 | + TENANT_PROFILE = 'TENANT_PROFILE', | |
31 | + CUSTOMER = 'CUSTOMER', | |
32 | + USER = 'USER', | |
33 | + DASHBOARD = 'DASHBOARD', | |
34 | + ASSET = 'ASSET', | |
35 | + DEVICE = 'DEVICE', | |
36 | + DEVICE_PROFILE = 'DEVICE_PROFILE', | |
37 | + ALARM = 'ALARM', | |
38 | + RULE_CHAIN = 'RULE_CHAIN', | |
39 | + RULE_NODE = 'RULE_NODE', | |
40 | + EDGE = 'EDGE', | |
41 | + ENTITY_VIEW = 'ENTITY_VIEW', | |
42 | + WIDGETS_BUNDLE = 'WIDGETS_BUNDLE', | |
43 | + WIDGET_TYPE = 'WIDGET_TYPE', | |
44 | + API_USAGE_STATE = 'API_USAGE_STATE', | |
45 | + TB_RESOURCE = 'TB_RESOURCE', | |
46 | + OTA_PACKAGE = 'OTA_PACKAGE', | |
47 | + RPC = 'RPC', | |
48 | +} | |
49 | + | |
50 | +export const formSchemas: FormSchema[] = [ | |
51 | + { | |
52 | + field: FormFieldsEnum.TIME_INTERVAL, | |
53 | + label: '时间段', | |
54 | + component: 'RangePicker', | |
55 | + colProps: { span: 24 }, | |
56 | + componentProps: { | |
57 | + showTime: true, | |
58 | + }, | |
59 | + renderComponentContent: ({ model }) => { | |
60 | + return { | |
61 | + renderExtraFooter: () => | |
62 | + h(RangePickerExtra, { | |
63 | + onChange: (date: moment.Moment[]) => { | |
64 | + model[FormFieldsEnum.TIME_INTERVAL] = date; | |
65 | + }, | |
66 | + }), | |
67 | + }; | |
68 | + }, | |
69 | + }, | |
70 | + { | |
71 | + field: FormFieldsEnum.SERVER, | |
72 | + label: '服务器', | |
73 | + component: 'Input', | |
74 | + componentProps: { | |
75 | + placeholder: `请输入服务器`, | |
76 | + }, | |
77 | + }, | |
78 | + { | |
79 | + field: FormFieldsEnum.MSG_DIRECTION_TYPE, | |
80 | + label: '类型', | |
81 | + component: 'Select', | |
82 | + componentProps: { | |
83 | + options: Object.keys(MessageDirectionTypeEnum).map((value) => ({ label: value, value })), | |
84 | + allowClear: true, | |
85 | + placeholder: `请选择类型`, | |
86 | + getPopupContainer: () => document.body, | |
87 | + }, | |
88 | + }, | |
89 | + { | |
90 | + field: FormFieldsEnum.ENTITY_ID, | |
91 | + label: '实体ID', | |
92 | + component: 'Input', | |
93 | + componentProps: { | |
94 | + placeholder: `请输入实体ID`, | |
95 | + }, | |
96 | + }, | |
97 | + { | |
98 | + field: FormFieldsEnum.ENTITY_NAME, | |
99 | + label: '实体类型', | |
100 | + component: 'Select', | |
101 | + componentProps: { | |
102 | + options: Object.keys(EntityNameEnum).map((value) => ({ label: value, value })), | |
103 | + allowClear: true, | |
104 | + placeholder: `请选择实体类型`, | |
105 | + getPopupContainer: () => document.body, | |
106 | + }, | |
107 | + }, | |
108 | + { | |
109 | + field: FormFieldsEnum.MSG_TYPE, | |
110 | + label: '消息类型', | |
111 | + component: 'Input', | |
112 | + componentProps: { | |
113 | + placeholder: `请输入消息类型`, | |
114 | + }, | |
115 | + }, | |
116 | + { | |
117 | + field: FormFieldsEnum.RELATION_TYPE, | |
118 | + label: '关联类型', | |
119 | + component: 'Input', | |
120 | + componentProps: { | |
121 | + placeholder: `请输入关联类型`, | |
122 | + }, | |
123 | + }, | |
124 | + { | |
125 | + field: FormFieldsEnum.DATA_SEARCH, | |
126 | + label: '数据', | |
127 | + component: 'Input', | |
128 | + componentProps: { | |
129 | + placeholder: `请输入数据`, | |
130 | + }, | |
131 | + }, | |
132 | + { | |
133 | + field: FormFieldsEnum.METADATA_SEARCH, | |
134 | + label: '元数据', | |
135 | + component: 'Input', | |
136 | + componentProps: { | |
137 | + placeholder: `请输入元数据`, | |
138 | + }, | |
139 | + }, | |
140 | + { | |
141 | + field: FormFieldsEnum.IS_ERROR, | |
142 | + label: '有错误', | |
143 | + component: 'Checkbox', | |
144 | + }, | |
145 | + { | |
146 | + field: FormFieldsEnum.ERROR_STR, | |
147 | + label: '错误', | |
148 | + component: 'Input', | |
149 | + show: ({ model }) => model[FormFieldsEnum.IS_ERROR], | |
150 | + componentProps: { | |
151 | + placeholder: `请输入错误`, | |
152 | + }, | |
153 | + }, | |
154 | +]; | |
155 | + | |
156 | +export function generateSearchParams( | |
157 | + value: Record<FormFieldsEnum, any> | |
158 | +): Record<'data' | 'params', Recordable> { | |
159 | + const { | |
160 | + startTime, | |
161 | + endTime, | |
162 | + dataSearch, | |
163 | + entityId, | |
164 | + entityName, | |
165 | + errorStr, | |
166 | + eventType, | |
167 | + isError, | |
168 | + metadataSearch, | |
169 | + msgDirectionType, | |
170 | + msgType, | |
171 | + relationType, | |
172 | + server, | |
173 | + } = value; | |
174 | + | |
175 | + return { | |
176 | + params: { startTime, endTime }, | |
177 | + data: { | |
178 | + dataSearch, | |
179 | + entityId, | |
180 | + entityName, | |
181 | + errorStr, | |
182 | + eventType, | |
183 | + isError, | |
184 | + metadataSearch, | |
185 | + msgDirectionType, | |
186 | + msgType, | |
187 | + relationType, | |
188 | + server, | |
189 | + }, | |
190 | + }; | |
191 | +} | ... | ... |
1 | +import { h } from 'vue'; | |
2 | +import { RangePickerExtra } from '../RangePickerExtra'; | |
3 | +import { FormSchema } from '/@/components/Form'; | |
4 | + | |
5 | +export enum FormFieldsEnum { | |
6 | + ERROR_STR = 'errorStr', | |
7 | + METHOD = 'method', | |
8 | + SERVER = 'server', | |
9 | + | |
10 | + START_TIME = 'startTime', | |
11 | + END_TIME = 'endTime', | |
12 | + TIME_INTERVAL = 'timeInterval', | |
13 | +} | |
14 | + | |
15 | +export const formSchemas: FormSchema[] = [ | |
16 | + { | |
17 | + field: FormFieldsEnum.TIME_INTERVAL, | |
18 | + label: '时间段', | |
19 | + component: 'RangePicker', | |
20 | + colProps: { span: 24 }, | |
21 | + componentProps: { | |
22 | + showTime: true, | |
23 | + }, | |
24 | + renderComponentContent: ({ model }) => { | |
25 | + return { | |
26 | + renderExtraFooter: () => | |
27 | + h(RangePickerExtra, { | |
28 | + onChange: (date: moment.Moment[]) => { | |
29 | + model[FormFieldsEnum.TIME_INTERVAL] = date; | |
30 | + }, | |
31 | + }), | |
32 | + }; | |
33 | + }, | |
34 | + }, | |
35 | + { | |
36 | + field: FormFieldsEnum.SERVER, | |
37 | + label: '服务器', | |
38 | + component: 'Input', | |
39 | + componentProps: { | |
40 | + placeholder: `请输入服务器`, | |
41 | + }, | |
42 | + }, | |
43 | + { | |
44 | + field: FormFieldsEnum.METHOD, | |
45 | + label: '方法', | |
46 | + component: 'Input', | |
47 | + componentProps: { | |
48 | + placeholder: `请输入方法`, | |
49 | + }, | |
50 | + }, | |
51 | + { | |
52 | + field: FormFieldsEnum.ERROR_STR, | |
53 | + label: '错误', | |
54 | + component: 'Input', | |
55 | + componentProps: { | |
56 | + placeholder: `请输入错误`, | |
57 | + }, | |
58 | + }, | |
59 | +]; | |
60 | + | |
61 | +export function generateSearchParams( | |
62 | + value: Record<FormFieldsEnum, any> | |
63 | +): Record<'data' | 'params', Recordable> { | |
64 | + const { startTime, endTime, errorStr, method, server } = value; | |
65 | + return { | |
66 | + data: { errorStr, method, server }, | |
67 | + params: { startTime, endTime }, | |
68 | + }; | |
69 | +} | ... | ... |
1 | +export { default as FilterForm } from './index.vue'; | ... | ... |
1 | +<script setup lang="ts"> | |
2 | + import { ref, unref } from 'vue'; | |
3 | + import { EventTypeEnum } from '../EventSelect/config'; | |
4 | + import { getFormSchemas, transformFilterValue } from './config'; | |
5 | + import { FormFieldsEnum } from './debug.config'; | |
6 | + import { BasicForm, useForm } from '/@/components/Form'; | |
7 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
8 | + | |
9 | + interface FilterChangeValueType { | |
10 | + data: Recordable; | |
11 | + params: Recordable; | |
12 | + } | |
13 | + | |
14 | + const emit = defineEmits<{ | |
15 | + (eventName: 'register', value: any): any; | |
16 | + (eventName: 'filterChange', value: FilterChangeValueType): void; | |
17 | + }>(); | |
18 | + | |
19 | + const [registerForm, { resetSchema, getFieldsValue, resetFields }] = useForm({ | |
20 | + layout: 'inline', | |
21 | + showActionButtonGroup: false, | |
22 | + labelWidth: 80, | |
23 | + fieldMapToTime: [ | |
24 | + [FormFieldsEnum.TIME_INTERVAL, [FormFieldsEnum.START_TIME, FormFieldsEnum.END_TIME], 'x'], | |
25 | + ], | |
26 | + }); | |
27 | + | |
28 | + const eventType = ref(); | |
29 | + | |
30 | + const [register, { closeModal }] = useModalInner( | |
31 | + (params: ModalParamsType<{ type: EventTypeEnum }>) => { | |
32 | + const { record } = params; | |
33 | + const { type } = record; | |
34 | + if (unref(eventType) !== type) { | |
35 | + resetFields(); | |
36 | + } | |
37 | + eventType.value = type; | |
38 | + resetSchema(getFormSchemas(unref(eventType))); | |
39 | + } | |
40 | + ); | |
41 | + | |
42 | + const handleOk = () => { | |
43 | + emit('filterChange', transformFilterValue(unref(eventType), getFieldsValue())); | |
44 | + closeModal(); | |
45 | + }; | |
46 | + | |
47 | + defineExpose({ | |
48 | + resetFields, | |
49 | + }); | |
50 | +</script> | |
51 | + | |
52 | +<template> | |
53 | + <BasicModal | |
54 | + @register="register" | |
55 | + title="过滤器" | |
56 | + wrapClassName="rule-node-filter-form" | |
57 | + @cancel="closeModal()" | |
58 | + @ok="handleOk" | |
59 | + > | |
60 | + <BasicForm @register="registerForm" /> | |
61 | + </BasicModal> | |
62 | +</template> | |
63 | + | |
64 | +<style lang="less"> | |
65 | + .rule-node-filter-form { | |
66 | + .ant-form-item-label { | |
67 | + label { | |
68 | + @apply w-full truncate block leading-8; | |
69 | + } | |
70 | + } | |
71 | + | |
72 | + .ant-calendar-picker.ant-calendar-picker-default { | |
73 | + @apply !w-full; | |
74 | + } | |
75 | + | |
76 | + .ant-input-number { | |
77 | + @apply w-full; | |
78 | + } | |
79 | + } | |
80 | +</style> | ... | ... |
1 | +import { h } from 'vue'; | |
2 | +import { RangePickerExtra } from '../RangePickerExtra'; | |
3 | +import { FormSchema } from '/@/components/Form'; | |
4 | + | |
5 | +export enum FormFieldsEnum { | |
6 | + ERROR_STR = 'errorStr', | |
7 | + EVENT = 'event', | |
8 | + SERVER = 'server', | |
9 | + STATUS = 'status', | |
10 | + | |
11 | + START_TIME = 'startTime', | |
12 | + END_TIME = 'endTime', | |
13 | + TIME_INTERVAL = 'timeInterval', | |
14 | +} | |
15 | + | |
16 | +enum StatusEnum { | |
17 | + SUCCESS = 'SUCCESS', | |
18 | + FAILURE = 'FAILURE', | |
19 | +} | |
20 | + | |
21 | +enum StatusNameEnum { | |
22 | + SUCCESS = 'Success', | |
23 | + FAILURE = 'Failure', | |
24 | +} | |
25 | + | |
26 | +export const formSchemas: FormSchema[] = [ | |
27 | + { | |
28 | + field: FormFieldsEnum.TIME_INTERVAL, | |
29 | + label: '时间段', | |
30 | + component: 'RangePicker', | |
31 | + colProps: { span: 24 }, | |
32 | + componentProps: { | |
33 | + showTime: true, | |
34 | + }, | |
35 | + renderComponentContent: ({ model }) => { | |
36 | + return { | |
37 | + renderExtraFooter: () => | |
38 | + h(RangePickerExtra, { | |
39 | + onChange: (date: moment.Moment[]) => { | |
40 | + model[FormFieldsEnum.TIME_INTERVAL] = date; | |
41 | + }, | |
42 | + }), | |
43 | + }; | |
44 | + }, | |
45 | + }, | |
46 | + { | |
47 | + field: FormFieldsEnum.SERVER, | |
48 | + label: '服务器', | |
49 | + component: 'Input', | |
50 | + componentProps: { | |
51 | + placeholder: `请输入服务器`, | |
52 | + }, | |
53 | + }, | |
54 | + { | |
55 | + field: FormFieldsEnum.EVENT, | |
56 | + label: '事件', | |
57 | + component: 'Input', | |
58 | + componentProps: { | |
59 | + placeholder: `请输入事件`, | |
60 | + }, | |
61 | + }, | |
62 | + { | |
63 | + field: FormFieldsEnum.STATUS, | |
64 | + label: '状态', | |
65 | + component: 'Input', | |
66 | + componentProps: { | |
67 | + options: Object.keys(StatusEnum).map((value) => ({ label: StatusNameEnum[value], value })), | |
68 | + allowClear: true, | |
69 | + placeholder: `请选择状态`, | |
70 | + getPopupContainer: () => document.body, | |
71 | + }, | |
72 | + }, | |
73 | + { | |
74 | + field: FormFieldsEnum.ERROR_STR, | |
75 | + label: '错误', | |
76 | + component: 'Input', | |
77 | + componentProps: { | |
78 | + placeholder: `请输入错误`, | |
79 | + }, | |
80 | + }, | |
81 | +]; | |
82 | + | |
83 | +export function generateSearchParams( | |
84 | + value: Record<FormFieldsEnum, any> | |
85 | +): Record<'data' | 'params', Recordable> { | |
86 | + const { startTime, endTime, errorStr, event, status, server } = value; | |
87 | + return { | |
88 | + data: { errorStr, event, status, server }, | |
89 | + params: { startTime, endTime }, | |
90 | + }; | |
91 | +} | ... | ... |
1 | +import { h } from 'vue'; | |
2 | +import { RangePickerExtra } from '../RangePickerExtra'; | |
3 | +import { FormSchema } from '/@/components/Form'; | |
4 | + | |
5 | +export enum FormFieldsEnum { | |
6 | + SERVER = 'server', | |
7 | + MESSAGE_PROCESSED = 'messageProcessed', | |
8 | + ERRORS_OCCURRED = 'errorsOccured', | |
9 | + | |
10 | + START_TIME = 'startTime', | |
11 | + END_TIME = 'endTime', | |
12 | + TIME_INTERVAL = 'timeInterval', | |
13 | +} | |
14 | + | |
15 | +export const formSchemas: FormSchema[] = [ | |
16 | + { | |
17 | + field: FormFieldsEnum.TIME_INTERVAL, | |
18 | + label: '时间段', | |
19 | + component: 'RangePicker', | |
20 | + colProps: { span: 24 }, | |
21 | + componentProps: { | |
22 | + showTime: true, | |
23 | + }, | |
24 | + renderComponentContent: ({ model }) => { | |
25 | + return { | |
26 | + renderExtraFooter: () => | |
27 | + h(RangePickerExtra, { | |
28 | + onChange: (date: moment.Moment[]) => { | |
29 | + model[FormFieldsEnum.TIME_INTERVAL] = date; | |
30 | + }, | |
31 | + }), | |
32 | + }; | |
33 | + }, | |
34 | + }, | |
35 | + { | |
36 | + field: FormFieldsEnum.SERVER, | |
37 | + label: '服务器', | |
38 | + component: 'Input', | |
39 | + componentProps: { | |
40 | + placeholder: `请输入服务器`, | |
41 | + }, | |
42 | + }, | |
43 | + { | |
44 | + field: FormFieldsEnum.MESSAGE_PROCESSED, | |
45 | + label: 'Minimum messages processed', | |
46 | + component: 'InputNumber', | |
47 | + componentProps: { | |
48 | + min: 0, | |
49 | + placeholder: `请输入Minimum messages processed`, | |
50 | + }, | |
51 | + }, | |
52 | + { | |
53 | + field: FormFieldsEnum.ERRORS_OCCURRED, | |
54 | + label: 'Minimum errors occurred', | |
55 | + component: 'InputNumber', | |
56 | + componentProps: { | |
57 | + min: 0, | |
58 | + placeholder: `请输入Minimum errors occurred`, | |
59 | + }, | |
60 | + }, | |
61 | +]; | |
62 | + | |
63 | +export function generateSearchParams( | |
64 | + value: Record<FormFieldsEnum, any> | |
65 | +): Record<'data' | 'params', Recordable> { | |
66 | + const { startTime, endTime, messageProcessed, errorsOccured, server } = value; | |
67 | + return { | |
68 | + data: { messageProcessed, errorsOccured, server }, | |
69 | + params: { startTime, endTime }, | |
70 | + }; | |
71 | +} | ... | ... |
1 | +import { dateUtil } from '/@/utils/dateUtil'; | |
2 | + | |
3 | +export enum TimeUnitEnum { | |
4 | + day = 'day', | |
5 | + hour = 'hour', | |
6 | + minute = 'minute', | |
7 | + second = 'second', | |
8 | +} | |
9 | +export enum TimeUnitNameEnum { | |
10 | + day = '天', | |
11 | + hour = '小时', | |
12 | + minute = '分', | |
13 | + second = '秒', | |
14 | +} | |
15 | + | |
16 | +export enum DateShortcutOptionEnum { | |
17 | + YESTERDAY = 'YESTERDAY', | |
18 | + DAY_BEFORE_YESTERDAY = 'DAY_BEFORE_YESTERDAY', | |
19 | + THIS_DAY_LAST_WEEK = 'THIS_DAY_LAST_WEEK', | |
20 | + PREVIOUS_WEEK_SUN_SAT = 'PREVIOUS_WEEK_SUN_SAT', | |
21 | + PREVIOUS_WEEK_MON_SUN = 'PREVIOUS_WEEK_MON_SUN', | |
22 | + PREVIOUS_MONTH = 'PREVIOUS_MONTH', | |
23 | + PREVIOUS_YEAR = 'PREVIOUS_YEAR', | |
24 | + CURRENT_HOUR = 'CURRENT_HOUR', | |
25 | + CURRENT_DAY = 'CURRENT_DAY', | |
26 | + CURRENT_DAY_SO_FAR = 'CURRENT_DAY_SO_FAR', | |
27 | + CURRENT_WEEK_SUN_SAT = 'CURRENT_WEEK_SUN_SAT', | |
28 | + CURRENT_WEEK_MON_SUN = 'CURRENT_WEEK_MON_SUN', | |
29 | + CURRENT_WEEK_SO_FAR_SUN_SAT = 'CURRENT_WEEK_SO_FAR_SUN_SAT', | |
30 | + CURRENT_WEEK_SO_FAR_MON_SUN = 'CURRENT_WEEK_SO_FAR_MON_SUN', | |
31 | + CURRENT_MONTH = 'CURRENT_MONTH', | |
32 | + CURRENT_MONTH_SO_FAR = 'CURRENT_MONTH_SO_FAR', | |
33 | + CURRENT_YEAR = 'CURRENT_YEAR', | |
34 | + CURRENT_YEAR_SO_FAR = 'CURRENT_YEAR_SO_FAR', | |
35 | +} | |
36 | +export enum DateShortcutOptionNameEnum { | |
37 | + YESTERDAY = '昨天', | |
38 | + DAY_BEFORE_YESTERDAY = '前天', | |
39 | + THIS_DAY_LAST_WEEK = '前一周的这一天', | |
40 | + PREVIOUS_WEEK_SUN_SAT = '前一周 (周日至周六)', | |
41 | + PREVIOUS_WEEK_MON_SUN = '前一周 (周一至周日)', | |
42 | + PREVIOUS_MONTH = '前一个月', | |
43 | + PREVIOUS_YEAR = '前一年', | |
44 | + CURRENT_HOUR = '当前小时', | |
45 | + CURRENT_DAY = '当前天', | |
46 | + CURRENT_DAY_SO_FAR = '当天到目前为止', | |
47 | + CURRENT_WEEK_SUN_SAT = '本周 (周日至周六)', | |
48 | + CURRENT_WEEK_MON_SUN = '本周 (周一至周日)', | |
49 | + CURRENT_WEEK_SO_FAR_SUN_SAT = '本周到目前为止 (周日至周六)', | |
50 | + CURRENT_WEEK_SO_FAR_MON_SUN = '本周到目前为止 (周一至周日)', | |
51 | + CURRENT_MONTH = '本月', | |
52 | + CURRENT_MONTH_SO_FAR = '本月到目前为止', | |
53 | + CURRENT_YEAR = '本年', | |
54 | + CURRENT_YEAR_SO_FAR = '本年到目前为止', | |
55 | +} | |
56 | + | |
57 | +const options = [ | |
58 | + { value: 1, unit: TimeUnitEnum.second }, | |
59 | + { value: 5, unit: TimeUnitEnum.second }, | |
60 | + { value: 10, unit: TimeUnitEnum.second }, | |
61 | + { value: 15, unit: TimeUnitEnum.second }, | |
62 | + { value: 30, unit: TimeUnitEnum.second }, | |
63 | + | |
64 | + { value: 1, unit: TimeUnitEnum.minute }, | |
65 | + { value: 5, unit: TimeUnitEnum.minute }, | |
66 | + { value: 10, unit: TimeUnitEnum.minute }, | |
67 | + { value: 15, unit: TimeUnitEnum.minute }, | |
68 | + { value: 30, unit: TimeUnitEnum.minute }, | |
69 | + | |
70 | + { value: 1, unit: TimeUnitEnum.hour }, | |
71 | + { value: 2, unit: TimeUnitEnum.hour }, | |
72 | + { value: 5, unit: TimeUnitEnum.hour }, | |
73 | + { value: 10, unit: TimeUnitEnum.hour }, | |
74 | + { value: 12, unit: TimeUnitEnum.hour }, | |
75 | + | |
76 | + { value: 1, unit: TimeUnitEnum.day }, | |
77 | + { value: 7, unit: TimeUnitEnum.day }, | |
78 | + { value: 30, unit: TimeUnitEnum.day }, | |
79 | +]; | |
80 | + | |
81 | +export const latestOptions = options.map((item) => ({ | |
82 | + ...item, | |
83 | + value: `${item.value}${item.unit}`, | |
84 | + label: `${item.value} ${TimeUnitNameEnum[item.unit]}`, | |
85 | + unitValue: item.value, | |
86 | +})); | |
87 | + | |
88 | +export const shortcutOptions = Object.keys(DateShortcutOptionEnum).map((value) => ({ | |
89 | + label: DateShortcutOptionNameEnum[value], | |
90 | + value, | |
91 | +})); | |
92 | + | |
93 | +export const getShortcutOptionValue = (value: DateShortcutOptionEnum) => { | |
94 | + const mapping = { | |
95 | + YESTERDAY: () => { | |
96 | + const startDate = dateUtil().subtract(1, 'day').startOf('day'); | |
97 | + const endDate = dateUtil().subtract(1, 'day').endOf('day'); | |
98 | + return [startDate, endDate]; | |
99 | + }, | |
100 | + DAY_BEFORE_YESTERDAY: () => { | |
101 | + const startDate = dateUtil().subtract(2, 'day').startOf('day'); | |
102 | + const endDate = dateUtil().subtract(2, 'day').endOf('day'); | |
103 | + return [startDate, endDate]; | |
104 | + }, | |
105 | + THIS_DAY_LAST_WEEK: () => { | |
106 | + const startDate = dateUtil().subtract(7, 'day').startOf('day'); | |
107 | + const endDate = dateUtil().subtract(7, 'day').endOf('day'); | |
108 | + return [startDate, endDate]; | |
109 | + }, | |
110 | + PREVIOUS_WEEK_SUN_SAT: () => { | |
111 | + const startDate = dateUtil() | |
112 | + .subtract(1, 'week') | |
113 | + .startOf('week') | |
114 | + .subtract(1, 'day') | |
115 | + .startOf('day'); | |
116 | + const endDate = dateUtil().subtract(1, 'week').endOf('week').subtract(1, 'day').endOf('day'); | |
117 | + return [startDate, endDate]; | |
118 | + }, | |
119 | + PREVIOUS_WEEK_MON_SUN: () => { | |
120 | + const startDate = dateUtil().subtract(1, 'week').startOf('week'); | |
121 | + const endDate = dateUtil().subtract(1, 'week').endOf('week'); | |
122 | + return [startDate, endDate]; | |
123 | + }, | |
124 | + PREVIOUS_MONTH: () => { | |
125 | + const startDate = dateUtil().subtract(1, 'month').startOf('month'); | |
126 | + const endDate = dateUtil().subtract(1, 'month').endOf('month'); | |
127 | + return [startDate, endDate]; | |
128 | + }, | |
129 | + PREVIOUS_YEAR: () => { | |
130 | + const startDate = dateUtil().subtract(1, 'year').startOf('year'); | |
131 | + const endDate = dateUtil().subtract(1, 'year').endOf('year'); | |
132 | + return [startDate, endDate]; | |
133 | + }, | |
134 | + CURRENT_HOUR: () => { | |
135 | + const startDate = dateUtil().startOf('hour'); | |
136 | + const endDate = dateUtil().endOf('hour'); | |
137 | + return [startDate, endDate]; | |
138 | + }, | |
139 | + CURRENT_DAY: () => { | |
140 | + const startDate = dateUtil().startOf('day'); | |
141 | + const endDate = dateUtil().endOf('day'); | |
142 | + return [startDate, endDate]; | |
143 | + }, | |
144 | + CURRENT_DAY_SO_FAR: () => { | |
145 | + const startDate = dateUtil().startOf('day'); | |
146 | + const endDate = dateUtil(); | |
147 | + return [startDate, endDate]; | |
148 | + }, | |
149 | + CURRENT_WEEK_SUN_SAT: () => { | |
150 | + const startDate = dateUtil().startOf('week').subtract(1, 'day').startOf('day'); | |
151 | + const endDate = dateUtil().endOf('week').subtract(1, 'day').endOf('day'); | |
152 | + return [startDate, endDate]; | |
153 | + }, | |
154 | + CURRENT_WEEK_MON_SUN: () => { | |
155 | + const startDate = dateUtil().startOf('week'); | |
156 | + const endDate = dateUtil().endOf('week'); | |
157 | + return [startDate, endDate]; | |
158 | + }, | |
159 | + CURRENT_WEEK_SO_FAR_SUN_SAT: () => { | |
160 | + const startDate = dateUtil().startOf('week').subtract(1, 'day').startOf('day'); | |
161 | + const endDate = dateUtil(); | |
162 | + return [startDate, endDate]; | |
163 | + }, | |
164 | + CURRENT_WEEK_SO_FAR_MON_SUN: () => { | |
165 | + const startDate = dateUtil().startOf('week'); | |
166 | + const endDate = dateUtil(); | |
167 | + return [startDate, endDate]; | |
168 | + }, | |
169 | + CURRENT_MONTH: () => { | |
170 | + const startDate = dateUtil().startOf('month'); | |
171 | + const endDate = dateUtil().endOf('month'); | |
172 | + return [startDate, endDate]; | |
173 | + }, | |
174 | + CURRENT_MONTH_SO_FAR: () => { | |
175 | + const startDate = dateUtil().startOf('month'); | |
176 | + const endDate = dateUtil(); | |
177 | + return [startDate, endDate]; | |
178 | + }, | |
179 | + CURRENT_YEAR: () => { | |
180 | + const startDate = dateUtil().startOf('year'); | |
181 | + const endDate = dateUtil().endOf('year'); | |
182 | + return [startDate, endDate]; | |
183 | + }, | |
184 | + CURRENT_YEAR_SO_FAR: () => { | |
185 | + const startDate = dateUtil().startOf('year'); | |
186 | + const endDate = dateUtil(); | |
187 | + return [startDate, endDate]; | |
188 | + }, | |
189 | + }; | |
190 | + return mapping?.[value]?.() || []; | |
191 | +}; | ... | ... |
1 | +export { default as RangePickerExtra } from './index.vue'; | ... | ... |
1 | +<script setup lang="ts"> | |
2 | + import { Button, Popover, Select, Switch, InputNumber } from 'ant-design-vue'; | |
3 | + import { reactive, ref, unref } from 'vue'; | |
4 | + import { | |
5 | + DateShortcutOptionEnum, | |
6 | + getShortcutOptionValue, | |
7 | + latestOptions, | |
8 | + shortcutOptions, | |
9 | + } from './config'; | |
10 | + import { getPopupContainer } from '/@/utils'; | |
11 | + import { dateUtil } from '/@/utils/dateUtil'; | |
12 | + | |
13 | + const emit = defineEmits<{ | |
14 | + (eventName: 'change', date: moment.Moment[]): void; | |
15 | + }>(); | |
16 | + | |
17 | + const mode = ref(false); | |
18 | + | |
19 | + const latestPopoverVisible = ref(false); | |
20 | + | |
21 | + const latestSelect = ref(); | |
22 | + | |
23 | + const advancedLatest = reactive({ | |
24 | + days: 0, | |
25 | + hours: 0, | |
26 | + minutes: 0, | |
27 | + seconds: 0, | |
28 | + }); | |
29 | + | |
30 | + const getAdvancedLatest = () => { | |
31 | + const startDate = Object.keys(advancedLatest).reduce((prev, next) => { | |
32 | + return prev.subtract(advancedLatest[next], next); | |
33 | + }, dateUtil()); | |
34 | + return [startDate, dateUtil()]; | |
35 | + }; | |
36 | + | |
37 | + const getLatestSelect = () => { | |
38 | + const selected = latestOptions.find((item) => item.value === unref(latestSelect))!; | |
39 | + if (!selected) return []; | |
40 | + const startDate = dateUtil().subtract(selected.unitValue, selected.unit); | |
41 | + return [startDate, dateUtil()]; | |
42 | + }; | |
43 | + | |
44 | + const handleUpdateDate = () => { | |
45 | + emit('change', unref(mode) ? getAdvancedLatest() : getLatestSelect()); | |
46 | + latestPopoverVisible.value = false; | |
47 | + }; | |
48 | + | |
49 | + const shortcutOptionPopoverVisible = ref(false); | |
50 | + | |
51 | + const shortcutOptionSelect = ref<DateShortcutOptionEnum>(); | |
52 | + | |
53 | + const handleShortcutOptionUpdate = () => { | |
54 | + unref(shortcutOptionSelect) && | |
55 | + emit('change', getShortcutOptionValue(unref(shortcutOptionSelect)!)); | |
56 | + shortcutOptionPopoverVisible.value = false; | |
57 | + }; | |
58 | +</script> | |
59 | + | |
60 | +<template> | |
61 | + <section class="h-full items-center flex gap-2 h-9"> | |
62 | + <Popover | |
63 | + v-model:visible="latestPopoverVisible" | |
64 | + trigger="click" | |
65 | + :overlayStyle="{ zIndex: 9999 }" | |
66 | + overlayClassName="range-picker-extra-latest-popover" | |
67 | + > | |
68 | + <template #content> | |
69 | + <main class="w-90 p-4"> | |
70 | + <div class="flex gap-3 items-end"> | |
71 | + <div v-if="!mode" class="w-full"> | |
72 | + <Select | |
73 | + v-model:value="latestSelect" | |
74 | + class="w-full border-b" | |
75 | + :getPopupContainer="getPopupContainer" | |
76 | + placeholder="请选择区间" | |
77 | + :bordered="false" | |
78 | + :options="latestOptions" | |
79 | + /> | |
80 | + </div> | |
81 | + | |
82 | + <div v-if="mode" class="w-full flex gap-1"> | |
83 | + <div class="w-1/4"> | |
84 | + <div>天</div> | |
85 | + <InputNumber v-model:value="advancedLatest.days" :min="0" :precision="0" /> | |
86 | + </div> | |
87 | + <div class="w-1/4"> | |
88 | + <div>小时</div> | |
89 | + <InputNumber v-model:value="advancedLatest.hours" :min="0" :precision="0" /> | |
90 | + </div> | |
91 | + <div class="w-1/4"> | |
92 | + <div>分钟</div> | |
93 | + <InputNumber v-model:value="advancedLatest.minutes" :min="0" :precision="0" /> | |
94 | + </div> | |
95 | + <div class="w-1/4"> | |
96 | + <div>秒</div> | |
97 | + <InputNumber v-model:value="advancedLatest.seconds" :min="0" :precision="0" /> | |
98 | + </div> | |
99 | + </div> | |
100 | + | |
101 | + <div> | |
102 | + <div class="h-6 text-center">高级</div> | |
103 | + <Switch v-model:checked="mode" /> | |
104 | + </div> | |
105 | + </div> | |
106 | + <div class="w-full flex mt-4 gap-4 justify-end"> | |
107 | + <Button size="small" @click="latestPopoverVisible = false"> 取消</Button> | |
108 | + <Button size="small" type="primary" @click="handleUpdateDate"> 更新</Button> | |
109 | + </div> | |
110 | + </main> | |
111 | + </template> | |
112 | + <Button type="primary" size="small" @click="latestPopoverVisible = true">最后</Button> | |
113 | + </Popover> | |
114 | + | |
115 | + <Popover | |
116 | + v-model:visible="shortcutOptionPopoverVisible" | |
117 | + trigger="click" | |
118 | + :overlayStyle="{ zIndex: 9999 }" | |
119 | + overlayClassName="range-picker-extra-shortcut-popover" | |
120 | + > | |
121 | + <template #content> | |
122 | + <main class="w-90 p-4"> | |
123 | + <div> | |
124 | + <Select | |
125 | + v-model:value="shortcutOptionSelect" | |
126 | + class="w-full border-b" | |
127 | + :getPopupContainer="getPopupContainer" | |
128 | + placeholder="请选择区间" | |
129 | + :bordered="false" | |
130 | + :options="shortcutOptions" | |
131 | + /> | |
132 | + </div> | |
133 | + <div class="w-full flex mt-4 gap-4 justify-end"> | |
134 | + <Button size="small" @click="shortcutOptionPopoverVisible = false"> 取消</Button> | |
135 | + <Button size="small" type="primary" @click="handleShortcutOptionUpdate"> 更新</Button> | |
136 | + </div> | |
137 | + </main> | |
138 | + </template> | |
139 | + <Button type="primary" size="small" @click="shortcutOptionPopoverVisible = true"> | |
140 | + 快捷选择 | |
141 | + </Button> | |
142 | + </Popover> | |
143 | + </section> | |
144 | +</template> | |
145 | + | |
146 | +<style lang="less"> | |
147 | + .range-picker-extra-latest-popover { | |
148 | + .ant-input-number { | |
149 | + min-width: fit-content; | |
150 | + width: 100%; | |
151 | + } | |
152 | + } | |
153 | +</style> | ... | ... |
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | import { useForm, BasicForm } from '/@/components/Form'; |
10 | 10 | import { BottomFormSchemas, TopFormSchemas } from '../CreateNodeModal/config'; |
11 | 11 | import { toRaw, unref } from 'vue'; |
12 | - import { BasicEvents } from '../BasicEvents'; | |
12 | + import { BasicEvents } from './BasicEvents'; | |
13 | 13 | |
14 | 14 | const [topFormRegister, topFormActionType] = useForm({ |
15 | 15 | schemas: TopFormSchemas, |
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | visible, |
26 | 26 | spinning, |
27 | 27 | nodeData, |
28 | + elementInfo, | |
28 | 29 | getComponentKey, |
29 | 30 | shadowComponent, |
30 | 31 | createComponentEl, |
... | ... | @@ -113,7 +114,7 @@ |
113 | 114 | </Spin> |
114 | 115 | </Tabs.TabPane> |
115 | 116 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.EVENT]" :key="TabsPanelEnum.EVENT"> |
116 | - <BasicEvents /> | |
117 | + <BasicEvents :elementInfo="elementInfo" /> | |
117 | 118 | </Tabs.TabPane> |
118 | 119 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.HELP]" :key="TabsPanelEnum.HELP"> |
119 | 120 | <HelpMessage :nodeData="nodeData" /> | ... | ... |