Showing
31 changed files
with
1417 additions
and
189 deletions
@@ -6,6 +6,7 @@ import { RuleChainType } from '/@/views/rule/designer/types/ruleNode'; | @@ -6,6 +6,7 @@ import { RuleChainType } from '/@/views/rule/designer/types/ruleNode'; | ||
6 | enum Api { | 6 | enum Api { |
7 | SAVE = '/ruleChain/metadata', | 7 | SAVE = '/ruleChain/metadata', |
8 | GET_RULE_CHAINES = '/ruleChains', | 8 | GET_RULE_CHAINES = '/ruleChains', |
9 | + GET_RULE_NODE_EVENTS = '/events/RULE_NODE', | ||
9 | } | 10 | } |
10 | 11 | ||
11 | export const getRuleChainData = (id: string) => { | 12 | export const getRuleChainData = (id: string) => { |
@@ -38,3 +39,18 @@ export const getRuleChains = (params: Recordable) => { | @@ -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,6 +10,11 @@ interface OptionsType { | ||
10 | type: ElementsTypeEnum; | 10 | type: ElementsTypeEnum; |
11 | } | 11 | } |
12 | 12 | ||
13 | +export interface ElementInfo { | ||
14 | + id: string; | ||
15 | + type: ElementsTypeEnum; | ||
16 | +} | ||
17 | + | ||
13 | export function useAwaitPopupWindowBindData( | 18 | export function useAwaitPopupWindowBindData( |
14 | options: OptionsType = { mode: DataActionModeEnum.CREATE, type: ElementsTypeEnum.NODE } | 19 | options: OptionsType = { mode: DataActionModeEnum.CREATE, type: ElementsTypeEnum.NODE } |
15 | ) { | 20 | ) { |
@@ -29,6 +34,8 @@ export function useAwaitPopupWindowBindData( | @@ -29,6 +34,8 @@ export function useAwaitPopupWindowBindData( | ||
29 | 34 | ||
30 | const shadowComponent = shallowRef<Nullable<Component>>(); | 35 | const shadowComponent = shallowRef<Nullable<Component>>(); |
31 | 36 | ||
37 | + const elementInfo = ref<ElementInfo>(); | ||
38 | + | ||
32 | const getNodeSetValue = computed(() => { | 39 | const getNodeSetValue = computed(() => { |
33 | return unref(mode) === DataActionModeEnum.CREATE | 40 | return unref(mode) === DataActionModeEnum.CREATE |
34 | ? unref(nodeData)?.config?.configurationDescriptor.nodeDefinition.defaultConfiguration | 41 | ? unref(nodeData)?.config?.configurationDescriptor.nodeDefinition.defaultConfiguration |
@@ -68,8 +75,10 @@ export function useAwaitPopupWindowBindData( | @@ -68,8 +75,10 @@ export function useAwaitPopupWindowBindData( | ||
68 | 75 | ||
69 | const open = async ( | 76 | const open = async ( |
70 | nodeData: NodeData, | 77 | nodeData: NodeData, |
71 | - edgeData?: EdgeData | 78 | + edgeData?: EdgeData, |
79 | + _elementInfo?: ElementInfo | ||
72 | ): Promise<AwaitPopupWindowReturnDataType> => { | 80 | ): Promise<AwaitPopupWindowReturnDataType> => { |
81 | + elementInfo.value = _elementInfo; | ||
73 | await handleFetchComponent(nodeData, edgeData); | 82 | await handleFetchComponent(nodeData, edgeData); |
74 | return new Promise((_resolve) => { | 83 | return new Promise((_resolve) => { |
75 | visible.value = true; | 84 | visible.value = true; |
@@ -113,6 +122,7 @@ export function useAwaitPopupWindowBindData( | @@ -113,6 +122,7 @@ export function useAwaitPopupWindowBindData( | ||
113 | visible, | 122 | visible, |
114 | nodeData, | 123 | nodeData, |
115 | spinning, | 124 | spinning, |
125 | + elementInfo, | ||
116 | shadowComponent, | 126 | shadowComponent, |
117 | createComponentEl, | 127 | createComponentEl, |
118 | getComponentKey, | 128 | getComponentKey, |
@@ -10,7 +10,7 @@ import type { Ref } from 'vue'; | @@ -10,7 +10,7 @@ import type { Ref } from 'vue'; | ||
10 | import { markRaw, toRaw, unref } from 'vue'; | 10 | import { markRaw, toRaw, unref } from 'vue'; |
11 | import { isFunction } from 'lodash-es'; | 11 | import { isFunction } from 'lodash-es'; |
12 | import type { CreateNodeModal } from '../src/components/CreateNodeModal'; | 12 | import type { CreateNodeModal } from '../src/components/CreateNodeModal'; |
13 | -import { EdgeTypeEnum, NodeTypeEnum } from '../enum'; | 13 | +import { EdgeTypeEnum, ElementsTypeEnum, NodeTypeEnum } from '../enum'; |
14 | import { BasicEdge, BasicNode } from '../src/components'; | 14 | import { BasicEdge, BasicNode } from '../src/components'; |
15 | import type { EdgeData, NodeData } from '../types/node'; | 15 | import type { EdgeData, NodeData } from '../types/node'; |
16 | import type { CreateEdgeModal } from '../src/components/CreateEdgeModal'; | 16 | import type { CreateEdgeModal } from '../src/components/CreateEdgeModal'; |
@@ -126,10 +126,11 @@ export function useRuleFlow(options: UseRuleFlowOptionsType) { | @@ -126,10 +126,11 @@ export function useRuleFlow(options: UseRuleFlowOptionsType) { | ||
126 | 126 | ||
127 | onNodeDoubleClick(async ({ node }) => { | 127 | onNodeDoubleClick(async ({ node }) => { |
128 | if ((node.data as NodeData).config?.disableAction) return; | 128 | if ((node.data as NodeData).config?.disableAction) return; |
129 | - | ||
130 | const { flag, data } = | 129 | const { flag, data } = |
131 | (await unref(updateNodeDrawerActionType)?.open( | 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 | if (!flag) return; | 136 | if (!flag) return; |
@@ -146,7 +147,8 @@ export function useRuleFlow(options: UseRuleFlowOptionsType) { | @@ -146,7 +147,8 @@ export function useRuleFlow(options: UseRuleFlowOptionsType) { | ||
146 | const { flag, data } = | 147 | const { flag, data } = |
147 | (await unref(updateEdgeDrawerActionType)?.open( | 148 | (await unref(updateEdgeDrawerActionType)?.open( |
148 | toRaw(unref(edge.sourceNode?.data as unknown as NodeData)), | 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 | if (!flag) return; | 154 | if (!flag) return; |
1 | <script setup lang="ts"> | 1 | <script setup lang="ts"> |
2 | + import { Spin } from 'ant-design-vue'; | ||
2 | import { Background, BackgroundVariant } from '@vue-flow/background'; | 3 | import { Background, BackgroundVariant } from '@vue-flow/background'; |
3 | import { Controls } from '@vue-flow/controls'; | 4 | import { Controls } from '@vue-flow/controls'; |
4 | import { Panel, PanelPosition, VueFlow } from '@vue-flow/core'; | 5 | import { Panel, PanelPosition, VueFlow } from '@vue-flow/core'; |
@@ -34,6 +35,7 @@ | @@ -34,6 +35,7 @@ | ||
34 | const elements = ref([]); | 35 | const elements = ref([]); |
35 | 36 | ||
36 | const { | 37 | const { |
38 | + loading, | ||
37 | changeMarker, | 39 | changeMarker, |
38 | getCurrentPageMetaData, | 40 | getCurrentPageMetaData, |
39 | triggerChange, | 41 | triggerChange, |
@@ -88,66 +90,68 @@ | @@ -88,66 +90,68 @@ | ||
88 | <main ref="rootElRef" class="w-full h-full flex relative" @drop="handleOnDrop"> | 90 | <main ref="rootElRef" class="w-full h-full flex relative" @drop="handleOnDrop"> |
89 | <Sidebar /> | 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 | <button | 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 | </button> | 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 | <CreateNodeModal ref="createNodeModalActionType" :get-container="handleGetContainer" /> | 156 | <CreateNodeModal ref="createNodeModalActionType" :get-container="handleGetContainer" /> |
153 | <CreateEdgeModal ref="createEdgeModalActionType" :get-container="handleGetContainer" /> | 157 | <CreateEdgeModal ref="createEdgeModalActionType" :get-container="handleGetContainer" /> |
@@ -162,3 +166,11 @@ | @@ -162,3 +166,11 @@ | ||
162 | box-shadow: 0 3px 5px -1px #0003, 0 6px 10px 0 #00000024, 0 1px 18px 0 #0000001f; | 166 | box-shadow: 0 3px 5px -1px #0003, 0 6px 10px 0 #00000024, 0 1px 18px 0 #0000001f; |
163 | } | 167 | } |
164 | </style> | 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 +6,7 @@ | ||
6 | import { useConnectionFocus } from '../../../hook/useConnectionFocus'; | 6 | import { useConnectionFocus } from '../../../hook/useConnectionFocus'; |
7 | import { useFlowContext } from '../../../hook/useFlowContext'; | 7 | import { useFlowContext } from '../../../hook/useFlowContext'; |
8 | import { useTextWidth } from '../../../hook/useTextWidth'; | 8 | import { useTextWidth } from '../../../hook/useTextWidth'; |
9 | + import { ElementsTypeEnum } from '../../../enum'; | ||
9 | 10 | ||
10 | const props = defineProps<EdgeProps>(); | 11 | const props = defineProps<EdgeProps>(); |
11 | 12 | ||
@@ -31,7 +32,8 @@ | @@ -31,7 +32,8 @@ | ||
31 | const { flag, data } = | 32 | const { flag, data } = |
32 | (await unref(updateEdgeDrawerActionType)?.open( | 33 | (await unref(updateEdgeDrawerActionType)?.open( |
33 | toRaw(unref(props.sourceNode?.data as unknown as NodeData)), | 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 | if (!flag) return; | 39 | if (!flag) return; |
@@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
5 | import { computed, toRaw, unref } from 'vue'; | 5 | import { computed, toRaw, unref } from 'vue'; |
6 | import { useFlowContext } from '../../../hook/useFlowContext'; | 6 | import { useFlowContext } from '../../../hook/useFlowContext'; |
7 | import type { NodeData } from '../../../types/node'; | 7 | import type { NodeData } from '../../../types/node'; |
8 | + import { ElementsTypeEnum } from '../../../enum'; | ||
8 | 9 | ||
9 | const props = defineProps<NodeProps>(); | 10 | const props = defineProps<NodeProps>(); |
10 | 11 | ||
@@ -14,7 +15,10 @@ | @@ -14,7 +15,10 @@ | ||
14 | 15 | ||
15 | const handleOpenEdit = async () => { | 16 | const handleOpenEdit = async () => { |
16 | const { flag, data } = | 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 | if (!flag) return; | 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,7 +9,7 @@ | ||
9 | import { useForm, BasicForm } from '/@/components/Form'; | 9 | import { useForm, BasicForm } from '/@/components/Form'; |
10 | import { BottomFormSchemas, TopFormSchemas } from '../CreateNodeModal/config'; | 10 | import { BottomFormSchemas, TopFormSchemas } from '../CreateNodeModal/config'; |
11 | import { toRaw, unref } from 'vue'; | 11 | import { toRaw, unref } from 'vue'; |
12 | - import { BasicEvents } from '../BasicEvents'; | 12 | + import { BasicEvents } from './BasicEvents'; |
13 | 13 | ||
14 | const [topFormRegister, topFormActionType] = useForm({ | 14 | const [topFormRegister, topFormActionType] = useForm({ |
15 | schemas: TopFormSchemas, | 15 | schemas: TopFormSchemas, |
@@ -25,6 +25,7 @@ | @@ -25,6 +25,7 @@ | ||
25 | visible, | 25 | visible, |
26 | spinning, | 26 | spinning, |
27 | nodeData, | 27 | nodeData, |
28 | + elementInfo, | ||
28 | getComponentKey, | 29 | getComponentKey, |
29 | shadowComponent, | 30 | shadowComponent, |
30 | createComponentEl, | 31 | createComponentEl, |
@@ -113,7 +114,7 @@ | @@ -113,7 +114,7 @@ | ||
113 | </Spin> | 114 | </Spin> |
114 | </Tabs.TabPane> | 115 | </Tabs.TabPane> |
115 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.EVENT]" :key="TabsPanelEnum.EVENT"> | 116 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.EVENT]" :key="TabsPanelEnum.EVENT"> |
116 | - <BasicEvents /> | 117 | + <BasicEvents :elementInfo="elementInfo" /> |
117 | </Tabs.TabPane> | 118 | </Tabs.TabPane> |
118 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.HELP]" :key="TabsPanelEnum.HELP"> | 119 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.HELP]" :key="TabsPanelEnum.HELP"> |
119 | <HelpMessage :nodeData="nodeData" /> | 120 | <HelpMessage :nodeData="nodeData" /> |