@fecp/designer 5.5.101 → 5.5.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/designer/package.json.mjs +1 -1
- package/es/designer/src/components/DocumentParam.vue.mjs +1 -1
- package/es/designer/src/components/ParamsConfig.vue2.mjs +1 -1
- package/es/designer/src/layout/aside/HiddenFieldDialog.vue.mjs +1 -1
- package/es/designer/src/packages/advancedFilter/ValueInput.vue2.mjs +1 -1
- package/es/designer/src/packages/dataLinkage/index.vue.mjs +1 -1
- package/es/designer/src/packages/dialogGlobal/index.vue.mjs +1 -1
- package/es/designer/src/packages/eventFlow/dialog/action/RiskSch.vue.mjs +1 -1
- package/es/designer/src/packages/form/property/approvalHistory.vue.mjs +1 -1
- package/es/designer/src/packages/form/property/contract.vue.mjs +1 -1
- package/es/designer/src/packages/form/property/subForm.vue.mjs +1 -1
- package/es/designer/src/packages/prod/index.vue.mjs +1 -1
- package/es/designer/src/packages/table/headerBtn.vue.mjs +1 -1
- package/es/designer.css +357 -68
- package/es/packages/mobile/index.mjs +4 -0
- package/es/packages/mobile/src/components/all.mjs +4 -0
- package/es/packages/mobile/src/components/custom/appDetail/AppDetail.vue.mjs +30 -7
- package/es/packages/mobile/src/components/custom/approvalBar/ApprovalBar.vue.mjs +191 -0
- package/es/packages/mobile/src/components/custom/approvalBar/index.mjs +10 -0
- package/es/packages/mobile/src/components/custom/approvalList/ApprovalList.vue.mjs +391 -0
- package/es/packages/mobile/src/components/custom/approvalList/index.mjs +10 -0
- package/es/packages/mobile/src/components/dataDisplay/cardList/CardList.vue.mjs +2 -18
- package/es/packages/mobile/src/components/dataDisplay/table/Table.vue.mjs +41 -9
- package/es/packages/mobile/src/components/form/field/Field.vue.mjs +38 -26
- package/es/packages/mobile/src/components/form/fieldArea/FieldArea.vue.mjs +4 -2
- package/es/packages/mobile/src/components/form/fieldCalendarPicker/FieldCalendarPicker.vue.mjs +1 -1
- package/es/packages/mobile/src/components/form/fieldCascaderPicker/fieldCascaderPicker.vue.mjs +1 -1
- package/es/packages/mobile/src/components/form/fieldDatePicker/FieldDatePicker.vue.mjs +1 -1
- package/es/packages/mobile/src/components/form/fieldDateTimePicker/FieldDateTimePicker.vue.mjs +1 -1
- package/es/packages/mobile/src/components/form/fieldIndustry/FieldIndustry.vue.mjs +38 -27
- package/es/packages/mobile/src/components/form/fieldPicker/FieldPicker.vue.mjs +58 -41
- package/es/packages/mobile/src/components/form/fieldTimePicker/FieldTimePicker.vue.mjs +1 -1
- package/es/packages/mobile/src/components/navigation/tabs/Tabs.vue.mjs +8 -3
- package/es/packages/mobile/src/composables/usePageEvents.mjs +80 -0
- package/es/packages/mobile/src/index.vue.mjs +8 -5
- package/es/packages/mobile/src/page.vue.mjs +150 -19
- package/es/packages/mobile/src/utils/datasource.mjs +12 -1
- package/es/packages/mobile/src/utils/eventFlow/actionHandlers.mjs +852 -0
- package/es/packages/mobile/src/utils/eventFlow/eventFlowHandler.mjs +94 -0
- package/es/packages/mobile/src/utils/eventFlowParser.mjs +396 -0
- package/es/packages/mobile/src/utils/formatterUtil.mjs +1 -0
- package/es/packages/mobile/src/utils/parseFilterConfig.mjs +98 -0
- package/es/packages/vue/src/components/table/Table.vue.mjs +11 -1
- package/lib/designer/package.json.js +1 -1
- package/lib/designer/src/components/DocumentParam.vue.js +1 -1
- package/lib/designer/src/components/ParamsConfig.vue2.js +1 -1
- package/lib/designer/src/layout/aside/HiddenFieldDialog.vue.js +1 -1
- package/lib/designer/src/packages/advancedFilter/ValueInput.vue2.js +1 -1
- package/lib/designer/src/packages/dataLinkage/index.vue.js +1 -1
- package/lib/designer/src/packages/dialogGlobal/index.vue.js +1 -1
- package/lib/designer/src/packages/eventFlow/dialog/action/RiskSch.vue.js +1 -1
- package/lib/designer/src/packages/form/property/approvalHistory.vue.js +1 -1
- package/lib/designer/src/packages/form/property/contract.vue.js +1 -1
- package/lib/designer/src/packages/form/property/subForm.vue.js +1 -1
- package/lib/designer/src/packages/prod/index.vue.js +1 -1
- package/lib/designer/src/packages/table/headerBtn.vue.js +1 -1
- package/lib/designer.css +357 -68
- package/lib/packages/mobile/index.js +6 -2
- package/lib/packages/mobile/src/components/all.js +4 -0
- package/lib/packages/mobile/src/components/custom/appDetail/AppDetail.vue.js +29 -6
- package/lib/packages/mobile/src/components/custom/approvalBar/ApprovalBar.vue.js +191 -0
- package/lib/packages/mobile/src/components/custom/approvalBar/index.js +10 -0
- package/lib/packages/mobile/src/components/custom/approvalList/ApprovalList.vue.js +391 -0
- package/lib/packages/mobile/src/components/custom/approvalList/index.js +10 -0
- package/lib/packages/mobile/src/components/dataDisplay/cardList/CardList.vue.js +2 -18
- package/lib/packages/mobile/src/components/dataDisplay/table/Table.vue.js +41 -9
- package/lib/packages/mobile/src/components/form/field/Field.vue.js +37 -25
- package/lib/packages/mobile/src/components/form/fieldArea/FieldArea.vue.js +4 -2
- package/lib/packages/mobile/src/components/form/fieldCalendarPicker/FieldCalendarPicker.vue.js +1 -1
- package/lib/packages/mobile/src/components/form/fieldCascaderPicker/fieldCascaderPicker.vue.js +1 -1
- package/lib/packages/mobile/src/components/form/fieldDatePicker/FieldDatePicker.vue.js +1 -1
- package/lib/packages/mobile/src/components/form/fieldDateTimePicker/FieldDateTimePicker.vue.js +1 -1
- package/lib/packages/mobile/src/components/form/fieldIndustry/FieldIndustry.vue.js +37 -26
- package/lib/packages/mobile/src/components/form/fieldPicker/FieldPicker.vue.js +57 -40
- package/lib/packages/mobile/src/components/form/fieldTimePicker/FieldTimePicker.vue.js +1 -1
- package/lib/packages/mobile/src/components/navigation/tabs/Tabs.vue.js +8 -3
- package/lib/packages/mobile/src/composables/usePageEvents.js +80 -0
- package/lib/packages/mobile/src/index.vue.js +8 -5
- package/lib/packages/mobile/src/page.vue.js +149 -18
- package/lib/packages/mobile/src/utils/datasource.js +14 -3
- package/lib/packages/mobile/src/utils/eventFlow/actionHandlers.js +852 -0
- package/lib/packages/mobile/src/utils/eventFlow/eventFlowHandler.js +94 -0
- package/lib/packages/mobile/src/utils/eventFlowParser.js +396 -0
- package/lib/packages/mobile/src/utils/formatterUtil.js +1 -0
- package/lib/packages/mobile/src/utils/parseFilterConfig.js +98 -0
- package/lib/packages/vue/src/components/table/Table.vue.js +11 -1
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createEventFlowParser } from "../eventFlowParser.mjs";
|
|
2
|
+
async function executeEventFlow(params) {
|
|
3
|
+
const {
|
|
4
|
+
eventFlow,
|
|
5
|
+
fields = [],
|
|
6
|
+
instance = null,
|
|
7
|
+
localConfig = {},
|
|
8
|
+
components = {},
|
|
9
|
+
onSuccess,
|
|
10
|
+
onError,
|
|
11
|
+
row,
|
|
12
|
+
item,
|
|
13
|
+
metadata
|
|
14
|
+
} = params;
|
|
15
|
+
if (!eventFlow) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const parser = createEventFlowParser({
|
|
20
|
+
eventFlow,
|
|
21
|
+
fields,
|
|
22
|
+
data: row,
|
|
23
|
+
instance,
|
|
24
|
+
localConfig,
|
|
25
|
+
components,
|
|
26
|
+
metadata
|
|
27
|
+
});
|
|
28
|
+
const result = await parser.start();
|
|
29
|
+
console.log("事件流执行完成:", result);
|
|
30
|
+
parser.destroy();
|
|
31
|
+
if (onSuccess) {
|
|
32
|
+
onSuccess(result, row, item);
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error("事件流执行失败:", error);
|
|
37
|
+
if (onError) {
|
|
38
|
+
onError(error, row, item);
|
|
39
|
+
}
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function createEventFlowHandler(options = {}) {
|
|
44
|
+
const {
|
|
45
|
+
fields = [],
|
|
46
|
+
instance = null,
|
|
47
|
+
onSuccess,
|
|
48
|
+
onError,
|
|
49
|
+
localConfig = {},
|
|
50
|
+
components = {},
|
|
51
|
+
metadata = {}
|
|
52
|
+
} = options;
|
|
53
|
+
return async function handleEvent(row, item, eventConfig) {
|
|
54
|
+
if (eventConfig && eventConfig.eventFlow) {
|
|
55
|
+
return await executeEventFlow({
|
|
56
|
+
eventFlow: eventConfig.eventFlow,
|
|
57
|
+
fields,
|
|
58
|
+
instance,
|
|
59
|
+
localConfig,
|
|
60
|
+
components,
|
|
61
|
+
onSuccess,
|
|
62
|
+
onError,
|
|
63
|
+
row,
|
|
64
|
+
item,
|
|
65
|
+
metadata: { ...metadata, item }
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function getEventHandlers(item, row, eventHandler, eventConfigs) {
|
|
71
|
+
const handlers = {};
|
|
72
|
+
if (!eventConfigs) {
|
|
73
|
+
return handlers;
|
|
74
|
+
}
|
|
75
|
+
eventConfigs.forEach((eventConfig) => {
|
|
76
|
+
if (!eventConfig.name) return;
|
|
77
|
+
const eventName = eventConfig.name.toLowerCase();
|
|
78
|
+
handlers[eventName] = () => eventHandler(row, item, eventConfig);
|
|
79
|
+
});
|
|
80
|
+
return handlers;
|
|
81
|
+
}
|
|
82
|
+
function useEventFlow(options = {}) {
|
|
83
|
+
const handleEvent = createEventFlowHandler(options);
|
|
84
|
+
return {
|
|
85
|
+
handleEvent,
|
|
86
|
+
getEventHandlers: (item, row, eventConfig) => getEventHandlers(item, row, handleEvent, eventConfig)
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
createEventFlowHandler,
|
|
91
|
+
executeEventFlow,
|
|
92
|
+
getEventHandlers,
|
|
93
|
+
useEventFlow
|
|
94
|
+
};
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { checkFilterMatch } from "./parseFilterConfig.mjs";
|
|
2
|
+
import { defaultActionHandlers } from "./eventFlow/actionHandlers.mjs";
|
|
3
|
+
import "../../../../node_modules/element-plus/es/index.mjs";
|
|
4
|
+
import { ElMessage } from "../../../../node_modules/element-plus/es/components/message/index.mjs";
|
|
5
|
+
const NodeType = {
|
|
6
|
+
START: "start",
|
|
7
|
+
END: "end",
|
|
8
|
+
EXCLUSIVE: "exclusive",
|
|
9
|
+
// 独占网关
|
|
10
|
+
CONDITION: "condition",
|
|
11
|
+
// 条件分支
|
|
12
|
+
APPROVAL: "approval"
|
|
13
|
+
// 动作/审批节点
|
|
14
|
+
};
|
|
15
|
+
class EventFlowParser {
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
this.options = options;
|
|
18
|
+
this.eventFlow = options.eventFlow || null;
|
|
19
|
+
this.fields = options.fields || [];
|
|
20
|
+
this.data = options.data || {};
|
|
21
|
+
this.components = options.components || {};
|
|
22
|
+
this.currentNode = null;
|
|
23
|
+
this.isPaused = false;
|
|
24
|
+
this.pausePromise = null;
|
|
25
|
+
this.pauseResolve = null;
|
|
26
|
+
this.pauseReject = null;
|
|
27
|
+
this.executionPath = [];
|
|
28
|
+
this.context = {
|
|
29
|
+
variables: {},
|
|
30
|
+
// 运行时变量
|
|
31
|
+
results: []
|
|
32
|
+
// 每个节点的执行结果
|
|
33
|
+
};
|
|
34
|
+
this.metadata = options.metadata || {};
|
|
35
|
+
this.actionHandlers = {
|
|
36
|
+
...defaultActionHandlers,
|
|
37
|
+
...options.customActionHandlers
|
|
38
|
+
// 允许自定义动作处理器
|
|
39
|
+
};
|
|
40
|
+
this.bindActionHandlers();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 启动事件流
|
|
44
|
+
* @param {Object} data - 数据对象
|
|
45
|
+
* @returns {Promise<Object>} 执行结果
|
|
46
|
+
*/
|
|
47
|
+
async start(data = null) {
|
|
48
|
+
if (data) {
|
|
49
|
+
this.data = data;
|
|
50
|
+
}
|
|
51
|
+
if (!this.eventFlow) {
|
|
52
|
+
throw new Error("事件流配置未设置");
|
|
53
|
+
}
|
|
54
|
+
this.isPaused = false;
|
|
55
|
+
this.pausePromise = null;
|
|
56
|
+
this.pauseResolve = null;
|
|
57
|
+
this.pauseReject = null;
|
|
58
|
+
this.executionPath = [];
|
|
59
|
+
this.context = {
|
|
60
|
+
variables: {},
|
|
61
|
+
results: []
|
|
62
|
+
};
|
|
63
|
+
const startNode = this.eventFlow;
|
|
64
|
+
if (startNode.type !== NodeType.START) {
|
|
65
|
+
throw new Error("事件流缺少开始节点");
|
|
66
|
+
}
|
|
67
|
+
this.currentNode = startNode;
|
|
68
|
+
return await this.executeCurrentNode();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 继续执行(用于从暂停状态恢复)
|
|
72
|
+
* @param {*} resumeData - 恢复时传递的数据(例如confirm的结果)
|
|
73
|
+
* @returns {Promise<Object>}
|
|
74
|
+
*/
|
|
75
|
+
async resume(resumeData = null) {
|
|
76
|
+
if (!this.isPaused || !this.pauseResolve) {
|
|
77
|
+
throw new Error("事件流未处于暂停状态");
|
|
78
|
+
}
|
|
79
|
+
this.isPaused = false;
|
|
80
|
+
this.pauseResolve(resumeData);
|
|
81
|
+
await this.pausePromise;
|
|
82
|
+
return await this.executeCurrentNode();
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 取消执行(用于取消confirm等操作)
|
|
86
|
+
* @param {*} reason - 取消原因
|
|
87
|
+
*/
|
|
88
|
+
cancel(reason = "用户取消") {
|
|
89
|
+
if (!this.isPaused || !this.pauseReject) {
|
|
90
|
+
throw new Error("事件流未处于暂停状态");
|
|
91
|
+
}
|
|
92
|
+
this.isPaused = false;
|
|
93
|
+
this.pauseReject(new Error(reason));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 执行当前节点
|
|
97
|
+
* @returns {Promise<Object>}
|
|
98
|
+
*/
|
|
99
|
+
async executeCurrentNode() {
|
|
100
|
+
if (!this.currentNode) {
|
|
101
|
+
return this.getExecutionResult();
|
|
102
|
+
}
|
|
103
|
+
const node = this.currentNode;
|
|
104
|
+
const nodeResult = {
|
|
105
|
+
id: node.id,
|
|
106
|
+
type: node.type,
|
|
107
|
+
name: node.name,
|
|
108
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
109
|
+
success: true,
|
|
110
|
+
data: null,
|
|
111
|
+
error: null
|
|
112
|
+
};
|
|
113
|
+
try {
|
|
114
|
+
let nextNode = null;
|
|
115
|
+
switch (node.type) {
|
|
116
|
+
case NodeType.START:
|
|
117
|
+
nextNode = await this.executeStartNode(node);
|
|
118
|
+
break;
|
|
119
|
+
case NodeType.END:
|
|
120
|
+
nextNode = await this.executeEndNode(node);
|
|
121
|
+
break;
|
|
122
|
+
case NodeType.EXCLUSIVE:
|
|
123
|
+
nextNode = await this.executeExclusiveNode(node);
|
|
124
|
+
break;
|
|
125
|
+
case NodeType.CONDITION:
|
|
126
|
+
nextNode = await this.executeConditionNode(node);
|
|
127
|
+
break;
|
|
128
|
+
case NodeType.APPROVAL:
|
|
129
|
+
nextNode = await this.executeApprovalNode(node);
|
|
130
|
+
break;
|
|
131
|
+
default:
|
|
132
|
+
throw new Error(`未知的节点类型: ${node.type}`);
|
|
133
|
+
}
|
|
134
|
+
nodeResult.data = this.context.variables[node.id] || null;
|
|
135
|
+
this.context.results.push(nodeResult);
|
|
136
|
+
const pathItem = {
|
|
137
|
+
nodeId: node.id,
|
|
138
|
+
nodeName: node.name,
|
|
139
|
+
nodeType: node.type,
|
|
140
|
+
timestamp: nodeResult.timestamp
|
|
141
|
+
};
|
|
142
|
+
pathItem.actionType = node.actionType;
|
|
143
|
+
pathItem.actionName = node.actionName;
|
|
144
|
+
pathItem.actionResult = nodeResult.data;
|
|
145
|
+
this.executionPath.push(pathItem);
|
|
146
|
+
if (nextNode) {
|
|
147
|
+
this.currentNode = nextNode;
|
|
148
|
+
return await this.executeCurrentNode();
|
|
149
|
+
} else {
|
|
150
|
+
return this.getExecutionResult();
|
|
151
|
+
}
|
|
152
|
+
} catch (error) {
|
|
153
|
+
nodeResult.success = false;
|
|
154
|
+
nodeResult.error = error.message;
|
|
155
|
+
this.context.results.push(nodeResult);
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 执行开始节点
|
|
161
|
+
*/
|
|
162
|
+
async executeStartNode(node) {
|
|
163
|
+
return node.next || null;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 执行结束节点
|
|
167
|
+
*/
|
|
168
|
+
async executeEndNode(node) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 执行独占网关
|
|
173
|
+
* 根据条件选择分支
|
|
174
|
+
*/
|
|
175
|
+
async executeExclusiveNode(node) {
|
|
176
|
+
if (!node.branches || node.branches.length === 0) {
|
|
177
|
+
throw new Error("独占网关没有配置分支");
|
|
178
|
+
}
|
|
179
|
+
let matchedBranch = null;
|
|
180
|
+
let defaultBranch = null;
|
|
181
|
+
for (const branch of node.branches) {
|
|
182
|
+
if (branch.def) {
|
|
183
|
+
defaultBranch = branch;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (await this.checkBranchCondition(branch)) {
|
|
187
|
+
matchedBranch = branch;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (!matchedBranch && defaultBranch) {
|
|
192
|
+
matchedBranch = defaultBranch;
|
|
193
|
+
}
|
|
194
|
+
if (!matchedBranch) {
|
|
195
|
+
throw new Error("没有满足条件的分支,且没有默认分支");
|
|
196
|
+
}
|
|
197
|
+
this.context.variables[node.id] = {
|
|
198
|
+
selectedBranch: matchedBranch.id,
|
|
199
|
+
branchName: matchedBranch.name
|
|
200
|
+
};
|
|
201
|
+
return matchedBranch.next || node.next || null;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* 检查分支条件是否满足
|
|
205
|
+
*/
|
|
206
|
+
async checkBranchCondition(branch) {
|
|
207
|
+
if (!branch.conditions) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
if (branch.def && (!branch.conditions.conditions || branch.conditions.conditions.length === 0)) {
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
return checkFilterMatch(branch.conditions, this.data, this.fields);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 执行条件节点
|
|
217
|
+
*/
|
|
218
|
+
async executeConditionNode(node) {
|
|
219
|
+
return node.next || null;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* 执行动作/审批节点
|
|
223
|
+
*/
|
|
224
|
+
async executeApprovalNode(node) {
|
|
225
|
+
var _a, _b;
|
|
226
|
+
if (!node.actionType) {
|
|
227
|
+
throw new Error("动作节点没有配置动作类型");
|
|
228
|
+
}
|
|
229
|
+
if ((_a = node.advanced) == null ? void 0 : _a.skipCondition) {
|
|
230
|
+
const shouldSkip = checkFilterMatch(
|
|
231
|
+
node.advanced.skipCondition,
|
|
232
|
+
this.data,
|
|
233
|
+
this.fields
|
|
234
|
+
);
|
|
235
|
+
if (shouldSkip) {
|
|
236
|
+
this.context.variables[node.id] = { skipped: true, reason: "满足跳过条件" };
|
|
237
|
+
this.executionPath.push({
|
|
238
|
+
nodeId: node.id,
|
|
239
|
+
nodeType: node.type,
|
|
240
|
+
actionType: node.actionType,
|
|
241
|
+
actionName: node.actionName,
|
|
242
|
+
result: {
|
|
243
|
+
skipped: true,
|
|
244
|
+
reason: "满足跳过条件"
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
return node.next || null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const actionResult = await this.executeAction(node);
|
|
251
|
+
if (actionResult === null) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
this.context.variables[node.id] = {
|
|
255
|
+
actionType: node.actionType,
|
|
256
|
+
actionName: node.actionName,
|
|
257
|
+
result: actionResult
|
|
258
|
+
};
|
|
259
|
+
if (actionResult.success === false) {
|
|
260
|
+
const errorMessage = actionResult.message || "动作执行失败";
|
|
261
|
+
console.error("[EventFlow] 动作执行失败:", errorMessage);
|
|
262
|
+
if (actionResult.shouldShowError !== false) {
|
|
263
|
+
ElMessage.error(errorMessage);
|
|
264
|
+
}
|
|
265
|
+
throw new Error(errorMessage);
|
|
266
|
+
}
|
|
267
|
+
if ((_b = node.advanced) == null ? void 0 : _b.blockCondition) {
|
|
268
|
+
const shouldBlock = checkFilterMatch(
|
|
269
|
+
node.advanced.blockCondition,
|
|
270
|
+
this.data,
|
|
271
|
+
this.fields
|
|
272
|
+
);
|
|
273
|
+
if (shouldBlock) {
|
|
274
|
+
console.log("后续动作被阻止条件拦截");
|
|
275
|
+
this.executionPath.push({
|
|
276
|
+
nodeId: node.id,
|
|
277
|
+
nodeType: node.type,
|
|
278
|
+
actionType: node.actionType,
|
|
279
|
+
actionName: node.actionName,
|
|
280
|
+
result: {
|
|
281
|
+
blocked: true,
|
|
282
|
+
reason: "后续动作被阻止条件拦截"
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return node.next || null;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* 执行动作
|
|
292
|
+
*/
|
|
293
|
+
async executeAction(node) {
|
|
294
|
+
var _a, _b, _c, _d, _e, _f;
|
|
295
|
+
const handler = this.actionHandlers[node.actionType];
|
|
296
|
+
if (!handler) {
|
|
297
|
+
throw new Error(`未找到动作处理器: ${node.actionType}`);
|
|
298
|
+
}
|
|
299
|
+
const context = {
|
|
300
|
+
parser: this,
|
|
301
|
+
instance: (_a = this.options) == null ? void 0 : _a.instance,
|
|
302
|
+
ctx: (_c = (_b = this.options) == null ? void 0 : _b.instance) == null ? void 0 : _c.proxy,
|
|
303
|
+
customActions: (_d = this.options) == null ? void 0 : _d.customActions,
|
|
304
|
+
localConfig: (_e = this.options) == null ? void 0 : _e.localConfig,
|
|
305
|
+
components: this.components,
|
|
306
|
+
metadata: (_f = this.options) == null ? void 0 : _f.metadata
|
|
307
|
+
};
|
|
308
|
+
return await handler(node, this.data, this.fields, context);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* 绑定动作处理器的上下文
|
|
312
|
+
*/
|
|
313
|
+
bindActionHandlers() {
|
|
314
|
+
for (const actionType in this.actionHandlers) {
|
|
315
|
+
if (typeof this.actionHandlers[actionType] === "function") {
|
|
316
|
+
this.actionHandlers[actionType] = this.actionHandlers[actionType].bind(this);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* 暂停事件流执行
|
|
322
|
+
* @returns {Promise} 返回一个 Promise,在 resume 时 resolve
|
|
323
|
+
*/
|
|
324
|
+
async pause() {
|
|
325
|
+
if (this.isPaused) {
|
|
326
|
+
throw new Error("事件流已经处于暂停状态");
|
|
327
|
+
}
|
|
328
|
+
this.isPaused = true;
|
|
329
|
+
this.pausePromise = new Promise((resolve, reject) => {
|
|
330
|
+
this.pauseResolve = resolve;
|
|
331
|
+
this.pauseReject = reject;
|
|
332
|
+
});
|
|
333
|
+
return this.pausePromise;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* 获取执行结果
|
|
337
|
+
*/
|
|
338
|
+
getExecutionResult() {
|
|
339
|
+
return {
|
|
340
|
+
success: true,
|
|
341
|
+
completed: true,
|
|
342
|
+
executionPath: this.executionPath,
|
|
343
|
+
context: this.context,
|
|
344
|
+
data: this.data
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* 获取当前节点信息
|
|
349
|
+
*/
|
|
350
|
+
getCurrentNodeInfo() {
|
|
351
|
+
if (!this.currentNode) {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
id: this.currentNode.id,
|
|
356
|
+
type: this.currentNode.type,
|
|
357
|
+
name: this.currentNode.name,
|
|
358
|
+
isPaused: this.isPaused
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* 注册自定义动作处理器
|
|
363
|
+
* @param {String} actionType - 动作类型
|
|
364
|
+
* @param {Function} handler - 处理器函数 (node, data, fields) => Promise
|
|
365
|
+
*/
|
|
366
|
+
registerActionHandler(actionType, handler) {
|
|
367
|
+
this.actionHandlers[actionType] = handler.bind(this);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* 销毁解析器
|
|
371
|
+
*/
|
|
372
|
+
destroy() {
|
|
373
|
+
if (this.isPaused) {
|
|
374
|
+
this.cancel("解析器被销毁");
|
|
375
|
+
}
|
|
376
|
+
this.eventFlow = null;
|
|
377
|
+
this.fields = [];
|
|
378
|
+
this.data = {};
|
|
379
|
+
this.currentNode = null;
|
|
380
|
+
this.executionPath = [];
|
|
381
|
+
this.context = {
|
|
382
|
+
variables: {},
|
|
383
|
+
results: []
|
|
384
|
+
};
|
|
385
|
+
this.actionHandlers = {};
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function createEventFlowParser(options = {}) {
|
|
389
|
+
return new EventFlowParser(options);
|
|
390
|
+
}
|
|
391
|
+
export {
|
|
392
|
+
EventFlowParser,
|
|
393
|
+
NodeType,
|
|
394
|
+
createEventFlowParser,
|
|
395
|
+
EventFlowParser as default
|
|
396
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { parseSingleParamValue } from "./parseRouteParams.mjs";
|
|
2
|
+
function isDateString(value) {
|
|
3
|
+
if (typeof value !== "string") return false;
|
|
4
|
+
return /^\d{4}\/\d{2}\/\d{2}$/.test(value);
|
|
5
|
+
}
|
|
6
|
+
function compareDate(a, b) {
|
|
7
|
+
return a.localeCompare(b);
|
|
8
|
+
}
|
|
9
|
+
function checkFilterMatch(filterConfig, data, fields = []) {
|
|
10
|
+
if (!filterConfig || !data) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return checkGroupMatch(filterConfig, data, fields);
|
|
14
|
+
}
|
|
15
|
+
function checkGroupMatch(group, data, fields) {
|
|
16
|
+
const { operator, conditions, groups } = group;
|
|
17
|
+
const results = [];
|
|
18
|
+
if (conditions && conditions.length > 0) {
|
|
19
|
+
conditions.forEach((cond) => {
|
|
20
|
+
results.push(checkConditionMatch(cond, data, fields));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (groups && groups.length > 0) {
|
|
24
|
+
groups.forEach((g) => {
|
|
25
|
+
results.push(checkGroupMatch(g, data, fields));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (operator == "and") {
|
|
29
|
+
return results.every((r) => r == true);
|
|
30
|
+
} else {
|
|
31
|
+
return results.some((r) => r == true);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function checkConditionMatch(condition, data, fields) {
|
|
35
|
+
const { field, operator, value } = condition;
|
|
36
|
+
const fieldInfo = fields.find((f) => f.id == field);
|
|
37
|
+
const fieldName = (fieldInfo == null ? void 0 : fieldInfo.fieldName) || field;
|
|
38
|
+
const dataValue = data[fieldName];
|
|
39
|
+
const parsedValue = parseSingleParamValue(value, data, fields);
|
|
40
|
+
switch (operator) {
|
|
41
|
+
case "eq":
|
|
42
|
+
return dataValue == parsedValue;
|
|
43
|
+
case "ne":
|
|
44
|
+
return dataValue != parsedValue;
|
|
45
|
+
case "gt":
|
|
46
|
+
if (isDateString(dataValue) && isDateString(parsedValue)) {
|
|
47
|
+
return compareDate(dataValue, parsedValue) > 0;
|
|
48
|
+
}
|
|
49
|
+
return Number(dataValue) > Number(parsedValue);
|
|
50
|
+
case "gte":
|
|
51
|
+
if (isDateString(dataValue) && isDateString(parsedValue)) {
|
|
52
|
+
return compareDate(dataValue, parsedValue) >= 0;
|
|
53
|
+
}
|
|
54
|
+
return Number(dataValue) >= Number(parsedValue);
|
|
55
|
+
case "lt":
|
|
56
|
+
if (isDateString(dataValue) && isDateString(parsedValue)) {
|
|
57
|
+
return compareDate(dataValue, parsedValue) < 0;
|
|
58
|
+
}
|
|
59
|
+
return Number(dataValue) < Number(parsedValue);
|
|
60
|
+
case "lte":
|
|
61
|
+
if (isDateString(dataValue) && isDateString(parsedValue)) {
|
|
62
|
+
return compareDate(dataValue, parsedValue) <= 0;
|
|
63
|
+
}
|
|
64
|
+
return Number(dataValue) <= Number(parsedValue);
|
|
65
|
+
case "range":
|
|
66
|
+
if (!parsedValue || parsedValue.min == null || parsedValue.max == null) return false;
|
|
67
|
+
if (isDateString(dataValue) && isDateString(parsedValue.min) && isDateString(parsedValue.max)) {
|
|
68
|
+
return compareDate(dataValue, parsedValue.min) >= 0 && compareDate(dataValue, parsedValue.max) <= 0;
|
|
69
|
+
}
|
|
70
|
+
const numValue = Number(dataValue);
|
|
71
|
+
return numValue >= Number(parsedValue.min) && numValue <= Number(parsedValue.max);
|
|
72
|
+
case "contains":
|
|
73
|
+
if (!dataValue || !parsedValue) return false;
|
|
74
|
+
return String(dataValue).toLowerCase().includes(String(parsedValue).toLowerCase());
|
|
75
|
+
case "not_contains":
|
|
76
|
+
if (!dataValue || !parsedValue) return true;
|
|
77
|
+
return !String(dataValue).toLowerCase().includes(String(parsedValue).toLowerCase());
|
|
78
|
+
case "in_any":
|
|
79
|
+
if (!Array.isArray(parsedValue)) {
|
|
80
|
+
return dataValue == parsedValue;
|
|
81
|
+
}
|
|
82
|
+
return parsedValue.some((v) => dataValue == v);
|
|
83
|
+
case "ni_any":
|
|
84
|
+
if (!Array.isArray(parsedValue)) {
|
|
85
|
+
return dataValue != parsedValue;
|
|
86
|
+
}
|
|
87
|
+
return !parsedValue.some((v) => dataValue == v);
|
|
88
|
+
case "is_null":
|
|
89
|
+
return dataValue == null || dataValue == void 0 || dataValue == "";
|
|
90
|
+
case "is_not_null":
|
|
91
|
+
return dataValue !== null && dataValue !== void 0 && dataValue !== "";
|
|
92
|
+
default:
|
|
93
|
+
return dataValue == parsedValue;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
checkFilterMatch
|
|
98
|
+
};
|
|
@@ -846,6 +846,16 @@ const _sfc_main = /* @__PURE__ */ Object.assign({
|
|
|
846
846
|
},
|
|
847
847
|
{ deep: true }
|
|
848
848
|
);
|
|
849
|
+
watch(
|
|
850
|
+
() => props.initHiddenData,
|
|
851
|
+
(newVal, oldVal) => {
|
|
852
|
+
if (props.canLoadBySearchData && dataSourceManager.value && !isEqual(newVal, oldVal)) {
|
|
853
|
+
dataSourceManager.value.updateInitSearchData(newVal);
|
|
854
|
+
refresh();
|
|
855
|
+
}
|
|
856
|
+
},
|
|
857
|
+
{ deep: true }
|
|
858
|
+
);
|
|
849
859
|
onUnmounted(() => {
|
|
850
860
|
if (dataSourceManager.value) {
|
|
851
861
|
dataSourceManager.value.destroy();
|
|
@@ -988,7 +998,7 @@ const _sfc_main = /* @__PURE__ */ Object.assign({
|
|
|
988
998
|
};
|
|
989
999
|
}
|
|
990
1000
|
});
|
|
991
|
-
const _Table = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
1001
|
+
const _Table = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-cf0b025d"]]);
|
|
992
1002
|
export {
|
|
993
1003
|
_Table as default
|
|
994
1004
|
};
|
|
@@ -11,7 +11,7 @@ require("../../../node_modules/element-plus/es/index.js");
|
|
|
11
11
|
;/* empty css */
|
|
12
12
|
const Vue = require("vue");
|
|
13
13
|
const index$2 = require("../../../node_modules/@element-plus/icons-vue/dist/index.js");
|
|
14
|
-
const ValueSelector = require("./ValueSelector.
|
|
14
|
+
const ValueSelector = require("./ValueSelector.vue.js");
|
|
15
15
|
const index = require("../api/index.js");
|
|
16
16
|
;/* empty css */
|
|
17
17
|
const _pluginVue_exportHelper = require("../../../_virtual/_plugin-vue_export-helper.js");
|
|
@@ -6,7 +6,7 @@ require("../../../node_modules/element-plus/es/index.js");
|
|
|
6
6
|
;/* empty css */
|
|
7
7
|
const Vue = require("vue");
|
|
8
8
|
const index$1 = require("../../../node_modules/@element-plus/icons-vue/dist/index.js");
|
|
9
|
-
const ValueSelector = require("./ValueSelector.
|
|
9
|
+
const ValueSelector = require("./ValueSelector.vue.js");
|
|
10
10
|
;/* empty css */
|
|
11
11
|
const _pluginVue_exportHelper = require("../../../_virtual/_plugin-vue_export-helper.js");
|
|
12
12
|
const index = require("../../../node_modules/element-plus/es/components/button/index.js");
|
|
@@ -18,7 +18,7 @@ const index$2 = require("../../../../node_modules/@element-plus/icons-vue/dist/i
|
|
|
18
18
|
const common = require("../../packages/utils/common.js");
|
|
19
19
|
const index$5 = require("../../packages/form/aside/index.js");
|
|
20
20
|
const index$6 = require("../../packages/table/aside/index.js");
|
|
21
|
-
const ValueSelector = require("../../components/ValueSelector.
|
|
21
|
+
const ValueSelector = require("../../components/ValueSelector.vue.js");
|
|
22
22
|
;/* empty css */
|
|
23
23
|
const _pluginVue_exportHelper = require("../../../../_virtual/_plugin-vue_export-helper.js");
|
|
24
24
|
const index = require("../../../../node_modules/element-plus/es/components/dialog/index.js");
|
|
@@ -16,7 +16,7 @@ require("../../../../node_modules/element-plus/theme-chalk/el-tooltip.css.js");
|
|
|
16
16
|
require("../../../../node_modules/element-plus/theme-chalk/el-date-picker.css.js");
|
|
17
17
|
const Vue = require("vue");
|
|
18
18
|
const index = require("../../../../node_modules/@vueuse/core/dist/index.js");
|
|
19
|
-
const ValueSelector = require("../../components/ValueSelector.
|
|
19
|
+
const ValueSelector = require("../../components/ValueSelector.vue.js");
|
|
20
20
|
const index$1 = require("../../api/index.js");
|
|
21
21
|
const common = require("../utils/common.js");
|
|
22
22
|
const datasource = require("../utils/datasource.js");
|
|
@@ -32,7 +32,7 @@ require("../../../../node_modules/element-plus/theme-chalk/el-date-picker.css.js
|
|
|
32
32
|
;/* empty css */
|
|
33
33
|
;/* empty css */
|
|
34
34
|
const _pluginVue_exportHelper = require("../../../../_virtual/_plugin-vue_export-helper.js");
|
|
35
|
-
;/* empty css
|
|
35
|
+
;/* empty css */
|
|
36
36
|
const index$8 = require("../../api/index.js");
|
|
37
37
|
;/* empty css */
|
|
38
38
|
;/* empty css */
|
|
@@ -86,7 +86,7 @@ const widgets = require("../table/property/widgets.vue.js");
|
|
|
86
86
|
require("../../../../node_modules/element-plus/theme-chalk/el-tab-pane.css.js");
|
|
87
87
|
;/* empty css */
|
|
88
88
|
;/* empty css */
|
|
89
|
-
;/* empty css
|
|
89
|
+
;/* empty css */
|
|
90
90
|
;/* empty css */
|
|
91
91
|
;/* empty css */
|
|
92
92
|
;/* empty css */
|