cloud-web-corejs 1.0.54-dev.688 → 1.0.54-dev.689
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/fileLibrary/index.vue +113 -33
- package/src/components/xform/docs//345/220/216/345/217/260/345/255/227/346/256/265/357/274/210/345/212/250/346/200/201/347/224/237/346/210/220/357/274/211JSON /350/257/264/346/230/216.md" +210 -305
- package/src/components/xform/docs//346/225/260/346/215/256/350/241/250/346/240/274/345/212/250/346/200/201/345/210/227 JSON /350/257/264/346/230/216.md" +657 -0
- package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +80 -14
- package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +18 -13
- package/src/components/xform/form-designer/form-widget/field-widget/number-widget.vue +11 -8
- package/src/components/xform/form-designer/form-widget/field-widget/script-input-widget.vue +143 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +87 -25
- package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +5 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +80 -34
- package/src/components/xform/form-designer/setting-panel/property-editor/field-script-input/script-input-editor.vue +54 -0
- package/src/components/xform/form-designer/setting-panel/propertyRegister.js +1 -0
- package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +56 -1
- package/src/components/xform/form-render/container-item/data-table-mixin.js +296 -118
- package/src/components/xform/form-render/container-item/dynamicFieldMixin.js +25 -37
- package/src/components/xform/form-render/container-item/list-h5-item.vue +5 -1
- package/src/components/xform/form-render/indexMixin.js +175 -6
- package/src/components/xform/lang/en-US.js +1 -0
- package/src/components/xform/lang/zh-CN.js +1 -0
- package/src/components/xform/utils/dynamicSchemaUtil.js +312 -0
- package/src/components/xform/utils/tableCellValidateUtil.js +148 -0
- package/src/components/xform/utils/tableColumnHelper.js +21 -1
- package/src/components/xform/utils/util.js +126 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 后台动态定义(表头后台字段 / 数据表格动态列)共用协议。
|
|
3
|
+
*
|
|
4
|
+
* 单条定义顶层字段:
|
|
5
|
+
* - 通用:keyName、type、label、optionItems、required 等字段级属性、options
|
|
6
|
+
* - 表头:colspan
|
|
7
|
+
* - 数据表格:width、formatS(展示列)、children(多级表头)、dropdownItems(dropdown 操作列)
|
|
8
|
+
*
|
|
9
|
+
* 请求体:{ formData, ...extra }
|
|
10
|
+
* 响应体:objx 数组,或 { fields: [] } / { columns: [] }
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** 顶层字段白名单 */
|
|
14
|
+
export const DYNAMIC_SCHEMA_CORE_KEYS = [
|
|
15
|
+
"keyName",
|
|
16
|
+
"type",
|
|
17
|
+
"label",
|
|
18
|
+
"optionItems",
|
|
19
|
+
"options",
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
/** 字段级属性:写顶层,不写 options(与表头 dynamicFieldMixin 一致) */
|
|
23
|
+
export const DYNAMIC_SCHEMA_WIDGET_FLAG_KEYS = [
|
|
24
|
+
"required",
|
|
25
|
+
"readonly",
|
|
26
|
+
"disabled",
|
|
27
|
+
"hidden",
|
|
28
|
+
"defaultValue",
|
|
29
|
+
"placeholder",
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
export const DYNAMIC_SCHEMA_TABLE_HEADER_KEYS = ["colspan"];
|
|
33
|
+
|
|
34
|
+
export const DYNAMIC_SCHEMA_COLUMN_EXTRA_KEYS = [
|
|
35
|
+
"width",
|
|
36
|
+
"align",
|
|
37
|
+
"sortable",
|
|
38
|
+
"filterable",
|
|
39
|
+
"show",
|
|
40
|
+
"fixed",
|
|
41
|
+
"formatS",
|
|
42
|
+
"render",
|
|
43
|
+
"utcTransformEnabled",
|
|
44
|
+
"children",
|
|
45
|
+
"dropdownItems",
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
export const DYNAMIC_SCHEMA_OPTION_KEYS = {
|
|
49
|
+
scriptCode: ["dynamicSchemaScriptCode", "dynamicColumnScriptCode"],
|
|
50
|
+
scriptParam: ["dynamicSchemaScriptParam", "dynamicColumnScriptParam"],
|
|
51
|
+
convert: ["dynamicSchemaConvert"],
|
|
52
|
+
mode: ["dynamicSchemaMode", "dynamicColumnMode"],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const widgetTypeToEditFormatMap = {
|
|
56
|
+
input: "editInput",
|
|
57
|
+
number: "editNumber",
|
|
58
|
+
date: "editDate",
|
|
59
|
+
select: "editSelect",
|
|
60
|
+
vabsearch: "editSearch",
|
|
61
|
+
baseAttachment: "editAttachment",
|
|
62
|
+
status: "editStatus",
|
|
63
|
+
text: "text",
|
|
64
|
+
checkbox: "checkbox",
|
|
65
|
+
radio: "radio",
|
|
66
|
+
textarea: "textarea",
|
|
67
|
+
"script-input": "editScriptInput",
|
|
68
|
+
"a-text": "aText",
|
|
69
|
+
"a-link": "aLink",
|
|
70
|
+
button: "button",
|
|
71
|
+
dropdown: "dropdown",
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const ACTION_COLUMN_FORMATS = new Set(["aLink", "button", "dropdown"]);
|
|
75
|
+
|
|
76
|
+
export function buildDropdownWidgetFromDef(def, index = 0) {
|
|
77
|
+
const options = def?.options;
|
|
78
|
+
const dropdownItems = def?.dropdownItems;
|
|
79
|
+
if (!Array.isArray(dropdownItems) || !dropdownItems.length) return null;
|
|
80
|
+
|
|
81
|
+
const ts = `${Date.now()}_${index}`;
|
|
82
|
+
const widgetList = dropdownItems.map((entry, i) => ({
|
|
83
|
+
type: "dropdown-item",
|
|
84
|
+
id: `dropdownitem_${ts}_${i}`,
|
|
85
|
+
options: {
|
|
86
|
+
label: entry.label || "",
|
|
87
|
+
onClick: entry.onClick || "",
|
|
88
|
+
disabled: !!entry.disabled,
|
|
89
|
+
hidden: !!entry.hidden,
|
|
90
|
+
},
|
|
91
|
+
}));
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
type: "dropdown",
|
|
95
|
+
id: `dropdown_${ts}`,
|
|
96
|
+
options: {
|
|
97
|
+
label: def.label || "操作",
|
|
98
|
+
dropdownType: options?.dropdownType || "link",
|
|
99
|
+
dropdownTrigger: options?.dropdownTrigger || "hover",
|
|
100
|
+
dropdownFlag: 1,
|
|
101
|
+
},
|
|
102
|
+
widgetList,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function isActionColumn(item, formatS) {
|
|
107
|
+
return isActionColumnFormat(formatS, item?.type);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function isActionColumnFormat(formatS, type) {
|
|
111
|
+
if (ACTION_COLUMN_FORMATS.has(formatS)) return true;
|
|
112
|
+
return ["a-link", "button", "dropdown"].includes(type);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function isActionOrGroupColumn(item, formatS) {
|
|
116
|
+
if (Array.isArray(item.children) && item.children.length) return true;
|
|
117
|
+
return isActionColumn(item, formatS);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function buildWidgetOptions(item, formatS, label) {
|
|
121
|
+
let widgetOptions =
|
|
122
|
+
item.options && typeof item.options === "object"
|
|
123
|
+
? { ...item.options }
|
|
124
|
+
: null;
|
|
125
|
+
|
|
126
|
+
if (widgetOptions) {
|
|
127
|
+
delete widgetOptions.dropdownItems;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
DYNAMIC_SCHEMA_WIDGET_FLAG_KEYS.forEach((key) => {
|
|
131
|
+
if (item[key] !== undefined) {
|
|
132
|
+
widgetOptions = widgetOptions || {};
|
|
133
|
+
widgetOptions[key] = item[key];
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
if (label) {
|
|
138
|
+
widgetOptions = widgetOptions || {};
|
|
139
|
+
if (!widgetOptions.label) {
|
|
140
|
+
widgetOptions.label = label;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (!isActionColumn(item, formatS)) {
|
|
145
|
+
widgetOptions = widgetOptions || {};
|
|
146
|
+
widgetOptions.labelHidden = true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return widgetOptions;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function getDynamicSchemaOption(options, key) {
|
|
153
|
+
if (!options) return null;
|
|
154
|
+
const keys = DYNAMIC_SCHEMA_OPTION_KEYS[key] || [];
|
|
155
|
+
for (let i = 0; i < keys.length; i++) {
|
|
156
|
+
const val = options[keys[i]];
|
|
157
|
+
if (val !== undefined && val !== null && val !== "") {
|
|
158
|
+
return val;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function resolveDynamicSchemaExtra(paramScript, handleCustomEvent) {
|
|
165
|
+
if (!paramScript || !handleCustomEvent) return {};
|
|
166
|
+
const result = handleCustomEvent(paramScript);
|
|
167
|
+
return result && typeof result === "object" && !Array.isArray(result)
|
|
168
|
+
? result
|
|
169
|
+
: {};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function buildDynamicSchemaRequestData(
|
|
173
|
+
formModel,
|
|
174
|
+
paramScript,
|
|
175
|
+
handleCustomEvent,
|
|
176
|
+
wrapContext
|
|
177
|
+
) {
|
|
178
|
+
const extra = resolveDynamicSchemaExtra(paramScript, handleCustomEvent);
|
|
179
|
+
const payload = {
|
|
180
|
+
formData: formModel || {},
|
|
181
|
+
...extra,
|
|
182
|
+
};
|
|
183
|
+
if (!wrapContext) {
|
|
184
|
+
return payload;
|
|
185
|
+
}
|
|
186
|
+
const { formCode, formVersion, taBm, dataId } = wrapContext;
|
|
187
|
+
return {
|
|
188
|
+
formCode,
|
|
189
|
+
formVersion,
|
|
190
|
+
taBm,
|
|
191
|
+
formData: payload.formData,
|
|
192
|
+
dataId,
|
|
193
|
+
data: {
|
|
194
|
+
dataId,
|
|
195
|
+
...payload,
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** 从 objx 或转换脚本结果中提取定义数组 */
|
|
201
|
+
export function extractDynamicSchemaItems(source) {
|
|
202
|
+
if (!source) return [];
|
|
203
|
+
if (Array.isArray(source)) return source;
|
|
204
|
+
if (typeof source !== "object") return [];
|
|
205
|
+
if (Array.isArray(source.fields)) return source.fields;
|
|
206
|
+
if (Array.isArray(source.columns)) return source.columns;
|
|
207
|
+
return [];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function resolveDynamicSchemaResponse(res, convertScript, handleCustomEvent) {
|
|
211
|
+
if (convertScript && handleCustomEvent) {
|
|
212
|
+
const result = handleCustomEvent(convertScript, ["res"], [res]);
|
|
213
|
+
return extractDynamicSchemaItems(result);
|
|
214
|
+
}
|
|
215
|
+
return extractDynamicSchemaItems(res && res.objx);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export function normalizeDynamicFieldKey(item) {
|
|
219
|
+
if (!item || typeof item !== "object") return undefined;
|
|
220
|
+
return item.keyName;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function normalizeDynamicColumnItem(item, index) {
|
|
224
|
+
if (!item || typeof item !== "object") {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const keyName = normalizeDynamicFieldKey(item);
|
|
229
|
+
const label = item.label;
|
|
230
|
+
let formatS = item.formatS || null;
|
|
231
|
+
if (!formatS && item.type) {
|
|
232
|
+
formatS = widgetTypeToEditFormatMap[item.type] || item.type;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
let editFormatS = null;
|
|
236
|
+
if (formatS && String(formatS).startsWith("edit")) {
|
|
237
|
+
editFormatS = formatS;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const widgetOptions = buildWidgetOptions(item, formatS, label);
|
|
241
|
+
|
|
242
|
+
let widget = null;
|
|
243
|
+
let widgetList = null;
|
|
244
|
+
if (
|
|
245
|
+
(item.type === "dropdown" || formatS === "dropdown") &&
|
|
246
|
+
Array.isArray(item.dropdownItems) &&
|
|
247
|
+
item.dropdownItems.length
|
|
248
|
+
) {
|
|
249
|
+
widget = buildDropdownWidgetFromDef(item, index);
|
|
250
|
+
if (widget && label) {
|
|
251
|
+
widget.options.label = label;
|
|
252
|
+
}
|
|
253
|
+
if (widget?.widgetList?.length) {
|
|
254
|
+
widgetList = widget.widgetList;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (!keyName && !isActionOrGroupColumn(item, formatS)) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const isAction = isActionColumn(item, formatS);
|
|
263
|
+
|
|
264
|
+
const widgetFlags = {};
|
|
265
|
+
DYNAMIC_SCHEMA_WIDGET_FLAG_KEYS.forEach((key) => {
|
|
266
|
+
if (item[key] !== undefined) {
|
|
267
|
+
widgetFlags[key] = item[key];
|
|
268
|
+
} else if (widgetOptions?.[key] !== undefined) {
|
|
269
|
+
widgetFlags[key] = widgetOptions[key];
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const children = Array.isArray(item.children)
|
|
274
|
+
? item.children
|
|
275
|
+
.map((child, childIndex) =>
|
|
276
|
+
normalizeDynamicColumnItem(child, index * 1000 + childIndex)
|
|
277
|
+
)
|
|
278
|
+
.filter(Boolean)
|
|
279
|
+
: item.children;
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
columnId: item.columnId || `${Date.now()}_${index}`,
|
|
283
|
+
type: item.type,
|
|
284
|
+
prop: keyName || undefined,
|
|
285
|
+
label,
|
|
286
|
+
width: item.width ?? 150,
|
|
287
|
+
show: item.show !== false,
|
|
288
|
+
sortable: isAction ? item.sortable === true : item.sortable !== false,
|
|
289
|
+
filterable: isAction ? item.filterable === true : item.filterable !== false,
|
|
290
|
+
...(item.align ? { align: item.align } : {}),
|
|
291
|
+
fixed: item.fixed,
|
|
292
|
+
formatS,
|
|
293
|
+
editFormatS: editFormatS || undefined,
|
|
294
|
+
optionItems: item.optionItems,
|
|
295
|
+
widget,
|
|
296
|
+
widgetList,
|
|
297
|
+
widgetOptions,
|
|
298
|
+
children: children,
|
|
299
|
+
render: item.render,
|
|
300
|
+
utcTransformEnabled: item.utcTransformEnabled,
|
|
301
|
+
...widgetFlags,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export function normalizeDynamicColumns(columns) {
|
|
306
|
+
if (!Array.isArray(columns)) {
|
|
307
|
+
return [];
|
|
308
|
+
}
|
|
309
|
+
return columns
|
|
310
|
+
.map((item, index) => normalizeDynamicColumnItem(item, index))
|
|
311
|
+
.filter(Boolean);
|
|
312
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isEmptyStr,
|
|
3
|
+
isEmptyArrayFieldValue,
|
|
4
|
+
isArrayValueWidgetType,
|
|
5
|
+
isVabsearchWidgetType,
|
|
6
|
+
isVabsearchMultiWidget,
|
|
7
|
+
} from "./util";
|
|
8
|
+
import { resolveColumnRequiredFlag } from "./tableColumnHelper";
|
|
9
|
+
|
|
10
|
+
/** 数据表格行内字段候选 key(column.prop 为权威存储字段) */
|
|
11
|
+
export function getCellFieldKeys(fieldWidget, columnConfig) {
|
|
12
|
+
const keys = [];
|
|
13
|
+
const addKey = (key) => {
|
|
14
|
+
if (key && !keys.includes(key)) {
|
|
15
|
+
keys.push(key);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
addKey(columnConfig?.prop);
|
|
20
|
+
|
|
21
|
+
if (!fieldWidget) {
|
|
22
|
+
return keys;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const options = fieldWidget.options || {};
|
|
26
|
+
if (
|
|
27
|
+
isVabsearchWidgetType(fieldWidget.type) &&
|
|
28
|
+
!isVabsearchMultiWidget(fieldWidget)
|
|
29
|
+
) {
|
|
30
|
+
addKey(options.vabSearchName);
|
|
31
|
+
addKey(getWidgetFieldKey(fieldWidget));
|
|
32
|
+
} else {
|
|
33
|
+
addKey(getWidgetFieldKey(fieldWidget));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return keys;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getCellFieldKey(fieldWidget, columnConfig) {
|
|
40
|
+
const keys = getCellFieldKeys(fieldWidget, columnConfig);
|
|
41
|
+
return keys.length ? keys[0] : null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getWidgetFieldKey(widget) {
|
|
45
|
+
if (!widget?.options) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const o = widget.options.name;
|
|
49
|
+
return (widget.options.keyNameEnabled && widget.options.keyName) || o;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function isCellFieldRequired(columnConfig, fieldWidget) {
|
|
53
|
+
if (!fieldWidget || fieldWidget.options?.hidden) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (fieldWidget.options?.required) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return resolveColumnRequiredFlag(columnConfig);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function shouldSkipCellValidation(fieldWidget) {
|
|
63
|
+
if (!fieldWidget) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
if (fieldWidget.options?.hidden) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (fieldWidget.options?.disabled) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function isEmptyCellValue(fieldWidget, value) {
|
|
76
|
+
if (!fieldWidget) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
const type = fieldWidget.type;
|
|
80
|
+
const options = fieldWidget.options || {};
|
|
81
|
+
|
|
82
|
+
if (type === "number") {
|
|
83
|
+
return value === null || value === undefined || value === "";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (isArrayValueWidgetType(type, options)) {
|
|
87
|
+
return isEmptyArrayFieldValue(value, type, options);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (type === "select" || type === "radio" || type === "status") {
|
|
91
|
+
if (value === null || value === undefined || value === "") {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
if (typeof value === "string" && !/[^\s]/.test(value)) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return isEmptyStr(value);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** 从行数据中读取单元格值(兼容 column.prop 与 widget 字段名不一致) */
|
|
104
|
+
export function getCellValueFromRow(row, fieldWidget, columnConfig) {
|
|
105
|
+
if (!row) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const keys = getCellFieldKeys(fieldWidget, columnConfig);
|
|
109
|
+
if (!keys.length) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
let fallbackValue;
|
|
113
|
+
for (const key of keys) {
|
|
114
|
+
const value = row[key];
|
|
115
|
+
if (fallbackValue === undefined) {
|
|
116
|
+
fallbackValue = value;
|
|
117
|
+
}
|
|
118
|
+
if (!isEmptyCellValue(fieldWidget, value)) {
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return fallbackValue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function isEmptyCellValueInRow(row, fieldWidget, columnConfig) {
|
|
126
|
+
return isEmptyCellValue(
|
|
127
|
+
fieldWidget,
|
|
128
|
+
getCellValueFromRow(row, fieldWidget, columnConfig)
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function buildCellRequiredHint(fieldWidget, columnConfig, t1Fn) {
|
|
133
|
+
const options = fieldWidget?.options || {};
|
|
134
|
+
if (options.requiredHint) {
|
|
135
|
+
return t1Fn(options.requiredHint);
|
|
136
|
+
}
|
|
137
|
+
const label = t1Fn(
|
|
138
|
+
options.label || columnConfig?.label || columnConfig?.prop || ""
|
|
139
|
+
);
|
|
140
|
+
return t1Fn("[{label}]不能为空", { label });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function buildTableCellFormProp(tableFieldKeyName, rowIndex, fieldKey) {
|
|
144
|
+
if (!tableFieldKeyName || !fieldKey || rowIndex < 0) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
return `${tableFieldKeyName}.${rowIndex}.${fieldKey}`;
|
|
148
|
+
}
|
|
@@ -43,6 +43,26 @@ function enrichColumnList(columns, configMap) {
|
|
|
43
43
|
/**
|
|
44
44
|
* Apply data-table column header icon config to vxe-table column definition.
|
|
45
45
|
*/
|
|
46
|
+
export function resolveColumnRequiredFlag(columnConfig) {
|
|
47
|
+
if (!columnConfig) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
if (columnConfig.required) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (columnConfig.editWidget?.options?.required) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (columnConfig.widget?.options?.required) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
const widgetOptions =
|
|
60
|
+
columnConfig.widgetOptions ?? columnConfig.columnOption;
|
|
61
|
+
const editWidgetOptions =
|
|
62
|
+
columnConfig.editWidgetOptions ?? columnConfig.editColumnOption;
|
|
63
|
+
return !!(widgetOptions?.required || editWidgetOptions?.required);
|
|
64
|
+
}
|
|
65
|
+
|
|
46
66
|
export function applyColumnLabelIcon(col, columnConfig) {
|
|
47
67
|
if (!col || !columnConfig) {
|
|
48
68
|
return col;
|
|
@@ -51,7 +71,7 @@ export function applyColumnLabelIcon(col, columnConfig) {
|
|
|
51
71
|
const iconClass = columnConfig.labelIconClass;
|
|
52
72
|
const position = columnConfig.labelIconPosition || "rear";
|
|
53
73
|
const tooltip = columnConfig.labelTooltip;
|
|
54
|
-
const required =
|
|
74
|
+
const required = resolveColumnRequiredFlag(columnConfig);
|
|
55
75
|
const title = col.title;
|
|
56
76
|
|
|
57
77
|
if (!iconClass && !required) {
|
|
@@ -19,6 +19,92 @@ export function isNotNull(value) {
|
|
|
19
19
|
return value !== null && value !== undefined;
|
|
20
20
|
}
|
|
21
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
|
+
if (!Array.isArray(value)) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
return value.length === 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
22
108
|
export function isEmptyStr(str) {
|
|
23
109
|
//return (str === undefined) || (!str) || (!/[^\s]/.test(str));
|
|
24
110
|
return (
|
|
@@ -700,6 +786,7 @@ export const columnFormatMap = {
|
|
|
700
786
|
radio: "radio",
|
|
701
787
|
dropdown: "dropdown",
|
|
702
788
|
textarea: "textarea",
|
|
789
|
+
editScriptInput: "script-input",
|
|
703
790
|
};
|
|
704
791
|
|
|
705
792
|
/** 列 widget 扩展选项:动态列 widgetOptions;设计器静态列 columnOption */
|
|
@@ -713,6 +800,45 @@ export function getColumnWidgetOptions(row, isEdit = false) {
|
|
|
713
800
|
return row.widgetOptions ?? row.columnOption;
|
|
714
801
|
}
|
|
715
802
|
|
|
803
|
+
/** 将列级 label / keyName / required 同步到列内 field widget(动态列 label 在列顶层) */
|
|
804
|
+
export function applyColumnMetaToFieldWidget(fieldWidget, row, isEdit = false) {
|
|
805
|
+
if (!fieldWidget || !row) {
|
|
806
|
+
return fieldWidget;
|
|
807
|
+
}
|
|
808
|
+
const widgetOptions = getColumnWidgetOptions(row, isEdit);
|
|
809
|
+
if (fieldWidget.options.hasOwnProperty("required")) {
|
|
810
|
+
fieldWidget.options.required = !!(row.required || widgetOptions?.required);
|
|
811
|
+
}
|
|
812
|
+
if (!fieldWidget.options.label && row.label) {
|
|
813
|
+
fieldWidget.options.label = row.label;
|
|
814
|
+
}
|
|
815
|
+
if (row.prop) {
|
|
816
|
+
if (fieldWidget.options.hasOwnProperty("keyName")) {
|
|
817
|
+
fieldWidget.options.keyName = row.prop;
|
|
818
|
+
fieldWidget.options.keyNameEnabled = true;
|
|
819
|
+
} else if (!fieldWidget.options.name) {
|
|
820
|
+
fieldWidget.options.name = row.prop;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
if (fieldWidget.type !== "button" && fieldWidget.type !== "a-link") {
|
|
824
|
+
fieldWidget.options.labelHidden = true;
|
|
825
|
+
}
|
|
826
|
+
return fieldWidget;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/** 同步列 widget / editWidget 的列级元数据(含 labelHidden) */
|
|
830
|
+
export function applyColumnMetaToColumnRow(row) {
|
|
831
|
+
if (!row) {
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
if (row.widget) {
|
|
835
|
+
applyColumnMetaToFieldWidget(row.widget, row, false);
|
|
836
|
+
}
|
|
837
|
+
if (row.editWidget) {
|
|
838
|
+
applyColumnMetaToFieldWidget(row.editWidget, row, true);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
716
842
|
export function getFieldWidgetById(widgetList, fieldId, staticWidgetsIncluded) {
|
|
717
843
|
if (!widgetList) {
|
|
718
844
|
return null;
|