cloud-web-corejs 1.1.0-dev.19 → 1.1.0-dev.21
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/package.json +1 -1
- package/src/components/baseInputExport/mixins.js +0 -6
- package/src/components/xform/docs/2026-09 /345/212/250/346/200/201/345/255/227/346/256/265/350/247/204/345/210/231/344/270/216/346/265/201/347/250/213/346/216/247/345/210/266/346/211/247/350/241/214/351/241/272/345/272/217/350/220/275/345/234/260/346/226/271/346/241/210.md" +409 -0
- package/src/components/xform/form-designer/designer.js +2086 -2084
- package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin.js +34 -0
- package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +13 -1
- package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +687 -602
- package/src/components/xform/form-designer/setting-panel/form-setting.vue +74 -9
- package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +8 -0
- package/src/components/xform/form-render/container-item/data-table-mixin.js +6304 -6285
- package/src/components/xform/form-render/container-item/dynamicFieldMixin.js +55 -1
- package/src/components/xform/form-render/container-item/tab-item.vue +138 -129
- package/src/components/xform/form-render/fieldControlEngine.js +218 -0
- package/src/components/xform/form-render/fieldControlMixin.js +534 -0
- package/src/components/xform/form-render/index.vue +164 -153
- package/src/components/xform/form-render/indexMixin.js +5415 -5331
- package/src/components/xform/mixins/defaultHandle.js +713 -707
- package/src/components/xform/utils/util.js +1710 -1708
- package/src/views/user/home/default.vue +6 -3
- package/src/views/user/home/wjl/content.vue +3 -2
- package/src/components/xform/form-render/container-item/dynamicFieldEngine.js +0 -285
- package/src/components/xform/form-render/formDynamicFieldMixin.js +0 -131
|
@@ -1,1708 +1,1710 @@
|
|
|
1
|
-
import Clipboard from "clipboard";
|
|
2
|
-
import axios from "axios";
|
|
3
|
-
import request from "../../../utils/request.js";
|
|
4
|
-
import { decode } from "js-base64";
|
|
5
|
-
|
|
6
|
-
export function getAccessUrl() {
|
|
7
|
-
return SUPPORT_PREFIX + "/report_ins/getData";
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function isNull(value) {
|
|
11
|
-
return value === null || value === undefined;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function isNilOrEmptyStr(value) {
|
|
15
|
-
return value === null || value === undefined || value === "";
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function isNotNull(value) {
|
|
19
|
-
return value !== null && value !== undefined;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const ATTACHMENT_WIDGET_TYPES = ["vabUpload", "baseAttachment", "vabUpload2"];
|
|
23
|
-
|
|
24
|
-
const PROJECT_TAG_WIDGET_TYPES = [
|
|
25
|
-
"project-tag",
|
|
26
|
-
"user-project-tag",
|
|
27
|
-
"saleOrg-project-tag",
|
|
28
|
-
];
|
|
29
|
-
|
|
30
|
-
const VABSEARCH_WIDGET_TYPES = ["vabsearch", "singerSearch", "multiSearch"];
|
|
31
|
-
|
|
32
|
-
export function isAttachmentWidgetType(type) {
|
|
33
|
-
return ATTACHMENT_WIDGET_TYPES.includes(type);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function isVabsearchWidgetType(type) {
|
|
37
|
-
return VABSEARCH_WIDGET_TYPES.includes(type);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function isVabsearchMultiWidget(widget) {
|
|
41
|
-
if (!widget) {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
const type = widget.type;
|
|
45
|
-
if (type === "multiSearch") {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
if (!isVabsearchWidgetType(type)) {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
const options = widget.options || {};
|
|
52
|
-
return !!(
|
|
53
|
-
options.multipleChoices || options.searchDialogConfig?.multipleChoices
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** 绑定值为数组的字段组件(含附件) */
|
|
58
|
-
export function isArrayValueWidgetType(type, options = {}) {
|
|
59
|
-
if (isAttachmentWidgetType(type)) {
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
if (type === "checkbox") {
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
if (type === "select" && options.multiple) {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
if (type === "time-range" || type === "date-range") {
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
if (type === "date" && options.type === "dates") {
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
if (PROJECT_TAG_WIDGET_TYPES.includes(type)) {
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
if (type === "multiSearch") {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
if (
|
|
81
|
-
type === "vabsearch" &&
|
|
82
|
-
(options.multipleChoices || options.searchDialogConfig?.multipleChoices)
|
|
83
|
-
) {
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** 数组类字段值是否为空(用于必填校验) */
|
|
90
|
-
export function isEmptyArrayFieldValue(value, type, options = {}) {
|
|
91
|
-
if (value === null || value === undefined) {
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
if (type === "time-range" || type === "date-range") {
|
|
95
|
-
if (!Array.isArray(value) || value.length === 0) {
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
return value.every(
|
|
99
|
-
(item) => item === null || item === undefined || item === ""
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
/* 附件字段开了「值存为URL」且限制数量为 1 时,模型里存的是单个 URL 字符串,
|
|
103
|
-
不能按空数组判空,否则必填校验永远不通过 */
|
|
104
|
-
if (isAttachmentWidgetType(type) && options.urlValueEnabled) {
|
|
105
|
-
if (typeof value === "string") {
|
|
106
|
-
return !value.trim();
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (!Array.isArray(value)) {
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
return value.length === 0;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function isEmptyStr(str) {
|
|
116
|
-
//return (str === undefined) || (!str) || (!/[^\s]/.test(str));
|
|
117
|
-
return (
|
|
118
|
-
str === undefined ||
|
|
119
|
-
(!str && str !== 0 && str !== "0") ||
|
|
120
|
-
!/[^\s]/.test(str)
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export const generateId = function () {
|
|
125
|
-
return Math.floor(
|
|
126
|
-
Math.random() * 100000 + Math.random() * 20000 + Math.random() * 5000
|
|
127
|
-
);
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
// 审计字段:创建/修改人及时间,camelCase 与 snake_case 两种形式;后端保存时重新生成
|
|
131
|
-
const AUDIT_FIELDS = [
|
|
132
|
-
"createBy",
|
|
133
|
-
"createDate",
|
|
134
|
-
"modifyBy",
|
|
135
|
-
"modifyDate",
|
|
136
|
-
"_createBy",
|
|
137
|
-
"_modifyBy",
|
|
138
|
-
"create_by",
|
|
139
|
-
"create_date",
|
|
140
|
-
"modify_by",
|
|
141
|
-
"modify_date",
|
|
142
|
-
];
|
|
143
|
-
// 展示态字段:查询时后端回填的创建/修改人昵称、手机号,保存前需剔除
|
|
144
|
-
const DISPLAY_FIELDS = [
|
|
145
|
-
"_createNickName",
|
|
146
|
-
"_createMobile",
|
|
147
|
-
"_modifyNickName",
|
|
148
|
-
"_modifyMobile",
|
|
149
|
-
];
|
|
150
|
-
// 子表/树表外键:复制场景下需断链
|
|
151
|
-
export const XFORM_SUB_FK_FIELDS = [
|
|
152
|
-
"head_table_id",
|
|
153
|
-
"headTableId",
|
|
154
|
-
"alias_id",
|
|
155
|
-
"object_foreign_id",
|
|
156
|
-
];
|
|
157
|
-
// 主表系统字段(含 id):供对比功能 sanitizeChangeData 清洗使用
|
|
158
|
-
export const XFORM_SYSTEM_FIELDS = ["id", ...AUDIT_FIELDS];
|
|
159
|
-
// 行级复制清洗字段:审计 + 展示态 + 子表外键;不含 id/parentField,
|
|
160
|
-
// 二者承载树层级,由调用方的树逻辑单独生成/重映射
|
|
161
|
-
export const XFORM_ROW_CLEAN_FIELDS = [
|
|
162
|
-
...AUDIT_FIELDS,
|
|
163
|
-
...DISPLAY_FIELDS,
|
|
164
|
-
...XFORM_SUB_FK_FIELDS,
|
|
165
|
-
];
|
|
166
|
-
|
|
167
|
-
export const createUUID = function () {
|
|
168
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
|
|
169
|
-
.replace(/[xy]/g, function (c) {
|
|
170
|
-
var r = (Math.random() * 16) | 0,
|
|
171
|
-
v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
172
|
-
return v.toString(16);
|
|
173
|
-
})
|
|
174
|
-
.replaceAll("-", "");
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
export const deepClone = function (origin) {
|
|
178
|
-
if (origin === undefined) {
|
|
179
|
-
return undefined;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return JSON.parse(JSON.stringify(origin));
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
export const overwriteObj = function (obj1, obj2) {
|
|
186
|
-
/* 浅拷贝对象属性,obj2覆盖obj1 */
|
|
187
|
-
// for (let prop in obj2) {
|
|
188
|
-
// if (obj2.hasOwnProperty(prop)) {
|
|
189
|
-
// obj1[prop] = obj2[prop]
|
|
190
|
-
// }
|
|
191
|
-
// }
|
|
192
|
-
|
|
193
|
-
Object.keys(obj2).forEach((prop) => {
|
|
194
|
-
obj1[prop] = obj2[prop];
|
|
195
|
-
});
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
export const addWindowResizeHandler = function (handler) {
|
|
199
|
-
// qiankun 沙箱下 window.onresize 直赋值落在代理对象上收不到真实事件,
|
|
200
|
-
// 统一走 addEventListener(沙箱会在子应用卸载时自动清理)。
|
|
201
|
-
// 主应用/独立运行时没有沙箱兜底,返回解绑函数供调用方在 beforeDestroy 中调用,
|
|
202
|
-
// 否则监听闭包会钉住已销毁的组件实例(内存泄露)
|
|
203
|
-
window.addEventListener("resize", handler);
|
|
204
|
-
return function () {
|
|
205
|
-
window.removeEventListener("resize", handler);
|
|
206
|
-
};
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const createStyleSheet = function () {
|
|
210
|
-
let head = document.head || document.getElementsByTagName("head")[0];
|
|
211
|
-
let style = document.createElement("style");
|
|
212
|
-
style.type = "text/css";
|
|
213
|
-
head.appendChild(style);
|
|
214
|
-
return style.sheet;
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
export const insertCustomCssToHead = function (cssCode, formId = "") {
|
|
218
|
-
let head = document.getElementsByTagName("head")[0];
|
|
219
|
-
let oldStyle = document.getElementById("vform-custom-css");
|
|
220
|
-
if (!!oldStyle) {
|
|
221
|
-
head.removeChild(oldStyle); //先清除后插入!!
|
|
222
|
-
}
|
|
223
|
-
if (!!formId) {
|
|
224
|
-
oldStyle = document.getElementById("vform-custom-css" + "-" + formId);
|
|
225
|
-
!!oldStyle && head.removeChild(oldStyle); //先清除后插入!!
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
let newStyle = document.createElement("style");
|
|
229
|
-
newStyle.type = "text/css";
|
|
230
|
-
newStyle.rel = "stylesheet";
|
|
231
|
-
newStyle.id = !!formId
|
|
232
|
-
? "vform-custom-css" + "-" + formId
|
|
233
|
-
: "vform-custom-css";
|
|
234
|
-
try {
|
|
235
|
-
newStyle.appendChild(document.createTextNode(cssCode));
|
|
236
|
-
} catch (ex) {
|
|
237
|
-
newStyle.styleSheet.cssText = cssCode;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
head.appendChild(newStyle);
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* 注入表单全局函数(formConfig.functions):把代码执行在【真实全局作用域】,
|
|
245
|
-
* 使表单各类事件脚本能引用到其中定义的函数。
|
|
246
|
-
*
|
|
247
|
-
* 为什么不再插 <script>:事件脚本一律由 new Function 创建,其作用域链恒为真实全局作用域;
|
|
248
|
-
* 而 qiankun 沙箱 patch 了 head/body 的 appendChild,子应用里动态 script 不会进 DOM,
|
|
249
|
-
* 改由 execScripts 以 (function(window){with(window){...}}).bind(proxy) 包裹执行——
|
|
250
|
-
* `function foo(){}` 落在包裹函数的作用域里、`window.foo=` 落在 proxy 上,两者在真实
|
|
251
|
-
* window 上都不存在,调用侧必然 ReferenceError 且被各处 try/catch 吞掉(静默失效)。
|
|
252
|
-
*
|
|
253
|
-
* 间接 eval 由规范保证在全局作用域、非严格模式下求值,函数声明因此成为真实 window 的属性,
|
|
254
|
-
* 与 new Function 的取值环境对齐;qiankun 对 `eval` 有显式特判(proxySandbox 返回原生 eval),
|
|
255
|
-
* 主应用形态与子应用形态行为一致。
|
|
256
|
-
*
|
|
257
|
-
* 函数名与 formId 参数保持不变:调用方(含 haier 分支)沿用此签名,改名只增加同步面。
|
|
258
|
-
* 现已不产生 DOM 节点、无需按 id 清理,formId 仅用于 sourceURL 定位。
|
|
259
|
-
*/
|
|
260
|
-
export const insertGlobalFunctionsToHtml = function (
|
|
261
|
-
functionsCode,
|
|
262
|
-
formId = ""
|
|
263
|
-
) {
|
|
264
|
-
if (!functionsCode || typeof functionsCode !== "string") {
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
let sourceName = !!formId
|
|
268
|
-
? "v_form_global_functions" + "-" + formId
|
|
269
|
-
: "v_form_global_functions";
|
|
270
|
-
try {
|
|
271
|
-
// (0, eval) 是间接调用形式,不可简写为 eval(...):直接 eval 会继承当前模块作用域,
|
|
272
|
-
// 函数声明将落在模块内而非真实 window 上。sourceURL 让 devtools 里可定位、可下断点。
|
|
273
|
-
(0, eval)(functionsCode + "\n//# sourceURL=" + sourceName + ".js");
|
|
274
|
-
} catch (e) {
|
|
275
|
-
// 原先 <script> 注入时语法/运行时错误只进 window.onerror、不影响表单渲染,
|
|
276
|
-
// 这里必须同样吞掉:否则会中断 initFormObject 整条表单初始化链路
|
|
277
|
-
console.error("[xform] 表单全局函数执行失败:" + sourceName, e);
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
export const optionExists = function (optionsObj, optionName) {
|
|
282
|
-
if (!optionsObj) {
|
|
283
|
-
return false;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return Object.keys(optionsObj).indexOf(optionName) > -1;
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
export const loadRemoteScript = function (srcPath, callback) {
|
|
290
|
-
/*加载远程js,加载成功后执行回调函数*/
|
|
291
|
-
let sid = encodeURIComponent(srcPath);
|
|
292
|
-
let oldScriptEle = document.getElementById(sid);
|
|
293
|
-
|
|
294
|
-
if (!oldScriptEle) {
|
|
295
|
-
let s = document.createElement("script");
|
|
296
|
-
s.src = srcPath;
|
|
297
|
-
s.id = sid;
|
|
298
|
-
document.body.appendChild(s);
|
|
299
|
-
|
|
300
|
-
s.onload = s.onreadystatechange = function (_, isAbort) {
|
|
301
|
-
/* 借鉴自ace.js */
|
|
302
|
-
if (
|
|
303
|
-
isAbort ||
|
|
304
|
-
!s.readyState ||
|
|
305
|
-
s.readyState === "loaded" ||
|
|
306
|
-
s.readyState === "complete"
|
|
307
|
-
) {
|
|
308
|
-
s = s.onload = s.onreadystatechange = null;
|
|
309
|
-
if (!isAbort) {
|
|
310
|
-
callback();
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
export function traverseFieldWidgets(
|
|
318
|
-
widgetList,
|
|
319
|
-
handler,
|
|
320
|
-
parent = null,
|
|
321
|
-
staticWidgetsIncluded
|
|
322
|
-
) {
|
|
323
|
-
if (!widgetList) {
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
loopHandleWidget(widgetList, (w, parent) => {
|
|
328
|
-
if (w.formItemFlag || (w.formItemFlag === false && staticWidgetsIncluded)) {
|
|
329
|
-
handler(w, parent);
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
/* widgetList.forEach((w) => {
|
|
334
|
-
if (w.formItemFlag || (w.formItemFlag === false && staticWidgetsIncluded)) {
|
|
335
|
-
handler(w, parent);
|
|
336
|
-
} else if (w.type === "grid") {
|
|
337
|
-
w.cols.forEach((col) => {
|
|
338
|
-
traverseFieldWidgets(col.widgetList, handler, w, staticWidgetsIncluded);
|
|
339
|
-
});
|
|
340
|
-
} else if (w.type === "table") {
|
|
341
|
-
w.rows.forEach((row) => {
|
|
342
|
-
row.cols.forEach((cell) => {
|
|
343
|
-
traverseFieldWidgets(
|
|
344
|
-
cell.widgetList,
|
|
345
|
-
handler,
|
|
346
|
-
w,
|
|
347
|
-
staticWidgetsIncluded
|
|
348
|
-
);
|
|
349
|
-
});
|
|
350
|
-
});
|
|
351
|
-
} else if (w.type === "tab") {
|
|
352
|
-
w.tabs.forEach((tab) => {
|
|
353
|
-
traverseFieldWidgets(tab.widgetList, handler, w, staticWidgetsIncluded);
|
|
354
|
-
});
|
|
355
|
-
} else if (w.type === "sub-form" || w.type === "grid-sub-form") {
|
|
356
|
-
traverseFieldWidgets(w.widgetList, handler, w, staticWidgetsIncluded);
|
|
357
|
-
} else if (w.category === "container") {
|
|
358
|
-
//自定义容器
|
|
359
|
-
traverseFieldWidgets(w.widgetList, handler, w, staticWidgetsIncluded);
|
|
360
|
-
}
|
|
361
|
-
}); */
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
export function traverseContainerWidgets(
|
|
365
|
-
widgetList,
|
|
366
|
-
handler,
|
|
367
|
-
skipDialogAndDrawer
|
|
368
|
-
) {
|
|
369
|
-
if (!widgetList) {
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
loopHandleWidget(widgetList, (w, parent) => {
|
|
374
|
-
if (w.category === "container") {
|
|
375
|
-
if (
|
|
376
|
-
skipDialogAndDrawer &&
|
|
377
|
-
(w.type === "vf-dialog" || w.type === "vf-drawer")
|
|
378
|
-
) {
|
|
379
|
-
//什么也不做
|
|
380
|
-
} else {
|
|
381
|
-
handler(w);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
/* widgetList.forEach((w) => {
|
|
387
|
-
if (w.category === "container") {
|
|
388
|
-
if (
|
|
389
|
-
skipDialogAndDrawer &&
|
|
390
|
-
(w.type === "vf-dialog" || w.type === "vf-drawer")
|
|
391
|
-
) {
|
|
392
|
-
//什么也不做
|
|
393
|
-
} else {
|
|
394
|
-
handler(w);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
if (w.type === "grid") {
|
|
399
|
-
w.cols.forEach((col) => {
|
|
400
|
-
traverseContainerWidgets(col.widgetList, handler);
|
|
401
|
-
});
|
|
402
|
-
} else if (w.type === "table") {
|
|
403
|
-
w.rows.forEach((row) => {
|
|
404
|
-
row.cols.forEach((cell) => {
|
|
405
|
-
traverseContainerWidgets(cell.widgetList, handler);
|
|
406
|
-
});
|
|
407
|
-
});
|
|
408
|
-
} else if (w.type === "tab") {
|
|
409
|
-
w.tabs.forEach((tab) => {
|
|
410
|
-
traverseContainerWidgets(tab.widgetList, handler);
|
|
411
|
-
});
|
|
412
|
-
} else if (w.type === "sub-form" || w.type === "grid-sub-form") {
|
|
413
|
-
traverseContainerWidgets(w.widgetList, handler);
|
|
414
|
-
} else if (w.category === "container") {
|
|
415
|
-
//自定义容器
|
|
416
|
-
if (
|
|
417
|
-
skipDialogAndDrawer &&
|
|
418
|
-
(w.type === "vf-dialog" || w.type === "vf-drawer")
|
|
419
|
-
) {
|
|
420
|
-
//什么也不做
|
|
421
|
-
} else {
|
|
422
|
-
traverseContainerWidgets(w.widgetList, handler);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}); */
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
export function traverseAllWidgetsNew(widgetList, callback) {
|
|
429
|
-
if (!widgetList) {
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
let columnLoopDo = (t, parentWidget) => {
|
|
433
|
-
if (t.children && t.children.length) {
|
|
434
|
-
t.children.forEach((item) => {
|
|
435
|
-
columnLoopDo(item, parentWidget);
|
|
436
|
-
});
|
|
437
|
-
} else {
|
|
438
|
-
if (t.widget) {
|
|
439
|
-
callback && callback(t.widget, parentWidget);
|
|
440
|
-
}
|
|
441
|
-
if (t.editWidget) {
|
|
442
|
-
callback && callback(t.editWidget, parentWidget);
|
|
443
|
-
}
|
|
444
|
-
if (t.widgetList && t.widgetList.length) {
|
|
445
|
-
loopHandleWidget(t.widgetList, (widget) => {
|
|
446
|
-
callback && callback(widget, parentWidget);
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
|
-
loopHandleWidget(widgetList, (widget, parentWidget) => {
|
|
452
|
-
if (callback) {
|
|
453
|
-
callback(widget, parentWidget);
|
|
454
|
-
if (widget.type === "data-table") {
|
|
455
|
-
for (let item of widget.options.tableColumns) {
|
|
456
|
-
columnLoopDo(item, parentWidget);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
export function traverseAllWidgets(widgetList, handler) {
|
|
464
|
-
if (!widgetList) {
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
loopHandleWidget(widgetList, (w, parentWidget) => {
|
|
469
|
-
handler(w, parentWidget);
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
/* widgetList.forEach((w) => {
|
|
473
|
-
handler(w);
|
|
474
|
-
|
|
475
|
-
if (w.type === "grid") {
|
|
476
|
-
w.cols.forEach((col) => {
|
|
477
|
-
handler(col);
|
|
478
|
-
traverseAllWidgets(col.widgetList, handler);
|
|
479
|
-
});
|
|
480
|
-
} else if (w.type === "table") {
|
|
481
|
-
w.rows.forEach((row) => {
|
|
482
|
-
row.cols.forEach((cell) => {
|
|
483
|
-
handler(cell);
|
|
484
|
-
traverseAllWidgets(cell.widgetList, handler);
|
|
485
|
-
});
|
|
486
|
-
});
|
|
487
|
-
} else if (w.type === "tab") {
|
|
488
|
-
w.tabs.forEach((tab) => {
|
|
489
|
-
traverseAllWidgets(tab.widgetList, handler);
|
|
490
|
-
});
|
|
491
|
-
} else if (w.type === "sub-form" || w.type === "grid-sub-form") {
|
|
492
|
-
traverseAllWidgets(w.widgetList, handler);
|
|
493
|
-
} else if (w.category === "container") {
|
|
494
|
-
//自定义容器
|
|
495
|
-
traverseAllWidgets(w.widgetList, handler);
|
|
496
|
-
}
|
|
497
|
-
}); */
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
function handleWidgetForTraverse(
|
|
501
|
-
widget,
|
|
502
|
-
handler,
|
|
503
|
-
staticWidgetsIncluded = false
|
|
504
|
-
) {
|
|
505
|
-
if (!!widget.category && widget.category === "container") {
|
|
506
|
-
traverseFieldWidgetsOfContainer(widget, handler);
|
|
507
|
-
} else if (widget.formItemFlag) {
|
|
508
|
-
handler(widget);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* 容器 → 子节点所在字段名。
|
|
514
|
-
*
|
|
515
|
-
* 注意:全库同一语义的映射有多份(designer.js 的局部表、indexMixin 的
|
|
516
|
-
* getTableFiledMap / getFormTemplateTableDTOs 两张局部表),改这里时请一并核对,
|
|
517
|
-
* 漏一份的后果参见 loopHandleWidgetItem 里关于 H5 容器的注释。
|
|
518
|
-
*/
|
|
519
|
-
export const itemFieldMap = {
|
|
520
|
-
grid: "cols",
|
|
521
|
-
table: "rows",
|
|
522
|
-
"table-cell": "widgetList",
|
|
523
|
-
"h5-table": "rows",
|
|
524
|
-
"h5-table-cell": "widgetList",
|
|
525
|
-
tab: "tabs",
|
|
526
|
-
"tab-pane": "widgetList",
|
|
527
|
-
"grid-col": "widgetList",
|
|
528
|
-
"vf-box": "widgetList",
|
|
529
|
-
card: "widgetList",
|
|
530
|
-
detail: "panes",
|
|
531
|
-
"detail-plain": "panes", // 与 indexMixin 的两张表对齐,此前这张漏了
|
|
532
|
-
"detail-pane": "widgetList",
|
|
533
|
-
"detail-h5": "panes",
|
|
534
|
-
"h5-card": "panes",
|
|
535
|
-
"h5-card-pane": "widgetList",
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* 遍历容器内的字段组件
|
|
540
|
-
* @param con
|
|
541
|
-
* @param handler
|
|
542
|
-
* @param staticWidgetsIncluded
|
|
543
|
-
*/
|
|
544
|
-
export function traverseFieldWidgetsOfContainer(
|
|
545
|
-
con,
|
|
546
|
-
handler,
|
|
547
|
-
staticWidgetsIncluded = false
|
|
548
|
-
) {
|
|
549
|
-
/*loopHandleWidget([con],(w, parent)=>{
|
|
550
|
-
handleWidgetForTraverse(w, handler, staticWidgetsIncluded);
|
|
551
|
-
});*/
|
|
552
|
-
if (con.type === "grid") {
|
|
553
|
-
con.cols.forEach((col) => {
|
|
554
|
-
col.widgetList.forEach((cw) => {
|
|
555
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
556
|
-
});
|
|
557
|
-
});
|
|
558
|
-
} else if (con.type === "table") {
|
|
559
|
-
con.rows.forEach((row) => {
|
|
560
|
-
row.cols.forEach((cell) => {
|
|
561
|
-
cell.widgetList.forEach((cw) => {
|
|
562
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
563
|
-
});
|
|
564
|
-
});
|
|
565
|
-
});
|
|
566
|
-
} else if (con.type === "tab") {
|
|
567
|
-
con.tabs.forEach((tab) => {
|
|
568
|
-
tab.widgetList.forEach((cw) => {
|
|
569
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
570
|
-
});
|
|
571
|
-
});
|
|
572
|
-
} else if (con.type === "sub-form" || con.type === "grid-sub-form") {
|
|
573
|
-
con.widgetList.forEach((cw) => {
|
|
574
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
575
|
-
});
|
|
576
|
-
} else if (con.type === "data-table") {
|
|
577
|
-
/*con.widgetList.forEach((cw) => {
|
|
578
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
579
|
-
});*/
|
|
580
|
-
if (!!con.widgetList) {
|
|
581
|
-
con.widgetList.forEach((childItem) => {
|
|
582
|
-
loopHandleWidgetItem(childItem, con, handler);
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
if (!!con.buttons) {
|
|
586
|
-
con.buttons.forEach((childItem) => {
|
|
587
|
-
loopHandleWidgetItem(childItem, con, handler);
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
for (let column of con.options.tableColumns) {
|
|
591
|
-
if (column.widget) {
|
|
592
|
-
handleWidgetForTraverse(column.widget, handler, staticWidgetsIncluded);
|
|
593
|
-
}
|
|
594
|
-
if (column.widgetList) {
|
|
595
|
-
column.widgetList.forEach((cw) => {
|
|
596
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
597
|
-
});
|
|
598
|
-
/*loopHandleWidget(column.widgetList, (cw) => {
|
|
599
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
600
|
-
});*/
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
} else if (con.category === "container") {
|
|
604
|
-
//自定义容器
|
|
605
|
-
/*let key = itemFieldMap[con.type]
|
|
606
|
-
con[key].forEach((cw) => {
|
|
607
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
608
|
-
});*/
|
|
609
|
-
|
|
610
|
-
/*con.widgetList.forEach(cw => {
|
|
611
|
-
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded)
|
|
612
|
-
})*/
|
|
613
|
-
loopHandleWidgetItem(con, null, (w) => {
|
|
614
|
-
if (con.id != w.id)
|
|
615
|
-
handleWidgetForTraverse(w, handler, staticWidgetsIncluded);
|
|
616
|
-
});
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
function handleContainerTraverse(
|
|
621
|
-
widget,
|
|
622
|
-
fieldHandler,
|
|
623
|
-
containerHandler,
|
|
624
|
-
internalContainerCallFlag,
|
|
625
|
-
staticWidgetsIncluded
|
|
626
|
-
) {
|
|
627
|
-
if (!!widget.category && widget.category === "container") {
|
|
628
|
-
traverseWidgetsOfContainer(
|
|
629
|
-
widget,
|
|
630
|
-
fieldHandler,
|
|
631
|
-
containerHandler,
|
|
632
|
-
internalContainerCallFlag,
|
|
633
|
-
staticWidgetsIncluded
|
|
634
|
-
);
|
|
635
|
-
} else if (widget.formItemFlag) {
|
|
636
|
-
fieldHandler(widget);
|
|
637
|
-
} else if (staticWidgetsIncluded) {
|
|
638
|
-
fieldHandler(widget);
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
/**
|
|
643
|
-
* 遍历容器内部的字段组件和容器组件
|
|
644
|
-
* @param con
|
|
645
|
-
* @param fieldHandler
|
|
646
|
-
* @param containerHandler
|
|
647
|
-
* @param internalContainerCallFlag 是否需要处理内部容器组件,默认不处理
|
|
648
|
-
* @param staticWidgetsIncluded 是否需要处理静态非表单交互类组件
|
|
649
|
-
*/
|
|
650
|
-
export function traverseWidgetsOfContainer(
|
|
651
|
-
con,
|
|
652
|
-
fieldHandler,
|
|
653
|
-
containerHandler,
|
|
654
|
-
internalContainerCallFlag,
|
|
655
|
-
staticWidgetsIncluded
|
|
656
|
-
) {
|
|
657
|
-
if (con.category === "container") {
|
|
658
|
-
containerHandler(con);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
/*loopHandleWidget([con], (cw, parent) => {
|
|
662
|
-
if (con.id !== cw.id) {
|
|
663
|
-
handleContainerTraverse(
|
|
664
|
-
cw,
|
|
665
|
-
fieldHandler,
|
|
666
|
-
containerHandler,
|
|
667
|
-
internalContainerCallFlag,
|
|
668
|
-
staticWidgetsIncluded
|
|
669
|
-
);
|
|
670
|
-
}
|
|
671
|
-
});*/
|
|
672
|
-
|
|
673
|
-
if (con.type === "grid") {
|
|
674
|
-
con.cols.forEach((col) => {
|
|
675
|
-
if (internalContainerCallFlag) {
|
|
676
|
-
containerHandler(col);
|
|
677
|
-
}
|
|
678
|
-
col.widgetList.forEach((cw) => {
|
|
679
|
-
handleContainerTraverse(
|
|
680
|
-
cw,
|
|
681
|
-
fieldHandler,
|
|
682
|
-
containerHandler,
|
|
683
|
-
internalContainerCallFlag,
|
|
684
|
-
staticWidgetsIncluded
|
|
685
|
-
);
|
|
686
|
-
});
|
|
687
|
-
});
|
|
688
|
-
} else if (con.type === "table") {
|
|
689
|
-
con.rows.forEach((row) => {
|
|
690
|
-
if (internalContainerCallFlag) {
|
|
691
|
-
containerHandler(row);
|
|
692
|
-
}
|
|
693
|
-
row.cols.forEach((cell) => {
|
|
694
|
-
if (internalContainerCallFlag) {
|
|
695
|
-
containerHandler(cell);
|
|
696
|
-
}
|
|
697
|
-
cell.widgetList.forEach((cw) => {
|
|
698
|
-
handleContainerTraverse(
|
|
699
|
-
cw,
|
|
700
|
-
fieldHandler,
|
|
701
|
-
containerHandler,
|
|
702
|
-
internalContainerCallFlag,
|
|
703
|
-
staticWidgetsIncluded
|
|
704
|
-
);
|
|
705
|
-
});
|
|
706
|
-
});
|
|
707
|
-
});
|
|
708
|
-
} else if (con.type === "tab") {
|
|
709
|
-
con.tabs.forEach((tab) => {
|
|
710
|
-
if (internalContainerCallFlag) {
|
|
711
|
-
containerHandler(tab);
|
|
712
|
-
}
|
|
713
|
-
tab.widgetList.forEach((cw) => {
|
|
714
|
-
handleContainerTraverse(
|
|
715
|
-
cw,
|
|
716
|
-
fieldHandler,
|
|
717
|
-
containerHandler,
|
|
718
|
-
internalContainerCallFlag,
|
|
719
|
-
staticWidgetsIncluded
|
|
720
|
-
);
|
|
721
|
-
});
|
|
722
|
-
});
|
|
723
|
-
} else if (con.type === "sub-form" || con.type === "grid-sub-form") {
|
|
724
|
-
con.widgetList.forEach((cw) => {
|
|
725
|
-
handleContainerTraverse(
|
|
726
|
-
cw,
|
|
727
|
-
fieldHandler,
|
|
728
|
-
containerHandler,
|
|
729
|
-
internalContainerCallFlag,
|
|
730
|
-
staticWidgetsIncluded
|
|
731
|
-
);
|
|
732
|
-
});
|
|
733
|
-
} else if (con.category === "container") {
|
|
734
|
-
//自定义容器
|
|
735
|
-
/* 容器类型不在 itemFieldMap 里时 key 是 undefined,con[undefined] 也是 undefined,
|
|
736
|
-
直接 .forEach 会抛 TypeError —— 表里没覆盖到的容器(list-h5、detail-tabs、
|
|
737
|
-
tree-pane…)都会中招,故取值后判空再遍历。 */
|
|
738
|
-
let key = itemFieldMap[con.type];
|
|
739
|
-
let childList = key ? con[key] : null;
|
|
740
|
-
if (childList && childList.length > 0) {
|
|
741
|
-
childList.forEach((cw) => {
|
|
742
|
-
handleContainerTraverse(
|
|
743
|
-
cw,
|
|
744
|
-
fieldHandler,
|
|
745
|
-
containerHandler,
|
|
746
|
-
internalContainerCallFlag,
|
|
747
|
-
staticWidgetsIncluded
|
|
748
|
-
);
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
export function traverseWidgetsOfGridCol(
|
|
755
|
-
gridCol,
|
|
756
|
-
fieldHandler,
|
|
757
|
-
containerHandler
|
|
758
|
-
) {
|
|
759
|
-
// if (gridCol.category === 'container') {
|
|
760
|
-
// containerHandler(gridCol)
|
|
761
|
-
// }
|
|
762
|
-
|
|
763
|
-
if (gridCol.type === "grid-col") {
|
|
764
|
-
gridCol.widgetList.forEach((cw) => {
|
|
765
|
-
handleContainerTraverse(cw, fieldHandler, containerHandler);
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
/**
|
|
771
|
-
* 获取所有字段组件
|
|
772
|
-
* @param widgetList
|
|
773
|
-
* @param staticWidgetsIncluded 是否包含按钮等静态组件,默认不包含
|
|
774
|
-
* @returns {[]}
|
|
775
|
-
*/
|
|
776
|
-
export function getAllFieldWidgets(widgetList, staticWidgetsIncluded) {
|
|
777
|
-
if (!widgetList) {
|
|
778
|
-
return [];
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
let result = [];
|
|
782
|
-
let handlerFn = (w) => {
|
|
783
|
-
result.push({
|
|
784
|
-
type: w.type,
|
|
785
|
-
name: w.options.name,
|
|
786
|
-
field: w,
|
|
787
|
-
});
|
|
788
|
-
};
|
|
789
|
-
traverseFieldWidgets(widgetList, handlerFn, null, staticWidgetsIncluded);
|
|
790
|
-
|
|
791
|
-
return result;
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
/**
|
|
795
|
-
* 获取所有容器组件
|
|
796
|
-
* @param widgetList
|
|
797
|
-
* @param skipDialogAndDrawer 是否跳过弹窗和抽屉内部组件,默认不跳过
|
|
798
|
-
* @returns {[]}
|
|
799
|
-
*/
|
|
800
|
-
export function getAllContainerWidgets(widgetList, skipDialogAndDrawer) {
|
|
801
|
-
if (!widgetList) {
|
|
802
|
-
return [];
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
let result = [];
|
|
806
|
-
let handlerFn = (w) => {
|
|
807
|
-
result.push({
|
|
808
|
-
type: w.type,
|
|
809
|
-
name: w.options.name,
|
|
810
|
-
container: w,
|
|
811
|
-
});
|
|
812
|
-
};
|
|
813
|
-
traverseContainerWidgets(widgetList, handlerFn, skipDialogAndDrawer);
|
|
814
|
-
|
|
815
|
-
return result;
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
export function getFieldWidgetByName(
|
|
819
|
-
widgetList,
|
|
820
|
-
fieldName,
|
|
821
|
-
staticWidgetsIncluded
|
|
822
|
-
) {
|
|
823
|
-
if (!widgetList) {
|
|
824
|
-
return null;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
let foundWidget = null;
|
|
828
|
-
let handlerFn = (widget) => {
|
|
829
|
-
if (widget.options.name === fieldName) {
|
|
830
|
-
foundWidget = widget;
|
|
831
|
-
}
|
|
832
|
-
};
|
|
833
|
-
|
|
834
|
-
traverseFieldWidgets(widgetList, handlerFn, null, staticWidgetsIncluded);
|
|
835
|
-
return foundWidget;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
export const columnFormatMap = {
|
|
839
|
-
editInput: "input",
|
|
840
|
-
editNumber: "number",
|
|
841
|
-
editDate: "date",
|
|
842
|
-
editSelect: "select",
|
|
843
|
-
editSearch: "vabsearch",
|
|
844
|
-
editAttachment: "baseAttachment",
|
|
845
|
-
editStatus: "status",
|
|
846
|
-
aText: "a-text",
|
|
847
|
-
aLink: "a-link",
|
|
848
|
-
editDelete: "a-link",
|
|
849
|
-
editButton: "a-link",
|
|
850
|
-
button: "button",
|
|
851
|
-
addSiblingEditRow: "a-link",
|
|
852
|
-
addChildTreeRow: "a-link",
|
|
853
|
-
moveUpRow: "a-link",
|
|
854
|
-
moveDownRow: "a-link",
|
|
855
|
-
removeTreeRow: "a-link",
|
|
856
|
-
text: "text",
|
|
857
|
-
checkbox: "checkbox",
|
|
858
|
-
radio: "radio",
|
|
859
|
-
dropdown: "dropdown",
|
|
860
|
-
textarea: "textarea",
|
|
861
|
-
editScriptInput: "script-input",
|
|
862
|
-
};
|
|
863
|
-
|
|
864
|
-
/** 列 widget 扩展选项:动态列 widgetOptions;设计器静态列 columnOption */
|
|
865
|
-
export function getColumnWidgetOptions(row, isEdit = false) {
|
|
866
|
-
if (!row) {
|
|
867
|
-
return undefined;
|
|
868
|
-
}
|
|
869
|
-
if (isEdit) {
|
|
870
|
-
return row.editWidgetOptions ?? row.editColumnOption;
|
|
871
|
-
}
|
|
872
|
-
return row.widgetOptions ?? row.columnOption;
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
/**
|
|
876
|
-
* 复制列内 field widget,用于展示组件与编辑组件同类型、只配置了其中一方的列。
|
|
877
|
-
* 另一方若按类型新建空白 schema,只配在已有一方的 defaultValue / optionItems /
|
|
878
|
-
* searchDialogConfig 等会全部丢失(编辑表新增行取默认值同样受影响)。
|
|
879
|
-
* 字段绑定 keyName 保持不变;id 与 name 必须重新生成——refList 按
|
|
880
|
-
* options.name + 行键 注册,fieldSchemaMap 按 id 索引,两个组件同名会互相覆盖。
|
|
881
|
-
*/
|
|
882
|
-
export function cloneColumnFieldWidget(fieldWidget) {
|
|
883
|
-
if (!fieldWidget) {
|
|
884
|
-
return null;
|
|
885
|
-
}
|
|
886
|
-
let newWidget = deepClone(fieldWidget);
|
|
887
|
-
newWidget.id = String(newWidget.type).replace(/-/g, "") + generateId();
|
|
888
|
-
if (newWidget.hasOwnProperty("tableField")) {
|
|
889
|
-
newWidget.tableField = newWidget.id;
|
|
890
|
-
}
|
|
891
|
-
newWidget.options.name = newWidget.id;
|
|
892
|
-
return newWidget;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
/**
|
|
896
|
-
* 展平数据表格列配置,只返回叶子列。
|
|
897
|
-
* tableColumns 里带 children 的是分组表头(自身 prop 为空),真正的业务字段挂在 children 上,
|
|
898
|
-
* 因此凡是按 prop 取字段的逻辑都必须先展平,不能只看顶层。
|
|
899
|
-
*/
|
|
900
|
-
export function flattenLeafColumns(columns) {
|
|
901
|
-
let result = [];
|
|
902
|
-
let loopDo = (cols) => {
|
|
903
|
-
(cols || []).forEach((item) => {
|
|
904
|
-
if (!item) {
|
|
905
|
-
return;
|
|
906
|
-
}
|
|
907
|
-
if (item.children && item.children.length) {
|
|
908
|
-
loopDo(item.children);
|
|
909
|
-
} else {
|
|
910
|
-
result.push(item);
|
|
911
|
-
}
|
|
912
|
-
});
|
|
913
|
-
};
|
|
914
|
-
loopDo(columns);
|
|
915
|
-
return result;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
/** 将列级 label / keyName / required 同步到列内 field widget(动态列 label 在列顶层) */
|
|
919
|
-
export function applyColumnMetaToFieldWidget(fieldWidget, row, isEdit = false) {
|
|
920
|
-
if (!fieldWidget || !row) {
|
|
921
|
-
return fieldWidget;
|
|
922
|
-
}
|
|
923
|
-
const widgetOptions = getColumnWidgetOptions(row, isEdit);
|
|
924
|
-
if (fieldWidget.options.hasOwnProperty("required")) {
|
|
925
|
-
fieldWidget.options.required = !!(row.required || widgetOptions?.required);
|
|
926
|
-
}
|
|
927
|
-
if (!fieldWidget.options.label && row.label) {
|
|
928
|
-
fieldWidget.options.label = row.label;
|
|
929
|
-
}
|
|
930
|
-
if (row.prop) {
|
|
931
|
-
if (fieldWidget.options.hasOwnProperty("keyName")) {
|
|
932
|
-
fieldWidget.options.keyName = row.prop;
|
|
933
|
-
fieldWidget.options.keyNameEnabled = true;
|
|
934
|
-
} else if (!fieldWidget.options.name) {
|
|
935
|
-
fieldWidget.options.name = row.prop;
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
if (fieldWidget.type !== "button" && fieldWidget.type !== "a-link") {
|
|
939
|
-
fieldWidget.options.labelHidden = true;
|
|
940
|
-
}
|
|
941
|
-
return fieldWidget;
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
/** 同步列 widget / editWidget 的列级元数据(含 labelHidden) */
|
|
945
|
-
export function applyColumnMetaToColumnRow(row) {
|
|
946
|
-
if (!row) {
|
|
947
|
-
return;
|
|
948
|
-
}
|
|
949
|
-
if (row.widget) {
|
|
950
|
-
applyColumnMetaToFieldWidget(row.widget, row, false);
|
|
951
|
-
}
|
|
952
|
-
if (row.editWidget) {
|
|
953
|
-
applyColumnMetaToFieldWidget(row.editWidget, row, true);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
export function getFieldWidgetById(widgetList, fieldId, staticWidgetsIncluded) {
|
|
958
|
-
if (!widgetList) {
|
|
959
|
-
return null;
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
let foundWidget = null;
|
|
963
|
-
let handlerFn = (widget) => {
|
|
964
|
-
if (widget.id === fieldId) {
|
|
965
|
-
foundWidget = widget;
|
|
966
|
-
} else if (widget.type === "data-table") {
|
|
967
|
-
for (let column of widget.options.tableColumns) {
|
|
968
|
-
if (column?.widget?.id + "" === fieldId) {
|
|
969
|
-
foundWidget = column.widget;
|
|
970
|
-
break;
|
|
971
|
-
} else if (column.widgetList) {
|
|
972
|
-
loopHandleWidget(column.widgetList, (item1) => {
|
|
973
|
-
if (item1.id === fieldId) {
|
|
974
|
-
foundWidget = item1;
|
|
975
|
-
}
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
};
|
|
981
|
-
|
|
982
|
-
traverseFieldWidgets(widgetList, handlerFn, null, staticWidgetsIncluded);
|
|
983
|
-
return foundWidget;
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
export function getContainerWidgetByName(widgetList, containerName) {
|
|
987
|
-
if (!widgetList) {
|
|
988
|
-
return null;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
let foundContainer = null;
|
|
992
|
-
let handlerFn = (con) => {
|
|
993
|
-
if (con.options.name === containerName) {
|
|
994
|
-
foundContainer = con;
|
|
995
|
-
}
|
|
996
|
-
};
|
|
997
|
-
|
|
998
|
-
traverseContainerWidgets(widgetList, handlerFn);
|
|
999
|
-
return foundContainer;
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
export function getContainerWidgetById(widgetList, containerId) {
|
|
1003
|
-
if (!widgetList) {
|
|
1004
|
-
return null;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
let foundContainer = null;
|
|
1008
|
-
let handlerFn = (con) => {
|
|
1009
|
-
if (con.id === containerId) {
|
|
1010
|
-
foundContainer = con;
|
|
1011
|
-
}
|
|
1012
|
-
};
|
|
1013
|
-
|
|
1014
|
-
traverseContainerWidgets(widgetList, handlerFn);
|
|
1015
|
-
return foundContainer;
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
export function copyToClipboard(
|
|
1019
|
-
content,
|
|
1020
|
-
clickEvent,
|
|
1021
|
-
$message,
|
|
1022
|
-
successMsg,
|
|
1023
|
-
errorMsg
|
|
1024
|
-
) {
|
|
1025
|
-
const clipboard = new Clipboard(clickEvent.target, {
|
|
1026
|
-
text: () => content,
|
|
1027
|
-
});
|
|
1028
|
-
|
|
1029
|
-
clipboard.on("success", () => {
|
|
1030
|
-
$message.success(successMsg);
|
|
1031
|
-
clipboard.destroy();
|
|
1032
|
-
});
|
|
1033
|
-
|
|
1034
|
-
clipboard.on("error", () => {
|
|
1035
|
-
$message.error(errorMsg);
|
|
1036
|
-
clipboard.destroy();
|
|
1037
|
-
});
|
|
1038
|
-
|
|
1039
|
-
clipboard.onClick(clickEvent);
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
export function getQueryParam(variable) {
|
|
1043
|
-
let query = window.location.search.substring(1);
|
|
1044
|
-
let vars = query.split("&");
|
|
1045
|
-
for (let i = 0; i < vars.length; i++) {
|
|
1046
|
-
let pair = vars[i].split("=");
|
|
1047
|
-
if (pair[0] === variable) {
|
|
1048
|
-
return pair[1];
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
return undefined;
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
export function getDefaultFormConfig() {
|
|
1056
|
-
return {
|
|
1057
|
-
modelName: "formData",
|
|
1058
|
-
refName: "vForm",
|
|
1059
|
-
rulesName: "rules",
|
|
1060
|
-
labelWidth: 80,
|
|
1061
|
-
labelPosition: "left",
|
|
1062
|
-
size: "",
|
|
1063
|
-
labelAlign: "label-right-align",
|
|
1064
|
-
cssCode: "",
|
|
1065
|
-
customClass: "",
|
|
1066
|
-
functions: "",
|
|
1067
|
-
layoutType: "PC",
|
|
1068
|
-
dataSources: [],
|
|
1069
|
-
onBeforeCreated: "",
|
|
1070
|
-
onFormCreated: "",
|
|
1071
|
-
onFormBeforeMounted: "",
|
|
1072
|
-
onFormMounted: "",
|
|
1073
|
-
onFormDataChange: "",
|
|
1074
|
-
gridConfig: {
|
|
1075
|
-
accessReturnType: 1,
|
|
1076
|
-
isLoadDataByAccess: false,
|
|
1077
|
-
},
|
|
1078
|
-
getConfig: {
|
|
1079
|
-
accessType: "1",
|
|
1080
|
-
accessUrl: null,
|
|
1081
|
-
accessParam: null,
|
|
1082
|
-
accessCallback: null,
|
|
1083
|
-
scriptName: null,
|
|
1084
|
-
scriptCode: null,
|
|
1085
|
-
},
|
|
1086
|
-
saveConfig: {
|
|
1087
|
-
accessType: "1",
|
|
1088
|
-
accessUrl: null,
|
|
1089
|
-
accessParam: null,
|
|
1090
|
-
accessCallback: null,
|
|
1091
|
-
scriptName: null,
|
|
1092
|
-
scriptCode: null,
|
|
1093
|
-
},
|
|
1094
|
-
scriptList: [],
|
|
1095
|
-
formType: 0,
|
|
1096
|
-
entityTableCode: null,
|
|
1097
|
-
entityTableDesc: null,
|
|
1098
|
-
editFormCode: null,
|
|
1099
|
-
editFormName: null,
|
|
1100
|
-
searchDialogNameField: null,
|
|
1101
|
-
searchDialogUniqueField: null,
|
|
1102
|
-
entity: null,
|
|
1103
|
-
wfEnabled: false,
|
|
1104
|
-
isLoadEntity: false,
|
|
1105
|
-
formScriptCode: "getOne",
|
|
1106
|
-
formScriptParam: null,
|
|
1107
|
-
formScriptSuccess: null,
|
|
1108
|
-
saveScriptCode: "saveUpdate",
|
|
1109
|
-
wfConfig: null,
|
|
1110
|
-
wfStartBindSave: false,
|
|
1111
|
-
wfStartConfirmText: null,
|
|
1112
|
-
// 「保存并提交流程」内建按钮:由 detail-item 渲染,只在新增页(dataId 为空)显示。
|
|
1113
|
-
// 按钮名不在此处配,统一由后台 wf_diy_attribute(param18) 下发,见 components/wf/wfButtonName.js
|
|
1114
|
-
saveSubmitEnabled: false,
|
|
1115
|
-
// 「提交流程」「保存并提交流程」共用的提交前置处理脚本:校验通过后、确认框之前执行
|
|
1116
|
-
onBeforeSubmitWf: null,
|
|
1117
|
-
// 「提交流程」按钮显隐脚本:return false 隐藏,不配则显示
|
|
1118
|
-
wfStartBtnShow: null,
|
|
1119
|
-
wfAgreenBindSave: false,
|
|
1120
|
-
wfAgreeConfigData: [],
|
|
1121
|
-
wfConfigDataEnabled: false,
|
|
1122
|
-
wfConfigData: [],
|
|
1123
|
-
multiTabEnabled: false,
|
|
1124
|
-
multiTabLabelField: null,
|
|
1125
|
-
addTabEnabled: false, // 新增打开独立页签(不走「常规」页签)
|
|
1126
|
-
submitBehavior: "refreshCurrent", // 提交后行为: refreshCurrent(默认,留在详情页) | closeToList
|
|
1127
|
-
billNavEnabled: false, // 详情页签显示「上一单/下一单」翻单按钮
|
|
1128
|
-
addFormCode: null,
|
|
1129
|
-
addFormName: null,
|
|
1130
|
-
wfTheme: null,
|
|
1131
|
-
otherTabEnabled: false,
|
|
1132
|
-
otherTabList: [],
|
|
1133
|
-
hideNormalTab: false,
|
|
1134
|
-
customListTabLabel: null,
|
|
1135
|
-
globalConfig: null,
|
|
1136
|
-
// 表单级动态字段规则:按本地规则/后台脚本动态控制整个表单内任意字段/容器的显隐/必填/只读/禁用/取值
|
|
1137
|
-
dynamicFieldEnabled: false,
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
(t.
|
|
1159
|
-
(t.
|
|
1160
|
-
t
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
result[ai.name] =
|
|
1190
|
-
} else if ("
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
? (result[ai.name] = !
|
|
1195
|
-
:
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
} else if ("
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
let
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
"
|
|
1242
|
-
"
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
"
|
|
1260
|
-
"
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
"
|
|
1267
|
-
"
|
|
1268
|
-
"
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
export
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
return
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
const
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
return
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
const
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
"
|
|
1423
|
-
"
|
|
1424
|
-
"
|
|
1425
|
-
"
|
|
1426
|
-
"
|
|
1427
|
-
"
|
|
1428
|
-
"
|
|
1429
|
-
"
|
|
1430
|
-
"
|
|
1431
|
-
"
|
|
1432
|
-
"
|
|
1433
|
-
"
|
|
1434
|
-
"
|
|
1435
|
-
"
|
|
1436
|
-
"
|
|
1437
|
-
"
|
|
1438
|
-
"
|
|
1439
|
-
"
|
|
1440
|
-
"
|
|
1441
|
-
"
|
|
1442
|
-
"
|
|
1443
|
-
"
|
|
1444
|
-
"
|
|
1445
|
-
"
|
|
1446
|
-
"
|
|
1447
|
-
"
|
|
1448
|
-
"
|
|
1449
|
-
"
|
|
1450
|
-
"
|
|
1451
|
-
"
|
|
1452
|
-
"
|
|
1453
|
-
"
|
|
1454
|
-
"
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
? o.replace(new RegExp("
|
|
1534
|
-
:
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
return
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
"detail
|
|
1576
|
-
"
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
}
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
return value;
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1
|
+
import Clipboard from "clipboard";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import request from "../../../utils/request.js";
|
|
4
|
+
import { decode } from "js-base64";
|
|
5
|
+
|
|
6
|
+
export function getAccessUrl() {
|
|
7
|
+
return SUPPORT_PREFIX + "/report_ins/getData";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function isNull(value) {
|
|
11
|
+
return value === null || value === undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function isNilOrEmptyStr(value) {
|
|
15
|
+
return value === null || value === undefined || value === "";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function isNotNull(value) {
|
|
19
|
+
return value !== null && value !== undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const ATTACHMENT_WIDGET_TYPES = ["vabUpload", "baseAttachment", "vabUpload2"];
|
|
23
|
+
|
|
24
|
+
const PROJECT_TAG_WIDGET_TYPES = [
|
|
25
|
+
"project-tag",
|
|
26
|
+
"user-project-tag",
|
|
27
|
+
"saleOrg-project-tag",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const VABSEARCH_WIDGET_TYPES = ["vabsearch", "singerSearch", "multiSearch"];
|
|
31
|
+
|
|
32
|
+
export function isAttachmentWidgetType(type) {
|
|
33
|
+
return ATTACHMENT_WIDGET_TYPES.includes(type);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function isVabsearchWidgetType(type) {
|
|
37
|
+
return VABSEARCH_WIDGET_TYPES.includes(type);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function isVabsearchMultiWidget(widget) {
|
|
41
|
+
if (!widget) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const type = widget.type;
|
|
45
|
+
if (type === "multiSearch") {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (!isVabsearchWidgetType(type)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const options = widget.options || {};
|
|
52
|
+
return !!(
|
|
53
|
+
options.multipleChoices || options.searchDialogConfig?.multipleChoices
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** 绑定值为数组的字段组件(含附件) */
|
|
58
|
+
export function isArrayValueWidgetType(type, options = {}) {
|
|
59
|
+
if (isAttachmentWidgetType(type)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
if (type === "checkbox") {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (type === "select" && options.multiple) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
if (type === "time-range" || type === "date-range") {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
if (type === "date" && options.type === "dates") {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
if (PROJECT_TAG_WIDGET_TYPES.includes(type)) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
if (type === "multiSearch") {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
if (
|
|
81
|
+
type === "vabsearch" &&
|
|
82
|
+
(options.multipleChoices || options.searchDialogConfig?.multipleChoices)
|
|
83
|
+
) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** 数组类字段值是否为空(用于必填校验) */
|
|
90
|
+
export function isEmptyArrayFieldValue(value, type, options = {}) {
|
|
91
|
+
if (value === null || value === undefined) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
if (type === "time-range" || type === "date-range") {
|
|
95
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
return value.every(
|
|
99
|
+
(item) => item === null || item === undefined || item === ""
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
/* 附件字段开了「值存为URL」且限制数量为 1 时,模型里存的是单个 URL 字符串,
|
|
103
|
+
不能按空数组判空,否则必填校验永远不通过 */
|
|
104
|
+
if (isAttachmentWidgetType(type) && options.urlValueEnabled) {
|
|
105
|
+
if (typeof value === "string") {
|
|
106
|
+
return !value.trim();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (!Array.isArray(value)) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return value.length === 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function isEmptyStr(str) {
|
|
116
|
+
//return (str === undefined) || (!str) || (!/[^\s]/.test(str));
|
|
117
|
+
return (
|
|
118
|
+
str === undefined ||
|
|
119
|
+
(!str && str !== 0 && str !== "0") ||
|
|
120
|
+
!/[^\s]/.test(str)
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export const generateId = function () {
|
|
125
|
+
return Math.floor(
|
|
126
|
+
Math.random() * 100000 + Math.random() * 20000 + Math.random() * 5000
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// 审计字段:创建/修改人及时间,camelCase 与 snake_case 两种形式;后端保存时重新生成
|
|
131
|
+
const AUDIT_FIELDS = [
|
|
132
|
+
"createBy",
|
|
133
|
+
"createDate",
|
|
134
|
+
"modifyBy",
|
|
135
|
+
"modifyDate",
|
|
136
|
+
"_createBy",
|
|
137
|
+
"_modifyBy",
|
|
138
|
+
"create_by",
|
|
139
|
+
"create_date",
|
|
140
|
+
"modify_by",
|
|
141
|
+
"modify_date",
|
|
142
|
+
];
|
|
143
|
+
// 展示态字段:查询时后端回填的创建/修改人昵称、手机号,保存前需剔除
|
|
144
|
+
const DISPLAY_FIELDS = [
|
|
145
|
+
"_createNickName",
|
|
146
|
+
"_createMobile",
|
|
147
|
+
"_modifyNickName",
|
|
148
|
+
"_modifyMobile",
|
|
149
|
+
];
|
|
150
|
+
// 子表/树表外键:复制场景下需断链
|
|
151
|
+
export const XFORM_SUB_FK_FIELDS = [
|
|
152
|
+
"head_table_id",
|
|
153
|
+
"headTableId",
|
|
154
|
+
"alias_id",
|
|
155
|
+
"object_foreign_id",
|
|
156
|
+
];
|
|
157
|
+
// 主表系统字段(含 id):供对比功能 sanitizeChangeData 清洗使用
|
|
158
|
+
export const XFORM_SYSTEM_FIELDS = ["id", ...AUDIT_FIELDS];
|
|
159
|
+
// 行级复制清洗字段:审计 + 展示态 + 子表外键;不含 id/parentField,
|
|
160
|
+
// 二者承载树层级,由调用方的树逻辑单独生成/重映射
|
|
161
|
+
export const XFORM_ROW_CLEAN_FIELDS = [
|
|
162
|
+
...AUDIT_FIELDS,
|
|
163
|
+
...DISPLAY_FIELDS,
|
|
164
|
+
...XFORM_SUB_FK_FIELDS,
|
|
165
|
+
];
|
|
166
|
+
|
|
167
|
+
export const createUUID = function () {
|
|
168
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
|
|
169
|
+
.replace(/[xy]/g, function (c) {
|
|
170
|
+
var r = (Math.random() * 16) | 0,
|
|
171
|
+
v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
172
|
+
return v.toString(16);
|
|
173
|
+
})
|
|
174
|
+
.replaceAll("-", "");
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export const deepClone = function (origin) {
|
|
178
|
+
if (origin === undefined) {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return JSON.parse(JSON.stringify(origin));
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export const overwriteObj = function (obj1, obj2) {
|
|
186
|
+
/* 浅拷贝对象属性,obj2覆盖obj1 */
|
|
187
|
+
// for (let prop in obj2) {
|
|
188
|
+
// if (obj2.hasOwnProperty(prop)) {
|
|
189
|
+
// obj1[prop] = obj2[prop]
|
|
190
|
+
// }
|
|
191
|
+
// }
|
|
192
|
+
|
|
193
|
+
Object.keys(obj2).forEach((prop) => {
|
|
194
|
+
obj1[prop] = obj2[prop];
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export const addWindowResizeHandler = function (handler) {
|
|
199
|
+
// qiankun 沙箱下 window.onresize 直赋值落在代理对象上收不到真实事件,
|
|
200
|
+
// 统一走 addEventListener(沙箱会在子应用卸载时自动清理)。
|
|
201
|
+
// 主应用/独立运行时没有沙箱兜底,返回解绑函数供调用方在 beforeDestroy 中调用,
|
|
202
|
+
// 否则监听闭包会钉住已销毁的组件实例(内存泄露)
|
|
203
|
+
window.addEventListener("resize", handler);
|
|
204
|
+
return function () {
|
|
205
|
+
window.removeEventListener("resize", handler);
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const createStyleSheet = function () {
|
|
210
|
+
let head = document.head || document.getElementsByTagName("head")[0];
|
|
211
|
+
let style = document.createElement("style");
|
|
212
|
+
style.type = "text/css";
|
|
213
|
+
head.appendChild(style);
|
|
214
|
+
return style.sheet;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export const insertCustomCssToHead = function (cssCode, formId = "") {
|
|
218
|
+
let head = document.getElementsByTagName("head")[0];
|
|
219
|
+
let oldStyle = document.getElementById("vform-custom-css");
|
|
220
|
+
if (!!oldStyle) {
|
|
221
|
+
head.removeChild(oldStyle); //先清除后插入!!
|
|
222
|
+
}
|
|
223
|
+
if (!!formId) {
|
|
224
|
+
oldStyle = document.getElementById("vform-custom-css" + "-" + formId);
|
|
225
|
+
!!oldStyle && head.removeChild(oldStyle); //先清除后插入!!
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
let newStyle = document.createElement("style");
|
|
229
|
+
newStyle.type = "text/css";
|
|
230
|
+
newStyle.rel = "stylesheet";
|
|
231
|
+
newStyle.id = !!formId
|
|
232
|
+
? "vform-custom-css" + "-" + formId
|
|
233
|
+
: "vform-custom-css";
|
|
234
|
+
try {
|
|
235
|
+
newStyle.appendChild(document.createTextNode(cssCode));
|
|
236
|
+
} catch (ex) {
|
|
237
|
+
newStyle.styleSheet.cssText = cssCode;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
head.appendChild(newStyle);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* 注入表单全局函数(formConfig.functions):把代码执行在【真实全局作用域】,
|
|
245
|
+
* 使表单各类事件脚本能引用到其中定义的函数。
|
|
246
|
+
*
|
|
247
|
+
* 为什么不再插 <script>:事件脚本一律由 new Function 创建,其作用域链恒为真实全局作用域;
|
|
248
|
+
* 而 qiankun 沙箱 patch 了 head/body 的 appendChild,子应用里动态 script 不会进 DOM,
|
|
249
|
+
* 改由 execScripts 以 (function(window){with(window){...}}).bind(proxy) 包裹执行——
|
|
250
|
+
* `function foo(){}` 落在包裹函数的作用域里、`window.foo=` 落在 proxy 上,两者在真实
|
|
251
|
+
* window 上都不存在,调用侧必然 ReferenceError 且被各处 try/catch 吞掉(静默失效)。
|
|
252
|
+
*
|
|
253
|
+
* 间接 eval 由规范保证在全局作用域、非严格模式下求值,函数声明因此成为真实 window 的属性,
|
|
254
|
+
* 与 new Function 的取值环境对齐;qiankun 对 `eval` 有显式特判(proxySandbox 返回原生 eval),
|
|
255
|
+
* 主应用形态与子应用形态行为一致。
|
|
256
|
+
*
|
|
257
|
+
* 函数名与 formId 参数保持不变:调用方(含 haier 分支)沿用此签名,改名只增加同步面。
|
|
258
|
+
* 现已不产生 DOM 节点、无需按 id 清理,formId 仅用于 sourceURL 定位。
|
|
259
|
+
*/
|
|
260
|
+
export const insertGlobalFunctionsToHtml = function (
|
|
261
|
+
functionsCode,
|
|
262
|
+
formId = ""
|
|
263
|
+
) {
|
|
264
|
+
if (!functionsCode || typeof functionsCode !== "string") {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
let sourceName = !!formId
|
|
268
|
+
? "v_form_global_functions" + "-" + formId
|
|
269
|
+
: "v_form_global_functions";
|
|
270
|
+
try {
|
|
271
|
+
// (0, eval) 是间接调用形式,不可简写为 eval(...):直接 eval 会继承当前模块作用域,
|
|
272
|
+
// 函数声明将落在模块内而非真实 window 上。sourceURL 让 devtools 里可定位、可下断点。
|
|
273
|
+
(0, eval)(functionsCode + "\n//# sourceURL=" + sourceName + ".js");
|
|
274
|
+
} catch (e) {
|
|
275
|
+
// 原先 <script> 注入时语法/运行时错误只进 window.onerror、不影响表单渲染,
|
|
276
|
+
// 这里必须同样吞掉:否则会中断 initFormObject 整条表单初始化链路
|
|
277
|
+
console.error("[xform] 表单全局函数执行失败:" + sourceName, e);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
export const optionExists = function (optionsObj, optionName) {
|
|
282
|
+
if (!optionsObj) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return Object.keys(optionsObj).indexOf(optionName) > -1;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
export const loadRemoteScript = function (srcPath, callback) {
|
|
290
|
+
/*加载远程js,加载成功后执行回调函数*/
|
|
291
|
+
let sid = encodeURIComponent(srcPath);
|
|
292
|
+
let oldScriptEle = document.getElementById(sid);
|
|
293
|
+
|
|
294
|
+
if (!oldScriptEle) {
|
|
295
|
+
let s = document.createElement("script");
|
|
296
|
+
s.src = srcPath;
|
|
297
|
+
s.id = sid;
|
|
298
|
+
document.body.appendChild(s);
|
|
299
|
+
|
|
300
|
+
s.onload = s.onreadystatechange = function (_, isAbort) {
|
|
301
|
+
/* 借鉴自ace.js */
|
|
302
|
+
if (
|
|
303
|
+
isAbort ||
|
|
304
|
+
!s.readyState ||
|
|
305
|
+
s.readyState === "loaded" ||
|
|
306
|
+
s.readyState === "complete"
|
|
307
|
+
) {
|
|
308
|
+
s = s.onload = s.onreadystatechange = null;
|
|
309
|
+
if (!isAbort) {
|
|
310
|
+
callback();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
export function traverseFieldWidgets(
|
|
318
|
+
widgetList,
|
|
319
|
+
handler,
|
|
320
|
+
parent = null,
|
|
321
|
+
staticWidgetsIncluded
|
|
322
|
+
) {
|
|
323
|
+
if (!widgetList) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
loopHandleWidget(widgetList, (w, parent) => {
|
|
328
|
+
if (w.formItemFlag || (w.formItemFlag === false && staticWidgetsIncluded)) {
|
|
329
|
+
handler(w, parent);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
/* widgetList.forEach((w) => {
|
|
334
|
+
if (w.formItemFlag || (w.formItemFlag === false && staticWidgetsIncluded)) {
|
|
335
|
+
handler(w, parent);
|
|
336
|
+
} else if (w.type === "grid") {
|
|
337
|
+
w.cols.forEach((col) => {
|
|
338
|
+
traverseFieldWidgets(col.widgetList, handler, w, staticWidgetsIncluded);
|
|
339
|
+
});
|
|
340
|
+
} else if (w.type === "table") {
|
|
341
|
+
w.rows.forEach((row) => {
|
|
342
|
+
row.cols.forEach((cell) => {
|
|
343
|
+
traverseFieldWidgets(
|
|
344
|
+
cell.widgetList,
|
|
345
|
+
handler,
|
|
346
|
+
w,
|
|
347
|
+
staticWidgetsIncluded
|
|
348
|
+
);
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
} else if (w.type === "tab") {
|
|
352
|
+
w.tabs.forEach((tab) => {
|
|
353
|
+
traverseFieldWidgets(tab.widgetList, handler, w, staticWidgetsIncluded);
|
|
354
|
+
});
|
|
355
|
+
} else if (w.type === "sub-form" || w.type === "grid-sub-form") {
|
|
356
|
+
traverseFieldWidgets(w.widgetList, handler, w, staticWidgetsIncluded);
|
|
357
|
+
} else if (w.category === "container") {
|
|
358
|
+
//自定义容器
|
|
359
|
+
traverseFieldWidgets(w.widgetList, handler, w, staticWidgetsIncluded);
|
|
360
|
+
}
|
|
361
|
+
}); */
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export function traverseContainerWidgets(
|
|
365
|
+
widgetList,
|
|
366
|
+
handler,
|
|
367
|
+
skipDialogAndDrawer
|
|
368
|
+
) {
|
|
369
|
+
if (!widgetList) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
loopHandleWidget(widgetList, (w, parent) => {
|
|
374
|
+
if (w.category === "container") {
|
|
375
|
+
if (
|
|
376
|
+
skipDialogAndDrawer &&
|
|
377
|
+
(w.type === "vf-dialog" || w.type === "vf-drawer")
|
|
378
|
+
) {
|
|
379
|
+
//什么也不做
|
|
380
|
+
} else {
|
|
381
|
+
handler(w);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
/* widgetList.forEach((w) => {
|
|
387
|
+
if (w.category === "container") {
|
|
388
|
+
if (
|
|
389
|
+
skipDialogAndDrawer &&
|
|
390
|
+
(w.type === "vf-dialog" || w.type === "vf-drawer")
|
|
391
|
+
) {
|
|
392
|
+
//什么也不做
|
|
393
|
+
} else {
|
|
394
|
+
handler(w);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (w.type === "grid") {
|
|
399
|
+
w.cols.forEach((col) => {
|
|
400
|
+
traverseContainerWidgets(col.widgetList, handler);
|
|
401
|
+
});
|
|
402
|
+
} else if (w.type === "table") {
|
|
403
|
+
w.rows.forEach((row) => {
|
|
404
|
+
row.cols.forEach((cell) => {
|
|
405
|
+
traverseContainerWidgets(cell.widgetList, handler);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
} else if (w.type === "tab") {
|
|
409
|
+
w.tabs.forEach((tab) => {
|
|
410
|
+
traverseContainerWidgets(tab.widgetList, handler);
|
|
411
|
+
});
|
|
412
|
+
} else if (w.type === "sub-form" || w.type === "grid-sub-form") {
|
|
413
|
+
traverseContainerWidgets(w.widgetList, handler);
|
|
414
|
+
} else if (w.category === "container") {
|
|
415
|
+
//自定义容器
|
|
416
|
+
if (
|
|
417
|
+
skipDialogAndDrawer &&
|
|
418
|
+
(w.type === "vf-dialog" || w.type === "vf-drawer")
|
|
419
|
+
) {
|
|
420
|
+
//什么也不做
|
|
421
|
+
} else {
|
|
422
|
+
traverseContainerWidgets(w.widgetList, handler);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}); */
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
export function traverseAllWidgetsNew(widgetList, callback) {
|
|
429
|
+
if (!widgetList) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
let columnLoopDo = (t, parentWidget) => {
|
|
433
|
+
if (t.children && t.children.length) {
|
|
434
|
+
t.children.forEach((item) => {
|
|
435
|
+
columnLoopDo(item, parentWidget);
|
|
436
|
+
});
|
|
437
|
+
} else {
|
|
438
|
+
if (t.widget) {
|
|
439
|
+
callback && callback(t.widget, parentWidget);
|
|
440
|
+
}
|
|
441
|
+
if (t.editWidget) {
|
|
442
|
+
callback && callback(t.editWidget, parentWidget);
|
|
443
|
+
}
|
|
444
|
+
if (t.widgetList && t.widgetList.length) {
|
|
445
|
+
loopHandleWidget(t.widgetList, (widget) => {
|
|
446
|
+
callback && callback(widget, parentWidget);
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
loopHandleWidget(widgetList, (widget, parentWidget) => {
|
|
452
|
+
if (callback) {
|
|
453
|
+
callback(widget, parentWidget);
|
|
454
|
+
if (widget.type === "data-table") {
|
|
455
|
+
for (let item of widget.options.tableColumns) {
|
|
456
|
+
columnLoopDo(item, parentWidget);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
export function traverseAllWidgets(widgetList, handler) {
|
|
464
|
+
if (!widgetList) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
loopHandleWidget(widgetList, (w, parentWidget) => {
|
|
469
|
+
handler(w, parentWidget);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
/* widgetList.forEach((w) => {
|
|
473
|
+
handler(w);
|
|
474
|
+
|
|
475
|
+
if (w.type === "grid") {
|
|
476
|
+
w.cols.forEach((col) => {
|
|
477
|
+
handler(col);
|
|
478
|
+
traverseAllWidgets(col.widgetList, handler);
|
|
479
|
+
});
|
|
480
|
+
} else if (w.type === "table") {
|
|
481
|
+
w.rows.forEach((row) => {
|
|
482
|
+
row.cols.forEach((cell) => {
|
|
483
|
+
handler(cell);
|
|
484
|
+
traverseAllWidgets(cell.widgetList, handler);
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
} else if (w.type === "tab") {
|
|
488
|
+
w.tabs.forEach((tab) => {
|
|
489
|
+
traverseAllWidgets(tab.widgetList, handler);
|
|
490
|
+
});
|
|
491
|
+
} else if (w.type === "sub-form" || w.type === "grid-sub-form") {
|
|
492
|
+
traverseAllWidgets(w.widgetList, handler);
|
|
493
|
+
} else if (w.category === "container") {
|
|
494
|
+
//自定义容器
|
|
495
|
+
traverseAllWidgets(w.widgetList, handler);
|
|
496
|
+
}
|
|
497
|
+
}); */
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function handleWidgetForTraverse(
|
|
501
|
+
widget,
|
|
502
|
+
handler,
|
|
503
|
+
staticWidgetsIncluded = false
|
|
504
|
+
) {
|
|
505
|
+
if (!!widget.category && widget.category === "container") {
|
|
506
|
+
traverseFieldWidgetsOfContainer(widget, handler);
|
|
507
|
+
} else if (widget.formItemFlag) {
|
|
508
|
+
handler(widget);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* 容器 → 子节点所在字段名。
|
|
514
|
+
*
|
|
515
|
+
* 注意:全库同一语义的映射有多份(designer.js 的局部表、indexMixin 的
|
|
516
|
+
* getTableFiledMap / getFormTemplateTableDTOs 两张局部表),改这里时请一并核对,
|
|
517
|
+
* 漏一份的后果参见 loopHandleWidgetItem 里关于 H5 容器的注释。
|
|
518
|
+
*/
|
|
519
|
+
export const itemFieldMap = {
|
|
520
|
+
grid: "cols",
|
|
521
|
+
table: "rows",
|
|
522
|
+
"table-cell": "widgetList",
|
|
523
|
+
"h5-table": "rows",
|
|
524
|
+
"h5-table-cell": "widgetList",
|
|
525
|
+
tab: "tabs",
|
|
526
|
+
"tab-pane": "widgetList",
|
|
527
|
+
"grid-col": "widgetList",
|
|
528
|
+
"vf-box": "widgetList",
|
|
529
|
+
card: "widgetList",
|
|
530
|
+
detail: "panes",
|
|
531
|
+
"detail-plain": "panes", // 与 indexMixin 的两张表对齐,此前这张漏了
|
|
532
|
+
"detail-pane": "widgetList",
|
|
533
|
+
"detail-h5": "panes",
|
|
534
|
+
"h5-card": "panes",
|
|
535
|
+
"h5-card-pane": "widgetList",
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* 遍历容器内的字段组件
|
|
540
|
+
* @param con
|
|
541
|
+
* @param handler
|
|
542
|
+
* @param staticWidgetsIncluded
|
|
543
|
+
*/
|
|
544
|
+
export function traverseFieldWidgetsOfContainer(
|
|
545
|
+
con,
|
|
546
|
+
handler,
|
|
547
|
+
staticWidgetsIncluded = false
|
|
548
|
+
) {
|
|
549
|
+
/*loopHandleWidget([con],(w, parent)=>{
|
|
550
|
+
handleWidgetForTraverse(w, handler, staticWidgetsIncluded);
|
|
551
|
+
});*/
|
|
552
|
+
if (con.type === "grid") {
|
|
553
|
+
con.cols.forEach((col) => {
|
|
554
|
+
col.widgetList.forEach((cw) => {
|
|
555
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
} else if (con.type === "table") {
|
|
559
|
+
con.rows.forEach((row) => {
|
|
560
|
+
row.cols.forEach((cell) => {
|
|
561
|
+
cell.widgetList.forEach((cw) => {
|
|
562
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
563
|
+
});
|
|
564
|
+
});
|
|
565
|
+
});
|
|
566
|
+
} else if (con.type === "tab") {
|
|
567
|
+
con.tabs.forEach((tab) => {
|
|
568
|
+
tab.widgetList.forEach((cw) => {
|
|
569
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
570
|
+
});
|
|
571
|
+
});
|
|
572
|
+
} else if (con.type === "sub-form" || con.type === "grid-sub-form") {
|
|
573
|
+
con.widgetList.forEach((cw) => {
|
|
574
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
575
|
+
});
|
|
576
|
+
} else if (con.type === "data-table") {
|
|
577
|
+
/*con.widgetList.forEach((cw) => {
|
|
578
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
579
|
+
});*/
|
|
580
|
+
if (!!con.widgetList) {
|
|
581
|
+
con.widgetList.forEach((childItem) => {
|
|
582
|
+
loopHandleWidgetItem(childItem, con, handler);
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
if (!!con.buttons) {
|
|
586
|
+
con.buttons.forEach((childItem) => {
|
|
587
|
+
loopHandleWidgetItem(childItem, con, handler);
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
for (let column of con.options.tableColumns) {
|
|
591
|
+
if (column.widget) {
|
|
592
|
+
handleWidgetForTraverse(column.widget, handler, staticWidgetsIncluded);
|
|
593
|
+
}
|
|
594
|
+
if (column.widgetList) {
|
|
595
|
+
column.widgetList.forEach((cw) => {
|
|
596
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
597
|
+
});
|
|
598
|
+
/*loopHandleWidget(column.widgetList, (cw) => {
|
|
599
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
600
|
+
});*/
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
} else if (con.category === "container") {
|
|
604
|
+
//自定义容器
|
|
605
|
+
/*let key = itemFieldMap[con.type]
|
|
606
|
+
con[key].forEach((cw) => {
|
|
607
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded);
|
|
608
|
+
});*/
|
|
609
|
+
|
|
610
|
+
/*con.widgetList.forEach(cw => {
|
|
611
|
+
handleWidgetForTraverse(cw, handler, staticWidgetsIncluded)
|
|
612
|
+
})*/
|
|
613
|
+
loopHandleWidgetItem(con, null, (w) => {
|
|
614
|
+
if (con.id != w.id)
|
|
615
|
+
handleWidgetForTraverse(w, handler, staticWidgetsIncluded);
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
function handleContainerTraverse(
|
|
621
|
+
widget,
|
|
622
|
+
fieldHandler,
|
|
623
|
+
containerHandler,
|
|
624
|
+
internalContainerCallFlag,
|
|
625
|
+
staticWidgetsIncluded
|
|
626
|
+
) {
|
|
627
|
+
if (!!widget.category && widget.category === "container") {
|
|
628
|
+
traverseWidgetsOfContainer(
|
|
629
|
+
widget,
|
|
630
|
+
fieldHandler,
|
|
631
|
+
containerHandler,
|
|
632
|
+
internalContainerCallFlag,
|
|
633
|
+
staticWidgetsIncluded
|
|
634
|
+
);
|
|
635
|
+
} else if (widget.formItemFlag) {
|
|
636
|
+
fieldHandler(widget);
|
|
637
|
+
} else if (staticWidgetsIncluded) {
|
|
638
|
+
fieldHandler(widget);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* 遍历容器内部的字段组件和容器组件
|
|
644
|
+
* @param con
|
|
645
|
+
* @param fieldHandler
|
|
646
|
+
* @param containerHandler
|
|
647
|
+
* @param internalContainerCallFlag 是否需要处理内部容器组件,默认不处理
|
|
648
|
+
* @param staticWidgetsIncluded 是否需要处理静态非表单交互类组件
|
|
649
|
+
*/
|
|
650
|
+
export function traverseWidgetsOfContainer(
|
|
651
|
+
con,
|
|
652
|
+
fieldHandler,
|
|
653
|
+
containerHandler,
|
|
654
|
+
internalContainerCallFlag,
|
|
655
|
+
staticWidgetsIncluded
|
|
656
|
+
) {
|
|
657
|
+
if (con.category === "container") {
|
|
658
|
+
containerHandler(con);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/*loopHandleWidget([con], (cw, parent) => {
|
|
662
|
+
if (con.id !== cw.id) {
|
|
663
|
+
handleContainerTraverse(
|
|
664
|
+
cw,
|
|
665
|
+
fieldHandler,
|
|
666
|
+
containerHandler,
|
|
667
|
+
internalContainerCallFlag,
|
|
668
|
+
staticWidgetsIncluded
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
});*/
|
|
672
|
+
|
|
673
|
+
if (con.type === "grid") {
|
|
674
|
+
con.cols.forEach((col) => {
|
|
675
|
+
if (internalContainerCallFlag) {
|
|
676
|
+
containerHandler(col);
|
|
677
|
+
}
|
|
678
|
+
col.widgetList.forEach((cw) => {
|
|
679
|
+
handleContainerTraverse(
|
|
680
|
+
cw,
|
|
681
|
+
fieldHandler,
|
|
682
|
+
containerHandler,
|
|
683
|
+
internalContainerCallFlag,
|
|
684
|
+
staticWidgetsIncluded
|
|
685
|
+
);
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
} else if (con.type === "table") {
|
|
689
|
+
con.rows.forEach((row) => {
|
|
690
|
+
if (internalContainerCallFlag) {
|
|
691
|
+
containerHandler(row);
|
|
692
|
+
}
|
|
693
|
+
row.cols.forEach((cell) => {
|
|
694
|
+
if (internalContainerCallFlag) {
|
|
695
|
+
containerHandler(cell);
|
|
696
|
+
}
|
|
697
|
+
cell.widgetList.forEach((cw) => {
|
|
698
|
+
handleContainerTraverse(
|
|
699
|
+
cw,
|
|
700
|
+
fieldHandler,
|
|
701
|
+
containerHandler,
|
|
702
|
+
internalContainerCallFlag,
|
|
703
|
+
staticWidgetsIncluded
|
|
704
|
+
);
|
|
705
|
+
});
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
} else if (con.type === "tab") {
|
|
709
|
+
con.tabs.forEach((tab) => {
|
|
710
|
+
if (internalContainerCallFlag) {
|
|
711
|
+
containerHandler(tab);
|
|
712
|
+
}
|
|
713
|
+
tab.widgetList.forEach((cw) => {
|
|
714
|
+
handleContainerTraverse(
|
|
715
|
+
cw,
|
|
716
|
+
fieldHandler,
|
|
717
|
+
containerHandler,
|
|
718
|
+
internalContainerCallFlag,
|
|
719
|
+
staticWidgetsIncluded
|
|
720
|
+
);
|
|
721
|
+
});
|
|
722
|
+
});
|
|
723
|
+
} else if (con.type === "sub-form" || con.type === "grid-sub-form") {
|
|
724
|
+
con.widgetList.forEach((cw) => {
|
|
725
|
+
handleContainerTraverse(
|
|
726
|
+
cw,
|
|
727
|
+
fieldHandler,
|
|
728
|
+
containerHandler,
|
|
729
|
+
internalContainerCallFlag,
|
|
730
|
+
staticWidgetsIncluded
|
|
731
|
+
);
|
|
732
|
+
});
|
|
733
|
+
} else if (con.category === "container") {
|
|
734
|
+
//自定义容器
|
|
735
|
+
/* 容器类型不在 itemFieldMap 里时 key 是 undefined,con[undefined] 也是 undefined,
|
|
736
|
+
直接 .forEach 会抛 TypeError —— 表里没覆盖到的容器(list-h5、detail-tabs、
|
|
737
|
+
tree-pane…)都会中招,故取值后判空再遍历。 */
|
|
738
|
+
let key = itemFieldMap[con.type];
|
|
739
|
+
let childList = key ? con[key] : null;
|
|
740
|
+
if (childList && childList.length > 0) {
|
|
741
|
+
childList.forEach((cw) => {
|
|
742
|
+
handleContainerTraverse(
|
|
743
|
+
cw,
|
|
744
|
+
fieldHandler,
|
|
745
|
+
containerHandler,
|
|
746
|
+
internalContainerCallFlag,
|
|
747
|
+
staticWidgetsIncluded
|
|
748
|
+
);
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
export function traverseWidgetsOfGridCol(
|
|
755
|
+
gridCol,
|
|
756
|
+
fieldHandler,
|
|
757
|
+
containerHandler
|
|
758
|
+
) {
|
|
759
|
+
// if (gridCol.category === 'container') {
|
|
760
|
+
// containerHandler(gridCol)
|
|
761
|
+
// }
|
|
762
|
+
|
|
763
|
+
if (gridCol.type === "grid-col") {
|
|
764
|
+
gridCol.widgetList.forEach((cw) => {
|
|
765
|
+
handleContainerTraverse(cw, fieldHandler, containerHandler);
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* 获取所有字段组件
|
|
772
|
+
* @param widgetList
|
|
773
|
+
* @param staticWidgetsIncluded 是否包含按钮等静态组件,默认不包含
|
|
774
|
+
* @returns {[]}
|
|
775
|
+
*/
|
|
776
|
+
export function getAllFieldWidgets(widgetList, staticWidgetsIncluded) {
|
|
777
|
+
if (!widgetList) {
|
|
778
|
+
return [];
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
let result = [];
|
|
782
|
+
let handlerFn = (w) => {
|
|
783
|
+
result.push({
|
|
784
|
+
type: w.type,
|
|
785
|
+
name: w.options.name,
|
|
786
|
+
field: w,
|
|
787
|
+
});
|
|
788
|
+
};
|
|
789
|
+
traverseFieldWidgets(widgetList, handlerFn, null, staticWidgetsIncluded);
|
|
790
|
+
|
|
791
|
+
return result;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* 获取所有容器组件
|
|
796
|
+
* @param widgetList
|
|
797
|
+
* @param skipDialogAndDrawer 是否跳过弹窗和抽屉内部组件,默认不跳过
|
|
798
|
+
* @returns {[]}
|
|
799
|
+
*/
|
|
800
|
+
export function getAllContainerWidgets(widgetList, skipDialogAndDrawer) {
|
|
801
|
+
if (!widgetList) {
|
|
802
|
+
return [];
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
let result = [];
|
|
806
|
+
let handlerFn = (w) => {
|
|
807
|
+
result.push({
|
|
808
|
+
type: w.type,
|
|
809
|
+
name: w.options.name,
|
|
810
|
+
container: w,
|
|
811
|
+
});
|
|
812
|
+
};
|
|
813
|
+
traverseContainerWidgets(widgetList, handlerFn, skipDialogAndDrawer);
|
|
814
|
+
|
|
815
|
+
return result;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
export function getFieldWidgetByName(
|
|
819
|
+
widgetList,
|
|
820
|
+
fieldName,
|
|
821
|
+
staticWidgetsIncluded
|
|
822
|
+
) {
|
|
823
|
+
if (!widgetList) {
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
let foundWidget = null;
|
|
828
|
+
let handlerFn = (widget) => {
|
|
829
|
+
if (widget.options.name === fieldName) {
|
|
830
|
+
foundWidget = widget;
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
|
|
834
|
+
traverseFieldWidgets(widgetList, handlerFn, null, staticWidgetsIncluded);
|
|
835
|
+
return foundWidget;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
export const columnFormatMap = {
|
|
839
|
+
editInput: "input",
|
|
840
|
+
editNumber: "number",
|
|
841
|
+
editDate: "date",
|
|
842
|
+
editSelect: "select",
|
|
843
|
+
editSearch: "vabsearch",
|
|
844
|
+
editAttachment: "baseAttachment",
|
|
845
|
+
editStatus: "status",
|
|
846
|
+
aText: "a-text",
|
|
847
|
+
aLink: "a-link",
|
|
848
|
+
editDelete: "a-link",
|
|
849
|
+
editButton: "a-link",
|
|
850
|
+
button: "button",
|
|
851
|
+
addSiblingEditRow: "a-link",
|
|
852
|
+
addChildTreeRow: "a-link",
|
|
853
|
+
moveUpRow: "a-link",
|
|
854
|
+
moveDownRow: "a-link",
|
|
855
|
+
removeTreeRow: "a-link",
|
|
856
|
+
text: "text",
|
|
857
|
+
checkbox: "checkbox",
|
|
858
|
+
radio: "radio",
|
|
859
|
+
dropdown: "dropdown",
|
|
860
|
+
textarea: "textarea",
|
|
861
|
+
editScriptInput: "script-input",
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
/** 列 widget 扩展选项:动态列 widgetOptions;设计器静态列 columnOption */
|
|
865
|
+
export function getColumnWidgetOptions(row, isEdit = false) {
|
|
866
|
+
if (!row) {
|
|
867
|
+
return undefined;
|
|
868
|
+
}
|
|
869
|
+
if (isEdit) {
|
|
870
|
+
return row.editWidgetOptions ?? row.editColumnOption;
|
|
871
|
+
}
|
|
872
|
+
return row.widgetOptions ?? row.columnOption;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* 复制列内 field widget,用于展示组件与编辑组件同类型、只配置了其中一方的列。
|
|
877
|
+
* 另一方若按类型新建空白 schema,只配在已有一方的 defaultValue / optionItems /
|
|
878
|
+
* searchDialogConfig 等会全部丢失(编辑表新增行取默认值同样受影响)。
|
|
879
|
+
* 字段绑定 keyName 保持不变;id 与 name 必须重新生成——refList 按
|
|
880
|
+
* options.name + 行键 注册,fieldSchemaMap 按 id 索引,两个组件同名会互相覆盖。
|
|
881
|
+
*/
|
|
882
|
+
export function cloneColumnFieldWidget(fieldWidget) {
|
|
883
|
+
if (!fieldWidget) {
|
|
884
|
+
return null;
|
|
885
|
+
}
|
|
886
|
+
let newWidget = deepClone(fieldWidget);
|
|
887
|
+
newWidget.id = String(newWidget.type).replace(/-/g, "") + generateId();
|
|
888
|
+
if (newWidget.hasOwnProperty("tableField")) {
|
|
889
|
+
newWidget.tableField = newWidget.id;
|
|
890
|
+
}
|
|
891
|
+
newWidget.options.name = newWidget.id;
|
|
892
|
+
return newWidget;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* 展平数据表格列配置,只返回叶子列。
|
|
897
|
+
* tableColumns 里带 children 的是分组表头(自身 prop 为空),真正的业务字段挂在 children 上,
|
|
898
|
+
* 因此凡是按 prop 取字段的逻辑都必须先展平,不能只看顶层。
|
|
899
|
+
*/
|
|
900
|
+
export function flattenLeafColumns(columns) {
|
|
901
|
+
let result = [];
|
|
902
|
+
let loopDo = (cols) => {
|
|
903
|
+
(cols || []).forEach((item) => {
|
|
904
|
+
if (!item) {
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
if (item.children && item.children.length) {
|
|
908
|
+
loopDo(item.children);
|
|
909
|
+
} else {
|
|
910
|
+
result.push(item);
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
};
|
|
914
|
+
loopDo(columns);
|
|
915
|
+
return result;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/** 将列级 label / keyName / required 同步到列内 field widget(动态列 label 在列顶层) */
|
|
919
|
+
export function applyColumnMetaToFieldWidget(fieldWidget, row, isEdit = false) {
|
|
920
|
+
if (!fieldWidget || !row) {
|
|
921
|
+
return fieldWidget;
|
|
922
|
+
}
|
|
923
|
+
const widgetOptions = getColumnWidgetOptions(row, isEdit);
|
|
924
|
+
if (fieldWidget.options.hasOwnProperty("required")) {
|
|
925
|
+
fieldWidget.options.required = !!(row.required || widgetOptions?.required);
|
|
926
|
+
}
|
|
927
|
+
if (!fieldWidget.options.label && row.label) {
|
|
928
|
+
fieldWidget.options.label = row.label;
|
|
929
|
+
}
|
|
930
|
+
if (row.prop) {
|
|
931
|
+
if (fieldWidget.options.hasOwnProperty("keyName")) {
|
|
932
|
+
fieldWidget.options.keyName = row.prop;
|
|
933
|
+
fieldWidget.options.keyNameEnabled = true;
|
|
934
|
+
} else if (!fieldWidget.options.name) {
|
|
935
|
+
fieldWidget.options.name = row.prop;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
if (fieldWidget.type !== "button" && fieldWidget.type !== "a-link") {
|
|
939
|
+
fieldWidget.options.labelHidden = true;
|
|
940
|
+
}
|
|
941
|
+
return fieldWidget;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
/** 同步列 widget / editWidget 的列级元数据(含 labelHidden) */
|
|
945
|
+
export function applyColumnMetaToColumnRow(row) {
|
|
946
|
+
if (!row) {
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
if (row.widget) {
|
|
950
|
+
applyColumnMetaToFieldWidget(row.widget, row, false);
|
|
951
|
+
}
|
|
952
|
+
if (row.editWidget) {
|
|
953
|
+
applyColumnMetaToFieldWidget(row.editWidget, row, true);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
export function getFieldWidgetById(widgetList, fieldId, staticWidgetsIncluded) {
|
|
958
|
+
if (!widgetList) {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
let foundWidget = null;
|
|
963
|
+
let handlerFn = (widget) => {
|
|
964
|
+
if (widget.id === fieldId) {
|
|
965
|
+
foundWidget = widget;
|
|
966
|
+
} else if (widget.type === "data-table") {
|
|
967
|
+
for (let column of widget.options.tableColumns) {
|
|
968
|
+
if (column?.widget?.id + "" === fieldId) {
|
|
969
|
+
foundWidget = column.widget;
|
|
970
|
+
break;
|
|
971
|
+
} else if (column.widgetList) {
|
|
972
|
+
loopHandleWidget(column.widgetList, (item1) => {
|
|
973
|
+
if (item1.id === fieldId) {
|
|
974
|
+
foundWidget = item1;
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
|
|
982
|
+
traverseFieldWidgets(widgetList, handlerFn, null, staticWidgetsIncluded);
|
|
983
|
+
return foundWidget;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
export function getContainerWidgetByName(widgetList, containerName) {
|
|
987
|
+
if (!widgetList) {
|
|
988
|
+
return null;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
let foundContainer = null;
|
|
992
|
+
let handlerFn = (con) => {
|
|
993
|
+
if (con.options.name === containerName) {
|
|
994
|
+
foundContainer = con;
|
|
995
|
+
}
|
|
996
|
+
};
|
|
997
|
+
|
|
998
|
+
traverseContainerWidgets(widgetList, handlerFn);
|
|
999
|
+
return foundContainer;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
export function getContainerWidgetById(widgetList, containerId) {
|
|
1003
|
+
if (!widgetList) {
|
|
1004
|
+
return null;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
let foundContainer = null;
|
|
1008
|
+
let handlerFn = (con) => {
|
|
1009
|
+
if (con.id === containerId) {
|
|
1010
|
+
foundContainer = con;
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
|
|
1014
|
+
traverseContainerWidgets(widgetList, handlerFn);
|
|
1015
|
+
return foundContainer;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
export function copyToClipboard(
|
|
1019
|
+
content,
|
|
1020
|
+
clickEvent,
|
|
1021
|
+
$message,
|
|
1022
|
+
successMsg,
|
|
1023
|
+
errorMsg
|
|
1024
|
+
) {
|
|
1025
|
+
const clipboard = new Clipboard(clickEvent.target, {
|
|
1026
|
+
text: () => content,
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
clipboard.on("success", () => {
|
|
1030
|
+
$message.success(successMsg);
|
|
1031
|
+
clipboard.destroy();
|
|
1032
|
+
});
|
|
1033
|
+
|
|
1034
|
+
clipboard.on("error", () => {
|
|
1035
|
+
$message.error(errorMsg);
|
|
1036
|
+
clipboard.destroy();
|
|
1037
|
+
});
|
|
1038
|
+
|
|
1039
|
+
clipboard.onClick(clickEvent);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
export function getQueryParam(variable) {
|
|
1043
|
+
let query = window.location.search.substring(1);
|
|
1044
|
+
let vars = query.split("&");
|
|
1045
|
+
for (let i = 0; i < vars.length; i++) {
|
|
1046
|
+
let pair = vars[i].split("=");
|
|
1047
|
+
if (pair[0] === variable) {
|
|
1048
|
+
return pair[1];
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
return undefined;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
export function getDefaultFormConfig() {
|
|
1056
|
+
return {
|
|
1057
|
+
modelName: "formData",
|
|
1058
|
+
refName: "vForm",
|
|
1059
|
+
rulesName: "rules",
|
|
1060
|
+
labelWidth: 80,
|
|
1061
|
+
labelPosition: "left",
|
|
1062
|
+
size: "",
|
|
1063
|
+
labelAlign: "label-right-align",
|
|
1064
|
+
cssCode: "",
|
|
1065
|
+
customClass: "",
|
|
1066
|
+
functions: "",
|
|
1067
|
+
layoutType: "PC",
|
|
1068
|
+
dataSources: [],
|
|
1069
|
+
onBeforeCreated: "",
|
|
1070
|
+
onFormCreated: "",
|
|
1071
|
+
onFormBeforeMounted: "",
|
|
1072
|
+
onFormMounted: "",
|
|
1073
|
+
onFormDataChange: "",
|
|
1074
|
+
gridConfig: {
|
|
1075
|
+
accessReturnType: 1,
|
|
1076
|
+
isLoadDataByAccess: false,
|
|
1077
|
+
},
|
|
1078
|
+
getConfig: {
|
|
1079
|
+
accessType: "1",
|
|
1080
|
+
accessUrl: null,
|
|
1081
|
+
accessParam: null,
|
|
1082
|
+
accessCallback: null,
|
|
1083
|
+
scriptName: null,
|
|
1084
|
+
scriptCode: null,
|
|
1085
|
+
},
|
|
1086
|
+
saveConfig: {
|
|
1087
|
+
accessType: "1",
|
|
1088
|
+
accessUrl: null,
|
|
1089
|
+
accessParam: null,
|
|
1090
|
+
accessCallback: null,
|
|
1091
|
+
scriptName: null,
|
|
1092
|
+
scriptCode: null,
|
|
1093
|
+
},
|
|
1094
|
+
scriptList: [],
|
|
1095
|
+
formType: 0,
|
|
1096
|
+
entityTableCode: null,
|
|
1097
|
+
entityTableDesc: null,
|
|
1098
|
+
editFormCode: null,
|
|
1099
|
+
editFormName: null,
|
|
1100
|
+
searchDialogNameField: null,
|
|
1101
|
+
searchDialogUniqueField: null,
|
|
1102
|
+
entity: null,
|
|
1103
|
+
wfEnabled: false,
|
|
1104
|
+
isLoadEntity: false,
|
|
1105
|
+
formScriptCode: "getOne",
|
|
1106
|
+
formScriptParam: null,
|
|
1107
|
+
formScriptSuccess: null,
|
|
1108
|
+
saveScriptCode: "saveUpdate",
|
|
1109
|
+
wfConfig: null,
|
|
1110
|
+
wfStartBindSave: false,
|
|
1111
|
+
wfStartConfirmText: null,
|
|
1112
|
+
// 「保存并提交流程」内建按钮:由 detail-item 渲染,只在新增页(dataId 为空)显示。
|
|
1113
|
+
// 按钮名不在此处配,统一由后台 wf_diy_attribute(param18) 下发,见 components/wf/wfButtonName.js
|
|
1114
|
+
saveSubmitEnabled: false,
|
|
1115
|
+
// 「提交流程」「保存并提交流程」共用的提交前置处理脚本:校验通过后、确认框之前执行
|
|
1116
|
+
onBeforeSubmitWf: null,
|
|
1117
|
+
// 「提交流程」按钮显隐脚本:return false 隐藏,不配则显示
|
|
1118
|
+
wfStartBtnShow: null,
|
|
1119
|
+
wfAgreenBindSave: false,
|
|
1120
|
+
wfAgreeConfigData: [],
|
|
1121
|
+
wfConfigDataEnabled: false,
|
|
1122
|
+
wfConfigData: [],
|
|
1123
|
+
multiTabEnabled: false,
|
|
1124
|
+
multiTabLabelField: null,
|
|
1125
|
+
addTabEnabled: false, // 新增打开独立页签(不走「常规」页签)
|
|
1126
|
+
submitBehavior: "refreshCurrent", // 提交后行为: refreshCurrent(默认,留在详情页) | closeToList
|
|
1127
|
+
billNavEnabled: false, // 详情页签显示「上一单/下一单」翻单按钮
|
|
1128
|
+
addFormCode: null,
|
|
1129
|
+
addFormName: null,
|
|
1130
|
+
wfTheme: null,
|
|
1131
|
+
otherTabEnabled: false,
|
|
1132
|
+
otherTabList: [],
|
|
1133
|
+
hideNormalTab: false,
|
|
1134
|
+
customListTabLabel: null,
|
|
1135
|
+
globalConfig: null,
|
|
1136
|
+
// 表单级动态字段规则:按本地规则/后台脚本动态控制整个表单内任意字段/容器的显隐/必填/只读/禁用/取值
|
|
1137
|
+
dynamicFieldEnabled: false,
|
|
1138
|
+
dynamicFieldRunMode: "auto",
|
|
1139
|
+
dynamicFieldAllowValue: false,
|
|
1140
|
+
dynamicFieldSourceType: "local",
|
|
1141
|
+
dynamicFieldRules: [],
|
|
1142
|
+
dynamicFieldScriptCode: null,
|
|
1143
|
+
dynamicFieldScriptParam: null,
|
|
1144
|
+
dynamicFieldTriggerFields: [],
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
export function buildDefaultFormJson() {
|
|
1149
|
+
return {
|
|
1150
|
+
widgetList: [],
|
|
1151
|
+
formConfig: deepClone(getDefaultFormConfig()),
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
export function cloneFormConfigWithoutEventHandler(e) {
|
|
1156
|
+
var t = deepClone(e);
|
|
1157
|
+
return (
|
|
1158
|
+
(t.onFormCreated = ""),
|
|
1159
|
+
(t.onFormBeforeMounted = ""),
|
|
1160
|
+
(t.onFormMounted = ""),
|
|
1161
|
+
(t.onFormDataChange = ""),
|
|
1162
|
+
t
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
export function translateOptionItems(rawData, widgetType, labelKey, valueKey) {
|
|
1167
|
+
if (widgetType === "cascader") {
|
|
1168
|
+
// 级联选择不转译
|
|
1169
|
+
return deepClone(rawData);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
let result = [];
|
|
1173
|
+
if (!!rawData && rawData.length > 0) {
|
|
1174
|
+
result = deepClone(rawData);
|
|
1175
|
+
result.forEach((ri) => {
|
|
1176
|
+
ri[labelKey] = ri[labelKey] ?? null;
|
|
1177
|
+
ri[valueKey] = ri[valueKey] ?? null;
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
return result;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
export function assembleAxiosConfig(arrayObj, DSV, VFR) {
|
|
1185
|
+
var result = {};
|
|
1186
|
+
if (arrayObj && arrayObj.length) {
|
|
1187
|
+
arrayObj.map(function (ai) {
|
|
1188
|
+
if ("String" === ai.type) {
|
|
1189
|
+
result[ai.name] = String(ai.value);
|
|
1190
|
+
} else if ("Number" === ai.type) {
|
|
1191
|
+
result[ai.name] = Number(ai.value);
|
|
1192
|
+
} else if ("Boolean" === ai.type) {
|
|
1193
|
+
"false" === ai.value.toLowerCase() || "0" === ai.value
|
|
1194
|
+
? (result[ai.name] = !1)
|
|
1195
|
+
: "true" === ai.value.toLowerCase() || "1" === ai.value
|
|
1196
|
+
? (result[ai.name] = !0)
|
|
1197
|
+
: (result[ai.name] = null);
|
|
1198
|
+
} else if ("Variable" === ai.type) {
|
|
1199
|
+
result[ai.name] = eval(ai.value);
|
|
1200
|
+
} else if ("FormData" === ai.type) {
|
|
1201
|
+
if (VFR.formDataModel.hasOwnProperty(ai.value)) {
|
|
1202
|
+
result[ai.name] = VFR.formDataModel[ai.value];
|
|
1203
|
+
} else {
|
|
1204
|
+
let parentForm = VFR.parentForm;
|
|
1205
|
+
if (parentForm && parentForm.formDataModel.hasOwnProperty(ai.value)) {
|
|
1206
|
+
result[ai.name] = parentForm.formDataModel[ai.value];
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
return result;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
export function buildRequestConfig(dataSource, DSV, VFR, isSandbox) {
|
|
1216
|
+
var config = {};
|
|
1217
|
+
/* "String" === dataSource.requestaccessType ? config.url = dataSource.requestURL : config.url = eval(dataSource
|
|
1218
|
+
.requestURL), */
|
|
1219
|
+
let requestAccess = DSV.requestAccess;
|
|
1220
|
+
// config.url = dataSource.requestURL;
|
|
1221
|
+
config.url = getAccessUrl();
|
|
1222
|
+
(config.method = dataSource.requestMethod || "post"),
|
|
1223
|
+
(config.headers = assembleAxiosConfig(dataSource.headers, DSV, VFR)),
|
|
1224
|
+
(config.params = assembleAxiosConfig(dataSource.params, DSV, VFR));
|
|
1225
|
+
// config.data = assembleAxiosConfig(dataSource.data, DSV, VFR);
|
|
1226
|
+
let data = {};
|
|
1227
|
+
let conditions = assembleAxiosConfig(dataSource.data, DSV, VFR);
|
|
1228
|
+
|
|
1229
|
+
let globalReqData = getReportGlobalMap(); //全局请求参数
|
|
1230
|
+
Object.assign(conditions, globalReqData);
|
|
1231
|
+
|
|
1232
|
+
let doms = VFR.getWidgetRef(DSV.widgetName);
|
|
1233
|
+
let extraAccessData = doms.extraAccessData || {};
|
|
1234
|
+
|
|
1235
|
+
data.accessCode = requestAccess.accessCode;
|
|
1236
|
+
data.conditions = conditions;
|
|
1237
|
+
Object.assign(data.conditions, extraAccessData);
|
|
1238
|
+
|
|
1239
|
+
config.data = data;
|
|
1240
|
+
var chFn = new Function(
|
|
1241
|
+
"config",
|
|
1242
|
+
"isSandbox",
|
|
1243
|
+
"DSV",
|
|
1244
|
+
"VFR",
|
|
1245
|
+
dataSource.configHandlerCode
|
|
1246
|
+
);
|
|
1247
|
+
return chFn.call(null, config, isSandbox, DSV, VFR);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
export function runDataSourceRequest(e, t, i, n, o) {
|
|
1251
|
+
return _runDataSourceRequest.apply(this, arguments);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
export function _runDataSourceRequest() {
|
|
1255
|
+
let _runDataSourceRequestN = function (t, i, n, o, a) {
|
|
1256
|
+
var l, s, r, d;
|
|
1257
|
+
(l = buildRequestConfig(t, i, n, o)),
|
|
1258
|
+
(r = new Function(
|
|
1259
|
+
"result",
|
|
1260
|
+
"isSandbox",
|
|
1261
|
+
"DSV",
|
|
1262
|
+
"VFR",
|
|
1263
|
+
t.dataHandlerCode
|
|
1264
|
+
)),
|
|
1265
|
+
(d = new Function(
|
|
1266
|
+
"error",
|
|
1267
|
+
"isSandbox",
|
|
1268
|
+
"DSV",
|
|
1269
|
+
"$message",
|
|
1270
|
+
"VFR",
|
|
1271
|
+
t.errorHandlerCode
|
|
1272
|
+
));
|
|
1273
|
+
|
|
1274
|
+
return new Promise((resolve, reject) => {
|
|
1275
|
+
request({
|
|
1276
|
+
...l,
|
|
1277
|
+
callback: (res) => {
|
|
1278
|
+
resolve(r.call(null, res, o, i, n));
|
|
1279
|
+
},
|
|
1280
|
+
error: (error) => {
|
|
1281
|
+
d.call(null, error, o, i, a, n);
|
|
1282
|
+
reject(error);
|
|
1283
|
+
},
|
|
1284
|
+
});
|
|
1285
|
+
});
|
|
1286
|
+
};
|
|
1287
|
+
return _runDataSourceRequestN.apply(this, arguments);
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
export function getDSByName(e, t) {
|
|
1291
|
+
var i = null;
|
|
1292
|
+
return (
|
|
1293
|
+
t &&
|
|
1294
|
+
e.dataSources &&
|
|
1295
|
+
e.dataSources.forEach(function (e) {
|
|
1296
|
+
e.uniqueName === t && (i = e);
|
|
1297
|
+
}),
|
|
1298
|
+
i
|
|
1299
|
+
);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
export function setReportGlobalParam(value) {
|
|
1303
|
+
sessionStorage.setItem("reportGlobalParam", value);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
export function getReportGlobalMap() {
|
|
1307
|
+
let param = sessionStorage.getItem("reportGlobalParam");
|
|
1308
|
+
if (param) {
|
|
1309
|
+
let globalReqData = JSON.parse(decode(param));
|
|
1310
|
+
return globalReqData;
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
export function getSubFormNameByFieldId(o, e) {
|
|
1315
|
+
let n = null;
|
|
1316
|
+
return (
|
|
1317
|
+
getAllContainerWidgets(o).forEach((s) => {
|
|
1318
|
+
const c = (u) => {
|
|
1319
|
+
u.id === e && (n = s.name);
|
|
1320
|
+
};
|
|
1321
|
+
(s.type === "sub-form" || s.type === "grid-sub-form") &&
|
|
1322
|
+
traverseFieldWidgetsOfContainer(s.container, c);
|
|
1323
|
+
}),
|
|
1324
|
+
n
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
export const FORMULA_REG_EXP = /\{\{(\w+\.[^.]+\.\w+)}}/g;
|
|
1329
|
+
|
|
1330
|
+
export function fieldIsUsedInFormula(o, e, n) {
|
|
1331
|
+
const l = e.match(FORMULA_REG_EXP);
|
|
1332
|
+
if (!l) return !1;
|
|
1333
|
+
let s = !1;
|
|
1334
|
+
return (
|
|
1335
|
+
l.forEach((c) => {
|
|
1336
|
+
const u = c.split(".")[2];
|
|
1337
|
+
if (u.substring(0, u.length - 2) === "func") return;
|
|
1338
|
+
const g = c.split(".")[0],
|
|
1339
|
+
y = g.substring(2, g.length);
|
|
1340
|
+
getFieldWidgetById(n.formJsonObj.widgetList, y, !1).options.name === o &&
|
|
1341
|
+
(s = !0);
|
|
1342
|
+
}),
|
|
1343
|
+
s
|
|
1344
|
+
);
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
export function calculateFormula(o, e, n, l, s) {
|
|
1348
|
+
if (
|
|
1349
|
+
!!l.subFormItemFlag &&
|
|
1350
|
+
!!s.subFormItemFlag &&
|
|
1351
|
+
s.subFormRowId !== l.subFormRowId
|
|
1352
|
+
)
|
|
1353
|
+
return;
|
|
1354
|
+
let c = l.field.options.formula;
|
|
1355
|
+
c = replaceFieldsAndFunctionsOfFormula(o, l);
|
|
1356
|
+
const u = c.match(/[A-Za-z]*/g);
|
|
1357
|
+
u &&
|
|
1358
|
+
u.forEach((g) => {
|
|
1359
|
+
if (!!g && findCalFunStartIndex(g) !== -1) {
|
|
1360
|
+
const y = g.toUpperCase();
|
|
1361
|
+
c = c.replace(g, "formulaJs." + y);
|
|
1362
|
+
}
|
|
1363
|
+
}),
|
|
1364
|
+
console.log("formula: ", c),
|
|
1365
|
+
console.log("formulaFieldRef: ", l);
|
|
1366
|
+
const $ = evalFn(c, e, o, n);
|
|
1367
|
+
l.setValue($);
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
export function replaceFieldsAndFunctionsOfFormula(o, e) {
|
|
1371
|
+
let n = e.field.options.formula;
|
|
1372
|
+
const l = n.match(FORMULA_REG_EXP);
|
|
1373
|
+
if (!l) return n;
|
|
1374
|
+
let s = n;
|
|
1375
|
+
return (
|
|
1376
|
+
l.forEach((c) => {
|
|
1377
|
+
const u = c.split(".")[2];
|
|
1378
|
+
if (u.substring(0, u.length - 2) === "func") {
|
|
1379
|
+
const v = c.split(".")[1];
|
|
1380
|
+
s = s.replace(c, v);
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1383
|
+
const g = c.split(".")[0],
|
|
1384
|
+
y = g.substring(2, g.length),
|
|
1385
|
+
f = getFieldWidgetById(o.formJsonObj.widgetList, y, !1);
|
|
1386
|
+
if (f) {
|
|
1387
|
+
let v = o.getWidgetRef(f.options.name);
|
|
1388
|
+
if (v) s = s.replace(c, v.getValue());
|
|
1389
|
+
else {
|
|
1390
|
+
const w = o.getSubFormNameOfWidget(f.options.name);
|
|
1391
|
+
if (e.subFormItemFlag)
|
|
1392
|
+
w === e.subFormName
|
|
1393
|
+
? ((v = o.getWidgetRef(f.options.name + "@row" + e.subFormRowId)),
|
|
1394
|
+
v && (s = s.replaceAll(c, v.getValue())))
|
|
1395
|
+
: console.error("Invalid formula!");
|
|
1396
|
+
else {
|
|
1397
|
+
const _ = o.formDataModel[w];
|
|
1398
|
+
let O = "";
|
|
1399
|
+
const S = f.options.name;
|
|
1400
|
+
_.forEach((x, E) => {
|
|
1401
|
+
O = E === 0 ? x[S] : O + ", " + x[S];
|
|
1402
|
+
}),
|
|
1403
|
+
(s = s.replaceAll(c, O));
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
}),
|
|
1408
|
+
s
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
export function findCalFunStartIndex(o) {
|
|
1413
|
+
let e = -1;
|
|
1414
|
+
for (let n = 0; n < FORMULA_JS_FUNCTIONS.length; n++) {
|
|
1415
|
+
let l = o.indexOf(FORMULA_JS_FUNCTIONS[n]);
|
|
1416
|
+
if (l !== -1) return l;
|
|
1417
|
+
}
|
|
1418
|
+
return e;
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
export const FORMULA_JS_FUNCTIONS = [
|
|
1422
|
+
"INT",
|
|
1423
|
+
"SUM",
|
|
1424
|
+
"AVERAGE",
|
|
1425
|
+
"MAX",
|
|
1426
|
+
"MIN",
|
|
1427
|
+
"ABS",
|
|
1428
|
+
"ROUND",
|
|
1429
|
+
"CEILING",
|
|
1430
|
+
"LOG",
|
|
1431
|
+
"MOD",
|
|
1432
|
+
"POWER",
|
|
1433
|
+
"AND",
|
|
1434
|
+
"IF",
|
|
1435
|
+
"IFS",
|
|
1436
|
+
"IFERROR",
|
|
1437
|
+
"IFNA",
|
|
1438
|
+
"NOT",
|
|
1439
|
+
"OR",
|
|
1440
|
+
"SWITCH",
|
|
1441
|
+
"XOR",
|
|
1442
|
+
"YEAR",
|
|
1443
|
+
"MONTH",
|
|
1444
|
+
"DAY",
|
|
1445
|
+
"TODAY",
|
|
1446
|
+
"NOW",
|
|
1447
|
+
"EMONTH",
|
|
1448
|
+
"EDAY",
|
|
1449
|
+
"FIND",
|
|
1450
|
+
"LEFT",
|
|
1451
|
+
"RIGHT",
|
|
1452
|
+
"LEN",
|
|
1453
|
+
"LOWER",
|
|
1454
|
+
"UPPER",
|
|
1455
|
+
"MID",
|
|
1456
|
+
"TRIM",
|
|
1457
|
+
],
|
|
1458
|
+
formulas = [
|
|
1459
|
+
{
|
|
1460
|
+
fClass: "designer.hint.formulaFunctionMaths",
|
|
1461
|
+
flist: [
|
|
1462
|
+
{
|
|
1463
|
+
fName: "INT",
|
|
1464
|
+
fType: "designer.hint.formulaNumber",
|
|
1465
|
+
fIntro: "designer.hint.formulaINT",
|
|
1466
|
+
},
|
|
1467
|
+
{
|
|
1468
|
+
fName: "SUM",
|
|
1469
|
+
fType: "designer.hint.formulaNumber",
|
|
1470
|
+
fIntro: "designer.hint.formulaSUM",
|
|
1471
|
+
},
|
|
1472
|
+
{
|
|
1473
|
+
fName: "AVERAGE",
|
|
1474
|
+
fType: "designer.hint.formulaNumber",
|
|
1475
|
+
fIntro: "designer.hint.formulaAVERAGE",
|
|
1476
|
+
},
|
|
1477
|
+
{
|
|
1478
|
+
fName: "MAX",
|
|
1479
|
+
fType: "designer.hint.formulaNumber",
|
|
1480
|
+
fIntro: "designer.hint.formulaMAX",
|
|
1481
|
+
},
|
|
1482
|
+
{
|
|
1483
|
+
fName: "MIN",
|
|
1484
|
+
fType: "designer.hint.formulaNumber",
|
|
1485
|
+
fIntro: "designer.hint.formulaMIN",
|
|
1486
|
+
},
|
|
1487
|
+
{
|
|
1488
|
+
fName: "ABS",
|
|
1489
|
+
fType: "designer.hint.formulaNumber",
|
|
1490
|
+
fIntro: "designer.hint.formulaABS",
|
|
1491
|
+
},
|
|
1492
|
+
{
|
|
1493
|
+
fName: "ROUND",
|
|
1494
|
+
fType: "designer.hint.formulaNumber",
|
|
1495
|
+
fIntro: "designer.hint.formulaROUND",
|
|
1496
|
+
},
|
|
1497
|
+
{
|
|
1498
|
+
fName: "CEILING",
|
|
1499
|
+
fType: "designer.hint.formulaNumber",
|
|
1500
|
+
fIntro: "designer.hint.formulaCEILING",
|
|
1501
|
+
},
|
|
1502
|
+
{
|
|
1503
|
+
fName: "LOG",
|
|
1504
|
+
fType: "designer.hint.formulaNumber",
|
|
1505
|
+
fIntro: "designer.hint.formulaLOG",
|
|
1506
|
+
},
|
|
1507
|
+
{
|
|
1508
|
+
fName: "MOD",
|
|
1509
|
+
fType: "designer.hint.formulaNumber",
|
|
1510
|
+
fIntro: "designer.hint.formulaMOD",
|
|
1511
|
+
},
|
|
1512
|
+
{
|
|
1513
|
+
fName: "POWER",
|
|
1514
|
+
fType: "designer.hint.formulaNumber",
|
|
1515
|
+
fIntro: "designer.hint.formulaPOWER",
|
|
1516
|
+
},
|
|
1517
|
+
],
|
|
1518
|
+
},
|
|
1519
|
+
];
|
|
1520
|
+
|
|
1521
|
+
export function evalFn(o, e = null, n = null, l = null) {
|
|
1522
|
+
return new Function("DSV", "VFR", "LS", "formulaJs", "return " + o)(
|
|
1523
|
+
e,
|
|
1524
|
+
n,
|
|
1525
|
+
localStorage,
|
|
1526
|
+
l
|
|
1527
|
+
);
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
export function trimEx(o, e, n) {
|
|
1531
|
+
return e
|
|
1532
|
+
? n === "left"
|
|
1533
|
+
? o.replace(new RegExp("^%%" + e + "+", "g"), "")
|
|
1534
|
+
: n === "right"
|
|
1535
|
+
? o.replace(new RegExp("%%" + e + "+$", "g"), "")
|
|
1536
|
+
: o.replace(new RegExp("^%%" + e + "+|%%" + e + "+$", "g"), "")
|
|
1537
|
+
: o.replace(/^%s+|%s+$/g, "");
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
export function hasPropertyOfObject(o, e) {
|
|
1541
|
+
const n = e.split(".");
|
|
1542
|
+
let l = o,
|
|
1543
|
+
s = !0;
|
|
1544
|
+
for (const c of n)
|
|
1545
|
+
if (l.hasOwnProperty(c)) l = l[c];
|
|
1546
|
+
else {
|
|
1547
|
+
s = !1;
|
|
1548
|
+
break;
|
|
1549
|
+
}
|
|
1550
|
+
return s;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
export function objectKeysToArray(o) {
|
|
1554
|
+
if (!o) return [];
|
|
1555
|
+
const e = [];
|
|
1556
|
+
return (
|
|
1557
|
+
Object.keys(o).forEach((n) => {
|
|
1558
|
+
e.push(n);
|
|
1559
|
+
}),
|
|
1560
|
+
e
|
|
1561
|
+
);
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
//begin
|
|
1565
|
+
export function loopHandleWidget(widgetList, callback) {
|
|
1566
|
+
widgetList &&
|
|
1567
|
+
widgetList.length > 0 &&
|
|
1568
|
+
widgetList.forEach(function (e) {
|
|
1569
|
+
loopHandleWidgetItem(e, null, callback);
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
/* 子节点挂在 panes 上的容器(detail-h5 另有 widgetList 承载底部动作栏按钮) */
|
|
1574
|
+
const PANES_CONTAINER_TYPES = [
|
|
1575
|
+
"detail",
|
|
1576
|
+
"detail-plain",
|
|
1577
|
+
"detail-h5",
|
|
1578
|
+
"h5-card",
|
|
1579
|
+
];
|
|
1580
|
+
/* 内容在 widgetList、按钮在 buttonWidgetList 的分组容器 */
|
|
1581
|
+
const PANE_CONTAINER_TYPES = ["detail-pane", "h5-card-pane"];
|
|
1582
|
+
|
|
1583
|
+
function loopHandleWidgetItem(e, p, callback) {
|
|
1584
|
+
if ("container" === e.category) {
|
|
1585
|
+
callback(e, p);
|
|
1586
|
+
if ("vf-dialog" === e.type || "vf-drawer" === e.type);
|
|
1587
|
+
else if ("data-table" === e.type) {
|
|
1588
|
+
if (!!e.widgetList) {
|
|
1589
|
+
e.widgetList.forEach((childItem) => {
|
|
1590
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1593
|
+
if (!!e.buttons) {
|
|
1594
|
+
e.buttons.forEach((childItem) => {
|
|
1595
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
} else if ("list-h5" === e.type) {
|
|
1599
|
+
if (!!e.widgetList && e.widgetList.length > 0) {
|
|
1600
|
+
e.widgetList.forEach((childItem) => {
|
|
1601
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
/* 行按钮与顶部查询按钮,与 data-table 的 buttons 同一性质,
|
|
1605
|
+
不遍历的话它们的 wf 联动与显隐规则同样不生效 */
|
|
1606
|
+
if (!!e.lineButtons && e.lineButtons.length > 0) {
|
|
1607
|
+
e.lineButtons.forEach((childItem) => {
|
|
1608
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1609
|
+
});
|
|
1610
|
+
}
|
|
1611
|
+
if (!!e.buttons && e.buttons.length > 0) {
|
|
1612
|
+
e.buttons.forEach((childItem) => {
|
|
1613
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1614
|
+
});
|
|
1615
|
+
}
|
|
1616
|
+
} else if ("grid" === e.type) {
|
|
1617
|
+
e.cols &&
|
|
1618
|
+
e.cols.length > 0 &&
|
|
1619
|
+
e.cols.forEach(function (childItem) {
|
|
1620
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1621
|
+
});
|
|
1622
|
+
} else if ("table" === e.type) {
|
|
1623
|
+
e.rows &&
|
|
1624
|
+
e.rows.length > 0 &&
|
|
1625
|
+
e.rows.forEach(function (rowItem) {
|
|
1626
|
+
rowItem.cols &&
|
|
1627
|
+
rowItem.cols.length > 0 &&
|
|
1628
|
+
rowItem.cols.forEach(function (childItem) {
|
|
1629
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1630
|
+
});
|
|
1631
|
+
});
|
|
1632
|
+
} else if ("h5-table" === e.type) {
|
|
1633
|
+
e.rows &&
|
|
1634
|
+
e.rows.length > 0 &&
|
|
1635
|
+
e.rows.forEach(function (rowItem) {
|
|
1636
|
+
rowItem.cols &&
|
|
1637
|
+
rowItem.cols.length > 0 &&
|
|
1638
|
+
rowItem.cols.forEach(function (childItem) {
|
|
1639
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1640
|
+
});
|
|
1641
|
+
});
|
|
1642
|
+
} else if ("tab" === e.type) {
|
|
1643
|
+
e.tabs &&
|
|
1644
|
+
e.tabs.length > 0 &&
|
|
1645
|
+
e.tabs.forEach(function (tabItem) {
|
|
1646
|
+
tabItem.widgetList &&
|
|
1647
|
+
tabItem.widgetList.length > 0 &&
|
|
1648
|
+
tabItem.widgetList.forEach(function (childItem) {
|
|
1649
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1650
|
+
});
|
|
1651
|
+
});
|
|
1652
|
+
/* 子节点放在 panes 里的容器。detail-h5 / h5-card 是 H5 版式的两个,
|
|
1653
|
+
此前它们没有分支、落到最后的兜底 else,而兜底只遍历 widgetList ——
|
|
1654
|
+
等于 H5 表单的字段和按钮一个都进不了 traverseAllWidgets* 的回调,
|
|
1655
|
+
wf 联动(hiddenByWf/enabledByWf/wfEdit)、组件显隐规则等全部失效。
|
|
1656
|
+
设计器侧的 designer.js 早有正确映射("detail-h5"/"h5-card" → panes),
|
|
1657
|
+
这里是运行时遍历器没跟上。
|
|
1658
|
+
(detail-h5 的 widgetList 是底部动作栏按钮,也要一起遍历) */
|
|
1659
|
+
} else if (PANES_CONTAINER_TYPES.indexOf(e.type) > -1) {
|
|
1660
|
+
if (e.panes) {
|
|
1661
|
+
e.panes.forEach(function (childItem) {
|
|
1662
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
if (e.widgetList) {
|
|
1666
|
+
e.widgetList.forEach(function (childItem) {
|
|
1667
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
/* h5-card-pane 与 detail-pane 同构:内容在 widgetList、分组按钮在 buttonWidgetList。
|
|
1671
|
+
兜底 else 只认 widgetList,会漏掉分组按钮(如自动骨架里的「新增」)。 */
|
|
1672
|
+
} else if (PANE_CONTAINER_TYPES.indexOf(e.type) > -1) {
|
|
1673
|
+
if (e.widgetList) {
|
|
1674
|
+
e.widgetList.forEach(function (childItem) {
|
|
1675
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
if (e.buttonWidgetList) {
|
|
1679
|
+
e.buttonWidgetList.forEach(function (childItem) {
|
|
1680
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
} else {
|
|
1684
|
+
"grid-col" === e.type || e.type,
|
|
1685
|
+
e.widgetList &&
|
|
1686
|
+
e.widgetList.length > 0 &&
|
|
1687
|
+
e.widgetList.forEach(function (childItem) {
|
|
1688
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1689
|
+
});
|
|
1690
|
+
}
|
|
1691
|
+
} else {
|
|
1692
|
+
callback && callback(e);
|
|
1693
|
+
if (e.widgetList) {
|
|
1694
|
+
e.widgetList.forEach(function (childItem) {
|
|
1695
|
+
loopHandleWidgetItem(childItem, e, callback);
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
//end
|
|
1702
|
+
|
|
1703
|
+
export function trim(value) {
|
|
1704
|
+
if (isNull(value)) return value;
|
|
1705
|
+
if (value.trim) {
|
|
1706
|
+
return value.trim();
|
|
1707
|
+
} else {
|
|
1708
|
+
return value;
|
|
1709
|
+
}
|
|
1710
|
+
}
|