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.
Files changed (24) hide show
  1. package/package.json +1 -1
  2. package/src/components/fileLibrary/index.vue +113 -33
  3. 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
  4. 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
  5. package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +80 -14
  6. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +18 -13
  7. package/src/components/xform/form-designer/form-widget/field-widget/number-widget.vue +11 -8
  8. package/src/components/xform/form-designer/form-widget/field-widget/script-input-widget.vue +143 -0
  9. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +87 -25
  10. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +5 -0
  11. package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +80 -34
  12. package/src/components/xform/form-designer/setting-panel/property-editor/field-script-input/script-input-editor.vue +54 -0
  13. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +1 -0
  14. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +56 -1
  15. package/src/components/xform/form-render/container-item/data-table-mixin.js +296 -118
  16. package/src/components/xform/form-render/container-item/dynamicFieldMixin.js +25 -37
  17. package/src/components/xform/form-render/container-item/list-h5-item.vue +5 -1
  18. package/src/components/xform/form-render/indexMixin.js +175 -6
  19. package/src/components/xform/lang/en-US.js +1 -0
  20. package/src/components/xform/lang/zh-CN.js +1 -0
  21. package/src/components/xform/utils/dynamicSchemaUtil.js +312 -0
  22. package/src/components/xform/utils/tableCellValidateUtil.js +148 -0
  23. package/src/components/xform/utils/tableColumnHelper.js +21 -1
  24. 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 = !!columnConfig.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;