@dckj-npm/dc-material 0.1.376 → 0.1.378

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 (59) hide show
  1. package/build/docs/colorful-button.html +3 -3
  2. package/build/docs/colorful-input.html +3 -3
  3. package/build/docs/custom-form/requirements.html +48 -0
  4. package/build/docs/custom-form.html +48 -0
  5. package/build/docs/index.html +3 -3
  6. package/build/docs/teletext-list.html +3 -3
  7. package/build/docs/{umi.6743fcd4.css → umi.b31e14a3.css} +1 -1
  8. package/build/docs/umi.e6e366c9.js +1 -0
  9. package/build/docs/~demos/colorful-button-demo.html +3 -3
  10. package/build/docs/~demos/colorful-input-demo.html +3 -3
  11. package/build/docs/~demos/teletext-list-demo-1.html +3 -3
  12. package/build/docs/~demos/teletext-list-demo.html +3 -3
  13. package/build/lowcode/assets-daily.json +13 -13
  14. package/build/lowcode/assets-dev.json +2 -2
  15. package/build/lowcode/assets-prod.json +13 -13
  16. package/build/lowcode/meta.design.js +1 -1
  17. package/build/lowcode/meta.js +1 -1
  18. package/build/lowcode/render/default/view.css +1 -1
  19. package/build/lowcode/render/default/view.js +1 -1
  20. package/build/lowcode/view.css +1 -1
  21. package/build/lowcode/view.js +1 -1
  22. package/dist/BizComps.css +1 -1
  23. package/dist/BizComps.js +2 -2
  24. package/dist/BizComps.js.map +1 -1
  25. package/es/components/custom-form/CUSTOM_FORM_OPERATION_MANUAL.md +284 -0
  26. package/es/components/custom-form/custom-form.d.ts +168 -2
  27. package/es/components/custom-form/custom-form.js +444 -24
  28. package/es/components/custom-form/index.d.ts +1 -1
  29. package/es/components/custom-form/index.scss +1 -1
  30. package/es/components/custom-form/schema.json +1374 -0
  31. package/es/components/teletext-list/teletext-list-item.d.ts +14 -77
  32. package/es/components/teletext-list/teletext-list-item.js +153 -165
  33. package/es/components/teletext-list/teletext-list-item.scss +53 -4
  34. package/es/components/teletext-list/teletext-list.d.ts +60 -4
  35. package/es/components/teletext-list/teletext-list.js +55 -37
  36. package/lib/components/custom-form/CUSTOM_FORM_OPERATION_MANUAL.md +284 -0
  37. package/lib/components/custom-form/custom-form.d.ts +168 -2
  38. package/lib/components/custom-form/custom-form.js +449 -29
  39. package/lib/components/custom-form/index.d.ts +1 -1
  40. package/lib/components/custom-form/index.scss +1 -1
  41. package/lib/components/custom-form/schema.json +1374 -0
  42. package/lib/components/teletext-list/teletext-list-item.d.ts +14 -77
  43. package/lib/components/teletext-list/teletext-list-item.js +153 -164
  44. package/lib/components/teletext-list/teletext-list-item.scss +53 -4
  45. package/lib/components/teletext-list/teletext-list.d.ts +60 -4
  46. package/lib/components/teletext-list/teletext-list.js +55 -37
  47. package/lowcode/custom-form/meta.ts +1500 -118
  48. package/lowcode/teletext-list/meta.ts +457 -703
  49. package/lowcode/teletext-list/meta.ts.bak +821 -0
  50. package/lowcode_es/custom-form/meta.js +1932 -144
  51. package/lowcode_es/meta.js +1 -1
  52. package/lowcode_es/teletext-list/meta.js +689 -598
  53. package/lowcode_es/teletext-list/meta.ts.bak +821 -0
  54. package/lowcode_lib/custom-form/meta.js +1932 -144
  55. package/lowcode_lib/meta.js +1 -1
  56. package/lowcode_lib/teletext-list/meta.js +689 -598
  57. package/lowcode_lib/teletext-list/meta.ts.bak +821 -0
  58. package/package.json +3 -3
  59. package/build/docs/umi.d20b1d99.js +0 -1
@@ -5,13 +5,52 @@ import _NumberPicker from "@alifd/next/es/number-picker";
5
5
  import _DatePicker from "@alifd/next/es/date-picker";
6
6
  import _Checkbox from "@alifd/next/es/checkbox";
7
7
  import _Radio from "@alifd/next/es/radio";
8
+ import _Button from "@alifd/next/es/button";
8
9
  import _Select from "@alifd/next/es/select";
9
10
  import _Input from "@alifd/next/es/input";
10
11
  import _ResponsiveGrid from "@alifd/next/es/responsive-grid";
11
12
  import _Form from "@alifd/next/es/form";
12
- var _excluded = ["columns", "spacing", "emptyContent", "formItems", "showSubmit", "submitText", "submitValidate", "submitDataSource", "submitButtonProps", "showReset", "resetText", "resetButtonProps", "onSubmit", "onSubmitFailed", "children"];
13
- import React, { useCallback } from 'react';
13
+ var _excluded = ["columns", "spacing", "emptyContent", "formItems", "initialValues", "computedFields", "fieldLinkage", "submitMapping", "fullWidth", "showSubmit", "submitText", "submitValidate", "submitDataSource", "submitButtonProps", "showReset", "resetText", "resetButtonProps", "operations", "operationAlign", "onSubmit", "onSubmitFailed", "onChange", "onReset", "children", "labelAlign", "labelCol", "size"];
14
+ /**
15
+ * CustomForm v0.5
16
+ * 阶段一新增能力:
17
+ * - onChange(field, value, allValues) 统一字段变化事件,消灭所有 onXxxChange 样板函数
18
+ * - initialValues 属性面板直接配置字段初始值,无需在页面 state 手写
19
+ * - computedFields 声明式模板字符串计算衍生字段,提交时自动合并
20
+ * 阶段二新增能力:
21
+ * - DateTimePicker 日期时间组件,格式化为 YYYY-MM-DD HH:mm
22
+ * - optionsBind 下拉/单选/复选选项支持变量绑定(动态数据源)
23
+ * - fieldLinkage 字段联动:选 A → 自动填 B/C(从数据源查找匹配项)
24
+ * - submitMapping 提交映射:自动组装 itemList 格式,消灭手写 onSubmitClick
25
+ * 阶段三新增能力:
26
+ * - labelAlign 全局标签位置(top/left/inset),对齐 Fusion Form 标准
27
+ * - fullWidth(全局) 全局控制所有表单项组件是否 100% 宽,可被单项覆盖
28
+ * - isPreview 全局预览/只读态(依赖 Fusion Form isPreview 广播)
29
+ * - labelCol / wrapperCol via otherProps 透传,labelAlign=left 时配合使用
30
+ * - onReset 点击重置按钮后触发的回调事件
31
+ */
32
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
14
33
  import "./index.scss";
34
+ // ─── 调试日志工具(阶段一)────────────────────────────────────────────────────
35
+ var DEBUG_PREFIX = '[CustomForm v0.4]';
36
+ var cfLog = function cfLog(tag) {
37
+ var _console;
38
+ // 生产环境可通过 window.__CUSTOM_FORM_DEBUG__ = false 关闭
39
+ if (typeof window !== 'undefined' && window.__CUSTOM_FORM_DEBUG__ === false) return;
40
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
41
+ args[_key - 1] = arguments[_key];
42
+ }
43
+ (_console = console).log.apply(_console, [DEBUG_PREFIX + " [" + tag + "]"].concat(args));
44
+ };
45
+ var cfWarn = function cfWarn(tag) {
46
+ var _console2;
47
+ for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
48
+ args[_key2 - 1] = arguments[_key2];
49
+ }
50
+ (_console2 = console).warn.apply(_console2, [DEBUG_PREFIX + " [" + tag + "]"].concat(args));
51
+ };
52
+ // ─────────────────────────────────────────────────────────────────────────────
53
+
15
54
  var NextFormAny = _Form;
16
55
  var ResponsiveGridAny = _ResponsiveGrid;
17
56
  var ResponsiveGridCell = _ResponsiveGrid.Cell;
@@ -19,11 +58,108 @@ var FormItemAny = _Form.Item;
19
58
  var InputAny = _Input;
20
59
  var TextAreaAny = _Input.TextArea;
21
60
  var SelectAny = _Select;
61
+ var ButtonAny = _Button;
22
62
  var RadioGroupAny = _Radio.Group;
23
63
  var CheckboxGroupAny = _Checkbox.Group;
24
64
  var DatePickerAny = _DatePicker;
25
65
  var NumberPickerAny = _NumberPicker;
26
66
  var UploadAny = _Upload;
67
+
68
+ /**
69
+ * computedFields:计算字段映射表
70
+ * key = 要写入 values 的字段名
71
+ * value = 模板字符串,用 {fieldName} 引用其他字段值
72
+ * 示例:{ "order_desc": "{package_name},{package_price},日期:{banquet_date}" }
73
+ */
74
+
75
+ /**
76
+ * 字段联动规则(阶段二 + 阶段四 UX 简化)
77
+ *
78
+ * 【简单格式(推荐)】— 属性面板 ArraySetter 可视化编辑,每条规则对应一行:
79
+ * { watchField, matchValue?, fillField, fillValue }
80
+ * watchField = 监听哪个字段变化
81
+ * matchValue = 匹配值(留空 = 任何变化都触发)
82
+ * fillField = 要回填的目标字段名
83
+ * fillValue = 回填的具体值
84
+ *
85
+ * 【高级格式(兼容旧配置)】— 支持动态数据源查找 + staticRules 嵌套格式:
86
+ * { watchField, dataSource?, matchKey?, fillFields?, staticRules? }
87
+ */
88
+
89
+ /** 提交映射 item(阶段二) */
90
+
91
+ /**
92
+ * 操作按钮配置项(阶段四新增)
93
+ * 表单底部可配置多个按钮,每个按钮均可独立设置操作类型与数据源。
94
+ */
95
+
96
+ /**
97
+ * 提交映射配置(阶段二)
98
+ * 配置后,提交时自动将指定字段组装为 { columnName, columnValue }[] 格式并写入 finalValues。
99
+ * 消灭手写 onSubmitClick 中的 itemList 拼接逻辑。
100
+ */
101
+
102
+ // ─── 工具:模板字符串渲染 ─────────────────────────────────────────────────────
103
+ /**
104
+ * 将 "{fieldA},{fieldB}" 中的占位符替换为 values 对应的真实值
105
+ */
106
+ var renderTemplate = function renderTemplate(template, values) {
107
+ return template.replace(/\{(\w+)\}/g, function (_, key) {
108
+ var val = values[key];
109
+ return val !== undefined && val !== null ? String(val) : '';
110
+ });
111
+ };
112
+
113
+ /**
114
+ * 将 initialValues 从数组格式标准化为对象格式(向后兼容)。
115
+ * 数组格式由低代码设计器属性面板存储:[{field, valueType, value}, ...]
116
+ * 对象格式为运行时使用:{ fieldName: value, ... }
117
+ */
118
+ var normalizeInitialValues = function normalizeInitialValues(raw) {
119
+ if (!raw) return {};
120
+ if (Array.isArray(raw)) {
121
+ return raw.reduce(function (acc, item) {
122
+ if (item && item.field) {
123
+ acc[item.field] = item.value !== undefined ? item.value : '';
124
+ }
125
+ return acc;
126
+ }, {});
127
+ }
128
+ return raw;
129
+ };
130
+
131
+ /**
132
+ * 将 computedFields 从数组格式标准化为对象格式(向后兼容)。
133
+ * 数组格式:[{targetField, template}, ...]
134
+ * 对象格式:{ targetField: template, ... }
135
+ */
136
+ var normalizeComputedFields = function normalizeComputedFields(raw) {
137
+ if (!raw) return {};
138
+ if (Array.isArray(raw)) {
139
+ return raw.reduce(function (acc, item) {
140
+ if (item && item.targetField) {
141
+ acc[item.targetField] = item.template || '';
142
+ }
143
+ return acc;
144
+ }, {});
145
+ }
146
+ return raw;
147
+ };
148
+
149
+ /**
150
+ * 将 computedFields 的所有模板计算后合并进 values,返回新对象(不修改原值)
151
+ */
152
+ var applyComputedFields = function applyComputedFields(values, computedFields) {
153
+ if (!computedFields || Object.keys(computedFields).length === 0) return values;
154
+ var result = _extends({}, values);
155
+ Object.keys(computedFields).forEach(function (key) {
156
+ result[key] = renderTemplate(computedFields[key], result);
157
+ });
158
+ cfLog('computedFields', '计算字段结果', result);
159
+ return result;
160
+ };
161
+ // ─────────────────────────────────────────────────────────────────────────────
162
+
27
163
  var runSubmitDataSource = function runSubmitDataSource(submitDataSource, values, errors, field) {
28
164
  if (!submitDataSource) return;
29
165
  if (typeof submitDataSource === 'function') {
@@ -47,8 +183,10 @@ var runSubmitDataSource = function runSubmitDataSource(submitDataSource, values,
47
183
  }
48
184
  };
49
185
  var renderFormItemComponent = function renderFormItemComponent(item) {
186
+ var _item$optionsBind;
50
187
  var componentProps = item.componentProps || {};
51
- var dataSource = componentProps.dataSource || item.options || [];
188
+ // optionsBind(动态绑定)优先级 > componentProps.dataSource > options(静态)
189
+ var dataSource = (_item$optionsBind = item.optionsBind) !== null && _item$optionsBind !== void 0 && _item$optionsBind.length ? item.optionsBind : componentProps.dataSource || item.options || [];
52
190
  switch (item.componentType) {
53
191
  case 'TextArea':
54
192
  return /*#__PURE__*/React.createElement(TextAreaAny, componentProps);
@@ -68,6 +206,12 @@ var renderFormItemComponent = function renderFormItemComponent(item) {
68
206
  return /*#__PURE__*/React.createElement(NumberPickerAny, componentProps);
69
207
  case 'DatePicker':
70
208
  return /*#__PURE__*/React.createElement(DatePickerAny, componentProps);
209
+ case 'DateTimePicker':
210
+ // 日期时间选择器:showTime 开启,格式化为 YYYY-MM-DD HH:mm
211
+ return /*#__PURE__*/React.createElement(DatePickerAny, _extends({
212
+ showTime: true,
213
+ format: "YYYY-MM-DD HH:mm"
214
+ }, componentProps));
71
215
  case 'Upload':
72
216
  return /*#__PURE__*/React.createElement(UploadAny, componentProps);
73
217
  case 'Input':
@@ -79,11 +223,16 @@ var CustomForm = function CustomForm(_ref) {
79
223
  var _ref$columns = _ref.columns,
80
224
  columns = _ref$columns === void 0 ? 1 : _ref$columns,
81
225
  _ref$spacing = _ref.spacing,
82
- spacing = _ref$spacing === void 0 ? [0, 16, 16, 0] : _ref$spacing,
226
+ spacing = _ref$spacing === void 0 ? [0, 16] : _ref$spacing,
83
227
  _ref$emptyContent = _ref.emptyContent,
84
228
  emptyContent = _ref$emptyContent === void 0 ? '添加表单项' : _ref$emptyContent,
85
229
  _ref$formItems = _ref.formItems,
86
230
  formItems = _ref$formItems === void 0 ? [] : _ref$formItems,
231
+ initialValues = _ref.initialValues,
232
+ computedFields = _ref.computedFields,
233
+ fieldLinkage = _ref.fieldLinkage,
234
+ submitMapping = _ref.submitMapping,
235
+ globalFullWidth = _ref.fullWidth,
87
236
  _ref$showSubmit = _ref.showSubmit,
88
237
  showSubmit = _ref$showSubmit === void 0 ? true : _ref$showSubmit,
89
238
  _ref$submitText = _ref.submitText,
@@ -97,25 +246,256 @@ var CustomForm = function CustomForm(_ref) {
97
246
  _ref$resetText = _ref.resetText,
98
247
  resetText = _ref$resetText === void 0 ? '重置' : _ref$resetText,
99
248
  resetButtonProps = _ref.resetButtonProps,
249
+ operations = _ref.operations,
250
+ _ref$operationAlign = _ref.operationAlign,
251
+ operationAlign = _ref$operationAlign === void 0 ? 'center' : _ref$operationAlign,
100
252
  onSubmit = _ref.onSubmit,
101
253
  onSubmitFailed = _ref.onSubmitFailed,
254
+ onChange = _ref.onChange,
255
+ onReset = _ref.onReset,
102
256
  children = _ref.children,
257
+ labelAlign = _ref.labelAlign,
258
+ labelCol = _ref.labelCol,
259
+ globalSize = _ref.size,
103
260
  otherProps = _objectWithoutPropertiesLoose(_ref, _excluded);
104
- var handleSubmit = useCallback(function (values, errors, field) {
261
+ // ─── 直接传递列数,通过 device="desktop" 锁定成桌面模式,防止 ResponsiveGrid 根据视口自动缩列
262
+ // ResponsiveGrid columns 只接受 number/string,不接受 breakpoint 对象
263
+ var fixedColumns = columns;
264
+
265
+ // ─── 兼容旧版 4-value spacing → 标准化为 [rowGap, colGap] ─────────────────
266
+ var normalizedGap = useMemo(function () {
267
+ var _spacing$, _spacing$2;
268
+ if (!Array.isArray(spacing)) return spacing;
269
+ if (spacing.length >= 2) return [spacing[0], spacing[1]];
270
+ return [(_spacing$ = spacing[0]) !== null && _spacing$ !== void 0 ? _spacing$ : 0, (_spacing$2 = spacing[0]) !== null && _spacing$2 !== void 0 ? _spacing$2 : 16];
271
+ }, [spacing]);
272
+
273
+ // ─── 标准化 initialValues / computedFields(支持设计器生成的数组格式与运行时对象格式)
274
+ var resolvedInitialValues = useMemo(function () {
275
+ return normalizeInitialValues(initialValues);
276
+ }, [initialValues]);
277
+ var resolvedComputedFields = useMemo(function () {
278
+ return normalizeComputedFields(computedFields);
279
+ }, [computedFields]);
280
+
281
+ // ─── 用 ref 缓存所有字段的当前值,避免 onChange 闭包过期 ──────────────────
282
+ // 初始化时直接合并 resolvedInitialValues,避免 useEffect 延迟问题
283
+ var valuesRef = useRef(resolvedInitialValues ? _extends({}, resolvedInitialValues) : {});
284
+
285
+ // ─── 联动回填触发器:用 state 驱动组件重渲染以更新受控字段 ───────────────
286
+ var _useState = useState(function () {
287
+ return resolvedInitialValues ? _extends({}, resolvedInitialValues) : {};
288
+ }),
289
+ linkageValues = _useState[0],
290
+ setLinkageValues = _useState[1];
291
+
292
+ // ─── 统一 onChange 处理器(阶段一 + 阶段二核心)─────────────────────────────
293
+ var handleFieldChange = useCallback(function (field, value) {
294
+ var _extends2;
295
+ // 1. 更新本地 values 缓存
296
+ valuesRef.current = _extends({}, valuesRef.current, (_extends2 = {}, _extends2[field] = value, _extends2));
297
+ cfLog('onChange', "\u5B57\u6BB5 \"" + field + "\" \u53D8\u5316", {
298
+ value: value,
299
+ allValues: valuesRef.current
300
+ });
301
+
302
+ // 2. 字段联动(阶段二):检查是否有对应的联动规则
303
+ var linkagePatched = null;
304
+ if (fieldLinkage && fieldLinkage.length > 0) {
305
+ fieldLinkage.forEach(function (rule) {
306
+ if (rule.watchField !== field) return;
307
+
308
+ // 2a. 静态联动规则(高级格式)
309
+ if (rule.staticRules) {
310
+ var staticFill = rule.staticRules[String(value)];
311
+ if (staticFill) {
312
+ linkagePatched = _extends({}, linkagePatched || {}, staticFill);
313
+ Object.assign(valuesRef.current, staticFill);
314
+ cfLog('linkage', "\u9759\u6001\u8054\u52A8 \"" + field + "\" = " + value + "\uFF0C\u56DE\u586B", staticFill);
315
+ }
316
+ }
317
+
318
+ // 2b. 数据源动态联动(高级格式)
319
+ if (rule.dataSource && rule.fillFields) {
320
+ var matchKey = rule.matchKey || 'value';
321
+ var matched = rule.dataSource.find(function (item) {
322
+ return item[matchKey] === value;
323
+ });
324
+ if (matched) {
325
+ var fill = {};
326
+ Object.entries(rule.fillFields).forEach(function (_ref2) {
327
+ var formField = _ref2[0],
328
+ dsKey = _ref2[1];
329
+ fill[formField] = matched[dsKey];
330
+ });
331
+ linkagePatched = _extends({}, linkagePatched || {}, fill);
332
+ Object.assign(valuesRef.current, fill);
333
+ cfLog('linkage', "\u52A8\u6001\u8054\u52A8 \"" + field + "\" = " + value + "\uFF0C\u56DE\u586B", fill);
334
+ }
335
+ }
336
+
337
+ // 2c. 简单联动格式(新格式,属性面板可视化编辑生成)
338
+ if (rule.fillField !== undefined && rule.fillValue !== undefined) {
339
+ var noConstraint = rule.matchValue === undefined || rule.matchValue === '';
340
+ var _matched = noConstraint || String(value) === String(rule.matchValue);
341
+ if (_matched) {
342
+ var _fill2;
343
+ var _fill = (_fill2 = {}, _fill2[rule.fillField] = rule.fillValue, _fill2);
344
+ linkagePatched = _extends({}, linkagePatched || {}, _fill);
345
+ Object.assign(valuesRef.current, _fill);
346
+ cfLog('linkage', "\u7B80\u5355\u8054\u52A8 \"" + field + "\" = " + value + "\uFF0C\u56DE\u586B", _fill);
347
+ }
348
+ }
349
+ });
350
+ }
351
+ // 有联动回填时,更新 linkageValues 触发重渲染
352
+ if (linkagePatched) {
353
+ setLinkageValues(function (prev) {
354
+ return _extends({}, prev, linkagePatched);
355
+ });
356
+ }
357
+
358
+ // 3. 计算 computedFields,得到包含衍生字段的完整值
359
+ var allValues = applyComputedFields(valuesRef.current, resolvedComputedFields);
360
+
361
+ // 4. 触发外部 onChange 事件(低代码侧可绑定 updateVariable)
362
+ if (onChange) {
363
+ onChange(field, value, allValues);
364
+ }
365
+ }, [resolvedComputedFields, fieldLinkage, onChange]);
366
+
367
+ // ─── 提交处理 ───────────────────────────────────────────────────────────────
368
+ // ─── 对齐方式映射 ───────────────────────────────────────────────────────────
369
+ var alignJustifyMap = {
370
+ left: 'flex-start',
371
+ center: 'center',
372
+ right: 'flex-end'
373
+ };
374
+
375
+ // ─── 有效操作按钮列表 ────────────────────────────────────────────────────────
376
+ // operations prop 存在(哪怕是空数组)时:以 operations 为准,完全忽略旧版 showSubmit/showReset
377
+ // operations prop 为 undefined 时:回退到旧版双按钮模式(向后兼容)
378
+ var effectiveOperations = useMemo(function () {
379
+ if (operations !== undefined) return operations;
380
+ var ops = [];
381
+ if (showReset) ops.push({
382
+ text: resetText || '重置',
383
+ action: 'reset',
384
+ type: 'normal'
385
+ });
386
+ if (showSubmit) ops.push({
387
+ text: submitText || '提交',
388
+ action: 'submit',
389
+ type: 'primary',
390
+ submitValidate: submitValidate
391
+ });
392
+ return ops;
393
+ }, [operations, showSubmit, submitText, submitValidate, showReset, resetText]);
394
+ var handleSubmit = useCallback(function (values, errors, field, buttonDataSource) {
395
+ // 将 Form 收集的 values 与 ref 缓存合并(兼容 initialValues 未经 onChange 的字段)
396
+ var mergedValues = _extends({}, valuesRef.current, values);
397
+ // 追加 computedFields 衍生字段
398
+ var finalValues = applyComputedFields(mergedValues, resolvedComputedFields);
399
+
400
+ // submitMapping:自动组装 itemList 格式(阶段二)
401
+ if (submitMapping && submitMapping.items && submitMapping.items.length > 0) {
402
+ var _extends3;
403
+ var targetField = submitMapping.targetField || 'itemList';
404
+ var itemList = submitMapping.items.map(function (mappingItem) {
405
+ var columnValue;
406
+ if (mappingItem.field) {
407
+ var _finalValues$mappingI;
408
+ columnValue = (_finalValues$mappingI = finalValues[mappingItem.field]) !== null && _finalValues$mappingI !== void 0 ? _finalValues$mappingI : '';
409
+ } else if (mappingItem.template) {
410
+ columnValue = renderTemplate(mappingItem.template, finalValues);
411
+ } else {
412
+ columnValue = '';
413
+ }
414
+ return {
415
+ columnName: mappingItem.columnName,
416
+ columnValue: columnValue
417
+ };
418
+ });
419
+ finalValues = _extends({}, finalValues, (_extends3 = {}, _extends3[targetField] = itemList, _extends3));
420
+ cfLog('submitMapping', "\u5DF2\u751F\u6210 " + targetField, itemList);
421
+ }
422
+ cfLog('submit', '提交触发', {
423
+ rawValues: values,
424
+ errors: errors,
425
+ finalValues: finalValues
426
+ });
105
427
  if (errors && Object.keys(errors).length) {
428
+ cfWarn('submit', '校验失败', errors);
106
429
  if (onSubmitFailed) {
107
- onSubmitFailed(values, errors, field);
430
+ onSubmitFailed(finalValues, errors, field);
108
431
  }
109
432
  return;
110
433
  }
434
+ cfLog('submit', '校验通过,准备提交', finalValues);
111
435
  if (onSubmit) {
112
- onSubmit(values, errors, field);
436
+ onSubmit(finalValues, errors, field);
113
437
  }
114
- runSubmitDataSource(submitDataSource, values, errors, field);
115
- }, [onSubmit, onSubmitFailed, submitDataSource]);
438
+ // buttonDataSource:单个按钮绑定的数据源(优先);未绑定时回退到组件级 submitDataSource
439
+ var effectiveDS = buttonDataSource !== null && buttonDataSource !== void 0 ? buttonDataSource : submitDataSource;
440
+ runSubmitDataSource(effectiveDS, finalValues, errors, field);
441
+ }, [computedFields, submitMapping, onSubmit, onSubmitFailed, submitDataSource]);
442
+
443
+ // ─── 渲染表单项,绑定统一 onChange ──────────────────────────────────────────
116
444
  var formItemNodes = formItems.map(function (item, index) {
445
+ var _linkageValues$item$f, _item$componentProps;
117
446
  var colSpan = Math.min(columns, Math.max(1, item.columnSpan || 1));
118
- var formItemProps = item.formItemProps || {};
447
+
448
+ // 初始值优先级:item.initialValue > linkageValues[field](含联动回填)> initialValues[field]
449
+ var fieldInitialValue = item.initialValue !== undefined ? item.initialValue : (_linkageValues$item$f = linkageValues[item.field]) !== null && _linkageValues$item$f !== void 0 ? _linkageValues$item$f : resolvedInitialValues === null || resolvedInitialValues === void 0 ? void 0 : resolvedInitialValues[item.field];
450
+
451
+ // 包装组件的 onChange,注入 field 信息
452
+ // fullWidth 优先级:item.fullWidth(单项)> globalFullWidth(全局)> undefined(不限制)
453
+ var effectiveFullWidth = item.fullWidth !== undefined ? item.fullWidth : globalFullWidth;
454
+ // 有效尺寸:单项 > 全局 > undefined(继承 Form 默认)
455
+ var effectiveSize = item.size || globalSize;
456
+ var componentPropsWithChange = _extends({}, item.placeholder ? {
457
+ placeholder: item.placeholder
458
+ } : {}, effectiveSize ? {
459
+ size: effectiveSize
460
+ } : {}, effectiveFullWidth !== undefined ? {
461
+ style: _extends({
462
+ width: effectiveFullWidth ? '100%' : undefined
463
+ }, ((_item$componentProps = item.componentProps) === null || _item$componentProps === void 0 ? void 0 : _item$componentProps.style) || {})
464
+ } : {}, item.componentProps || {}, {
465
+ onChange: function onChange(value) {
466
+ var _item$componentProps2;
467
+ if (typeof ((_item$componentProps2 = item.componentProps) === null || _item$componentProps2 === void 0 ? void 0 : _item$componentProps2.onChange) === 'function') {
468
+ item.componentProps.onChange(value);
469
+ }
470
+ handleFieldChange(item.field, value);
471
+ }
472
+ });
473
+
474
+ // 联动回填时,通过 value(受控)覆盖字段值;否则只用 defaultValue
475
+ var isLinkageControlled = linkageValues[item.field] !== undefined && item.initialValue === undefined;
476
+ if (isLinkageControlled) {
477
+ componentPropsWithChange.value = linkageValues[item.field];
478
+ } else if (fieldInitialValue !== undefined && componentPropsWithChange.value === undefined) {
479
+ componentPropsWithChange.defaultValue = fieldInitialValue;
480
+ cfLog('renderItem', "\u5B57\u6BB5 \"" + item.field + "\" \u6CE8\u5165\u521D\u59CB\u503C", fieldInitialValue);
481
+ }
482
+ if (!item.field) {
483
+ cfWarn('renderItem', "\u7B2C " + (index + 1) + " \u4E2A\u8868\u5355\u9879\u7F3A\u5C11 field \u5B57\u6BB5\uFF0ConChange \u5C06\u65E0\u6CD5\u7ED1\u5B9A");
484
+ }
485
+
486
+ // 合并 Form.Item 属性:通用属性 < 快捷字段 < formItemProps(最高优先级)
487
+ // labelAlign / labelCol 显式传入,确保设计器中不依赖 Form context 也能生效
488
+ var mergedFormItemProps = _extends({}, labelAlign ? {
489
+ labelAlign: labelAlign
490
+ } : {}, labelCol ? {
491
+ labelCol: labelCol
492
+ } : {}, effectiveSize ? {
493
+ size: effectiveSize
494
+ } : {}, item.help ? {
495
+ help: item.help
496
+ } : {}, item.extra ? {
497
+ extra: item.extra
498
+ } : {}, item.formItemProps || {});
119
499
  return /*#__PURE__*/React.createElement(ResponsiveGridCell, {
120
500
  colSpan: colSpan,
121
501
  key: (item.field || index) + "-form-item"
@@ -123,7 +503,9 @@ var CustomForm = function CustomForm(_ref) {
123
503
  label: item.label,
124
504
  name: item.field,
125
505
  required: item.required
126
- }, formItemProps), renderFormItemComponent(item)));
506
+ }, mergedFormItemProps), renderFormItemComponent(_extends({}, item, {
507
+ componentProps: componentPropsWithChange
508
+ }))));
127
509
  });
128
510
  var childrenNodes = React.Children.toArray(children).map(function (child, index) {
129
511
  if (/*#__PURE__*/React.isValidElement(child) && child.type === ResponsiveGridCell) {
@@ -135,24 +517,62 @@ var CustomForm = function CustomForm(_ref) {
135
517
  }, child);
136
518
  });
137
519
  var hasContent = formItemNodes.length > 0 || childrenNodes.length > 0;
520
+
521
+ // initialValues 通过 defaultValue 传入 Form(非受控初始化),避免覆盖联动回填的受控值
522
+ var formInitialProps = {};
523
+ if (initialValues && Object.keys(initialValues).length > 0) {
524
+ formInitialProps.defaultValue = initialValues;
525
+ cfLog('render', '表单携带 initialValues 渲染', initialValues);
526
+ }
138
527
  return /*#__PURE__*/React.createElement(NextFormAny, _extends({
139
528
  className: "custom-form"
140
- }, otherProps), hasContent ? /*#__PURE__*/React.createElement(ResponsiveGridAny, {
529
+ }, labelAlign ? {
530
+ labelAlign: labelAlign
531
+ } : {}, labelCol ? {
532
+ labelCol: labelCol
533
+ } : {}, globalSize ? {
534
+ size: globalSize
535
+ } : {}, formInitialProps, otherProps), hasContent ? /*#__PURE__*/React.createElement(ResponsiveGridAny, {
141
536
  className: "custom-form__grid",
142
- gap: spacing,
143
- columns: columns
537
+ device: "desktop",
538
+ gap: normalizedGap,
539
+ columns: fixedColumns
144
540
  }, formItemNodes, childrenNodes) : /*#__PURE__*/React.createElement("div", {
145
541
  className: "custom-form__empty"
146
- }, emptyContent), showSubmit || showReset ? /*#__PURE__*/React.createElement("div", {
147
- className: "custom-form__actions"
148
- }, showReset ? /*#__PURE__*/React.createElement(NextFormAny.Reset, _extends({
149
- className: "custom-form__reset"
150
- }, resetButtonProps), resetText) : null, showSubmit ? /*#__PURE__*/React.createElement(NextFormAny.Submit, _extends({
151
- className: "custom-form__submit",
152
- type: "primary",
153
- validate: submitValidate,
154
- onClick: handleSubmit
155
- }, submitButtonProps), submitText) : null) : null);
542
+ }, emptyContent), effectiveOperations.length > 0 ? /*#__PURE__*/React.createElement("div", {
543
+ className: "custom-form__actions",
544
+ style: {
545
+ justifyContent: alignJustifyMap[operationAlign] || 'center'
546
+ }
547
+ }, effectiveOperations.map(function (op, opIndex) {
548
+ // ── 重置按钮 ─────────────────────────────────────────────────────
549
+ if (op.action === 'reset') {
550
+ return /*#__PURE__*/React.createElement(NextFormAny.Reset, _extends({
551
+ key: opIndex,
552
+ type: op.type || 'normal',
553
+ onClick: onReset
554
+ }, op.buttonProps || {}), op.text);
555
+ }
556
+ // ── 提交按钮 ─────────────────────────────────────────────────────
557
+ if (op.action === 'submit') {
558
+ // 每个提交按钮独立决定是否校验:per-button > 全局 submitValidate
559
+ var btnValidate = op.submitValidate !== undefined ? op.submitValidate : submitValidate;
560
+ return /*#__PURE__*/React.createElement(NextFormAny.Submit, _extends({
561
+ key: opIndex,
562
+ type: op.type || 'primary',
563
+ validate: btnValidate,
564
+ onClick: function onClick(values, errors, field) {
565
+ return handleSubmit(values, errors, field, op.dataSource);
566
+ }
567
+ }, op.buttonProps || {}), op.text);
568
+ }
569
+ // ── 自定义按钮 ───────────────────────────────────────────────────
570
+ return /*#__PURE__*/React.createElement(ButtonAny, _extends({
571
+ key: opIndex,
572
+ type: op.type || 'normal',
573
+ onClick: op.onClick
574
+ }, op.buttonProps || {}), op.text);
575
+ })) : null);
156
576
  };
157
577
  CustomForm.displayName = 'CustomForm';
158
578
  export default CustomForm;
@@ -2,5 +2,5 @@
2
2
  * 自定义表单
3
3
  */
4
4
  import CustomForm from './custom-form';
5
- export type { CustomFormProps, CustomFormItemSchema, CustomFormItemType } from './custom-form';
5
+ export type { CustomFormProps, CustomFormItemSchema, CustomFormItemType, ComputedFields } from './custom-form';
6
6
  export { CustomForm };
@@ -14,9 +14,9 @@
14
14
 
15
15
  .custom-form__actions {
16
16
  display: flex;
17
- justify-content: center;
18
17
  gap: 12px;
19
18
  padding: 12px 0 0;
19
+ /* 对齐方式通过 style.justifyContent 动态注入,此处不再硬编码 center */
20
20
  }
21
21
 
22
22
  .custom-form__submit,