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