lu-lowcode-package-form 0.11.83 → 0.11.85
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/dist/index.cjs.js +271 -271
- package/dist/index.es.js +15265 -15190
- package/package.json +1 -1
- package/src/App.jsx +2 -2
- package/src/components/form-container/index.jsx +203 -22
package/package.json
CHANGED
package/src/App.jsx
CHANGED
@@ -109,7 +109,7 @@ function App() {
|
|
109
109
|
}
|
110
110
|
}
|
111
111
|
const setFormFields = () => {
|
112
|
-
formRef?.current?.setFieldsValue({ "__id": 1, "userselect": "1213131", "remark11": { "label": "选项1", "value": "1", "name": "1111", "table": "[{\"price\":1,\"num\":2},{\"price\":2,\"num\":2},{\"price\":3,\"num\":3},{\"price\":3,\"num\":3}]" }, "table2": [{}], "table": [{ "product_num1": "123", "product_sum1": "", "node_oclxmzswzti": "", "select2": "", "switch_table": false, "remark11": { "label": "选项2", "value": "2" }, "product_price12": "", "tianchong1": { "label": "选项1", "value": "1", "tianchong2": { "label": "选项2", "value": "2" }, "tcinput1": "1111" }, "tianchong2": { "label": "选项2", "value": "2", "tcinput1": "8989", "tcinput2": "2222" }, "tcinput1": "8989", "tcinput2": "2222", "tcinput3": "2222" }, { "product_num1": "213", "product_sum1": "", "node_oclxmzswzti": "", "select2": "", "switch_table": false, "datetime2": "2024-08-22 11:09:07", "product_price13": 1, "product_price14": 2, "product_price12": "", "remark11": { "label": "选项3", "value": "3" }, "product_price11": 3 }], "product_total_price": "0.00", "DeptSelect": ["leaf11"], "PostSelect": ["parent 1-1", "leaf11"], "searchuser": [{ "id": 2, "name": "2222", "label": "2222", "value": 2 }, { "id": 4, "name": "4444", "label": "4444", "value": 4 }], "product_price": "213", "product_num": "21", "product_num_range": [1, 22], "product_sum": "4473", "switch": false, "datetime": "2024-08-25", "datetime2": "2024-08-25", "datetime3": "", "datetime4": "2024-08-22 11:09:04", "remark12": JSON.stringify([{ "label": "选项1", "value": "1" }, { "label": "选项2", "value": "2" }]) })
|
112
|
+
formRef?.current?.setFieldsValue({ "__id": 1, "routeType":1, "userselect": "1213131", "remark11": { "label": "选项1", "value": "1", "name": "1111", "table": "[{\"price\":1,\"num\":2},{\"price\":2,\"num\":2},{\"price\":3,\"num\":3},{\"price\":3,\"num\":3}]" }, "table2": [{}], "table": [{ "product_num1": "123", "product_sum1": "", "node_oclxmzswzti": "", "select2": "", "switch_table": false, "remark11": { "label": "选项2", "value": "2" }, "product_price12": "", "tianchong1": { "label": "选项1", "value": "1", "tianchong2": { "label": "选项2", "value": "2" }, "tcinput1": "1111" }, "tianchong2": { "label": "选项2", "value": "2", "tcinput1": "8989", "tcinput2": "2222" }, "tcinput1": "8989", "tcinput2": "2222", "tcinput3": "2222" }, { "product_num1": "213", "product_sum1": "", "node_oclxmzswzti": "", "select2": "", "switch_table": false, "datetime2": "2024-08-22 11:09:07", "product_price13": 1, "product_price14": 2, "product_price12": "", "remark11": { "label": "选项3", "value": "3" }, "product_price11": 3 }], "product_total_price": "0.00", "DeptSelect": ["leaf11"], "PostSelect": ["parent 1-1", "leaf11"], "searchuser": [{ "id": 2, "name": "2222", "label": "2222", "value": 2 }, { "id": 4, "name": "4444", "label": "4444", "value": 4 }], "product_price": "213", "product_num": "21", "product_num_range": [1, 22], "product_sum": "4473", "switch": false, "datetime": "2024-08-25", "datetime2": "2024-08-25", "datetime3": "", "datetime4": "2024-08-22 11:09:04", "remark12": JSON.stringify([{ "label": "选项1", "value": "1" }, { "label": "选项2", "value": "2" }]) })
|
113
113
|
// formRef?.current?.setFieldsValue({"tianchong1":{"label":"选项1","value":"1"}, })
|
114
114
|
}
|
115
115
|
const handleCols = () => {
|
@@ -189,7 +189,7 @@ function App() {
|
|
189
189
|
<div className='fw-[960px] frounded fbg-slate-50 fflex fflex-col fitems-center fpb-10'>
|
190
190
|
|
191
191
|
|
192
|
-
<FormContainerWrapper cols={cols} key={"formc"} className="" ref={formRef} >
|
192
|
+
<FormContainerWrapper denyEdit={true} cols={cols} key={"formc"} className="" ref={formRef} >
|
193
193
|
|
194
194
|
<Field.WithSingleSelect
|
195
195
|
ref={testRef}
|
@@ -50,7 +50,7 @@ function batchElements(elements, groupSize, dmap) {
|
|
50
50
|
}
|
51
51
|
|
52
52
|
|
53
|
-
const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) => {
|
53
|
+
const FormContainer = forwardRef(({ cols = 1, children, mode = "view", denyEdit = false }, ref) => {
|
54
54
|
const [form] = Form.useForm();
|
55
55
|
const formContentRef = React.useRef(null);
|
56
56
|
const [formContent, setFormContent] = React.useState(null);
|
@@ -114,6 +114,8 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
114
114
|
setFieldsValue: (values) => {
|
115
115
|
lockStatus.current = 1;
|
116
116
|
let formData = { ...values, __id: values?.id }
|
117
|
+
|
118
|
+
// denyEdit 模式下仍需要记录字段变化用于显示/隐藏逻辑
|
117
119
|
for (let key in values) {
|
118
120
|
changedFieldsState.current[key] = { name: key, value: values[key] }
|
119
121
|
if (dependencyMap.current.has(key) && dependencyMap.current.get(key).componentName == "Field.Table" && Array.isArray(values[key])) {
|
@@ -126,12 +128,19 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
126
128
|
}
|
127
129
|
}
|
128
130
|
form.setFieldsValue(formData)
|
129
|
-
|
131
|
+
|
132
|
+
// denyEdit 模式下跳过复杂的级联处理,但保留简单的显示/隐藏处理
|
133
|
+
if (denyEdit) {
|
134
|
+
// 只处理显示/隐藏逻辑,不处理填充和数据获取
|
135
|
+
debounceHandleFieldsChange_ReadOnly()
|
136
|
+
} else {
|
137
|
+
debounceHandleFieldsChange()
|
138
|
+
}
|
130
139
|
},
|
131
140
|
initializeFieldVisibility: (reloadFields) => {
|
132
141
|
initializeFieldVisibility(reloadFields);
|
133
142
|
},
|
134
|
-
}), []);
|
143
|
+
}), [denyEdit]);
|
135
144
|
|
136
145
|
// 添加节流后的 initializeFormRender
|
137
146
|
const throttledInitializeFormRender = React.useCallback(
|
@@ -162,8 +171,15 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
162
171
|
}
|
163
172
|
|
164
173
|
const lastFormValues = React.useRef(null);
|
174
|
+
// 统一使用点分隔的字符串格式
|
175
|
+
const normalizeFieldPath = (fieldPath) => {
|
176
|
+
if (Array.isArray(fieldPath)) {
|
177
|
+
return fieldPath.map(item => typeof item === "string" ? item : item.toString()).join(".");
|
178
|
+
}
|
179
|
+
return fieldPath;
|
180
|
+
};
|
165
181
|
const getLastFieldValue = (path) => {
|
166
|
-
return lastFormValues.current?.[path]
|
182
|
+
return lastFormValues.current?.[normalizeFieldPath(path)]
|
167
183
|
// let current = lastFormValues.current;
|
168
184
|
// for (let i = 0; i < path.length; i++) {
|
169
185
|
// if (current == null) {
|
@@ -303,6 +319,54 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
303
319
|
|
304
320
|
return needRefresh;
|
305
321
|
};
|
322
|
+
|
323
|
+
// denyEdit 模式专用函数 - 只处理显示/隐藏逻辑
|
324
|
+
const handleFieldsWithVisibleOnly = async (identifier, fieldValues, init = false, fieldId = null) => {
|
325
|
+
if (mode == "desgin") {
|
326
|
+
console.log("设计模式下不进行字段级联计算")
|
327
|
+
return false
|
328
|
+
}
|
329
|
+
|
330
|
+
console.log("handleFieldsWithVisibleOnly identifier", identifier)
|
331
|
+
let needRefresh = false;
|
332
|
+
let parentIdentifier = [];
|
333
|
+
if (Array.isArray(identifier)) {
|
334
|
+
parentIdentifier = [...(identifier.slice(0, -1))]
|
335
|
+
identifier = identifier.filter(item => typeof item == "string").join(".")
|
336
|
+
}
|
337
|
+
|
338
|
+
const currentFieldId = fieldId || identifier;
|
339
|
+
|
340
|
+
try {
|
341
|
+
if (dependencyMap.current.has(identifier)) {
|
342
|
+
const dependent = dependencyMap.current.get(identifier)
|
343
|
+
const dependentChildren = dependent.children;
|
344
|
+
|
345
|
+
// 只处理显示/隐藏逻辑,跳过填充规则
|
346
|
+
for (let index = 0; index < dependentChildren.length; index++) {
|
347
|
+
const child = dependentChildren[index];
|
348
|
+
|
349
|
+
// 处理 withVisibleFunc
|
350
|
+
if (child.component.props.withVisibleFunc && typeof child.component.props.withVisibleFunc === 'function') {
|
351
|
+
let needRefresh_ = handleFieldsVisibleFunc(fieldValues, child, parentIdentifier)
|
352
|
+
needRefresh = needRefresh || needRefresh_
|
353
|
+
}
|
354
|
+
|
355
|
+
// 处理 withVisible(但跳过数据获取部分)
|
356
|
+
if (child.component.props.withVisible) {
|
357
|
+
let needRefresh_ = await handleFieldsVisibleReadOnly(fieldValues, child, parentIdentifier, dependent?.componentName)
|
358
|
+
needRefresh = needRefresh || needRefresh_
|
359
|
+
}
|
360
|
+
|
361
|
+
// 跳过 withFill 处理
|
362
|
+
}
|
363
|
+
}
|
364
|
+
} catch (error) {
|
365
|
+
console.log("handleFieldsWithVisibleOnly error", error)
|
366
|
+
}
|
367
|
+
|
368
|
+
return needRefresh;
|
369
|
+
};
|
306
370
|
const removeLastFieldsValues = (name, isTable = false) => {
|
307
371
|
if (!lastFormValues.current) return
|
308
372
|
if (isTable) {
|
@@ -310,11 +374,11 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
310
374
|
for (let index = 0; index < lastFormValuesKeys.length; index++) {
|
311
375
|
const key = lastFormValuesKeys[index];
|
312
376
|
if (key.includes(`${name},`)) {
|
313
|
-
delete lastFormValues.current[key]
|
377
|
+
delete lastFormValues.current[normalizeFieldPath(key)]
|
314
378
|
}
|
315
379
|
}
|
316
380
|
}
|
317
|
-
else delete lastFormValues.current[name]
|
381
|
+
else delete lastFormValues.current[normalizeFieldPath(name)]
|
318
382
|
}
|
319
383
|
|
320
384
|
const recordFieldChange = (fieldName, fieldValue) => {
|
@@ -421,8 +485,12 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
421
485
|
changedFields[target] = { name: Array.isArray(target) ? target : [target], value: setValue };
|
422
486
|
}
|
423
487
|
if (rule?.type == 1) {
|
488
|
+
console.log("rule?.type == 1", target)
|
489
|
+
console.log("rule?.type == 1", setValue)
|
490
|
+
console.log("rule?.type == 1 current_identifier", current_identifier)
|
424
491
|
form.setFieldValue(target, undefined);
|
425
492
|
}
|
493
|
+
console.log("form.setFieldValue(target, setValue) " +target, setValue)
|
426
494
|
form.setFieldValue(target, setValue)
|
427
495
|
|
428
496
|
// 处理完当前字段后从依赖路径中移除
|
@@ -549,6 +617,61 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
549
617
|
}
|
550
618
|
return needRefresh
|
551
619
|
}
|
620
|
+
|
621
|
+
// denyEdit 模式专用 - 处理级联显示隐藏(跳过数据获取)
|
622
|
+
const handleFieldsVisibleReadOnly = async (fieldValues, child, parentIdentifier, componentName) => {
|
623
|
+
let needRefresh = false;
|
624
|
+
const withFill = child?.component?.props.withVisible;
|
625
|
+
let withFillIndex = 0
|
626
|
+
let withFillGroup = ""
|
627
|
+
let childIdentifier = child.identifier;
|
628
|
+
|
629
|
+
// 跳过数据获取部分,使用空数组作为 withDatas
|
630
|
+
let withDatas = [];
|
631
|
+
|
632
|
+
// 构造计算公式(但不获取远程数据)
|
633
|
+
let formula;
|
634
|
+
if (withFill.value && withFill.value.length > 0) {
|
635
|
+
formula = withFill.value.map(item => {
|
636
|
+
let result = "";
|
637
|
+
const { insert, attributes } = item
|
638
|
+
if (typeof insert !== "string") {
|
639
|
+
if (insert?.span && attributes && attributes.tagKey && attributes.id) {
|
640
|
+
result = getParamValue(attributes.tagKey, attributes.id, fieldValues, withDatas)
|
641
|
+
if (Array.isArray(result)) {
|
642
|
+
if (Array.isArray(childIdentifier) && result.length > withFillIndex) {
|
643
|
+
result = result[withFillIndex]
|
644
|
+
}
|
645
|
+
if (typeof result === "object" && result !== null)
|
646
|
+
result = JSON.stringify(result)
|
647
|
+
}
|
648
|
+
else if (typeof result === "object" && result !== null) {
|
649
|
+
result = JSON.stringify(result)
|
650
|
+
}
|
651
|
+
else if (result.length > 0) result = `"${result}"`
|
652
|
+
}
|
653
|
+
}
|
654
|
+
else result = insert
|
655
|
+
return result
|
656
|
+
})
|
657
|
+
}
|
658
|
+
|
659
|
+
if (dependencyMap.current.has(childIdentifier)) {
|
660
|
+
const childData = dependencyMap.current.get(childIdentifier);
|
661
|
+
if (formula && formula.length > 0) {
|
662
|
+
const formulaResult = (evalFormula(formula) == "true");
|
663
|
+
console.log(`${childIdentifier} 只读模式计算公式:`, formula)
|
664
|
+
console.log(`${childIdentifier} 只读模式计算结果:`, formulaResult)
|
665
|
+
if (childData.show != formulaResult) {
|
666
|
+
childData.show = formulaResult;
|
667
|
+
dependencyMap.current.set(childIdentifier, childData);
|
668
|
+
needRefresh = true;
|
669
|
+
}
|
670
|
+
}
|
671
|
+
}
|
672
|
+
return needRefresh
|
673
|
+
}
|
674
|
+
|
552
675
|
// 处理级联数据源
|
553
676
|
// 处理级联填充
|
554
677
|
const handleFieldsWithFill = async (fieldValues, child, parentIdentifier, componentName, sourceFieldId) => {
|
@@ -725,10 +848,10 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
725
848
|
dependencyGraphRef.current.startNewCycle();
|
726
849
|
|
727
850
|
// 创建当前变更的快照,避免处理过程中的并发修改
|
728
|
-
const currentChanges = {...changedFieldsState.current};
|
851
|
+
const currentChanges = { ...changedFieldsState.current };
|
729
852
|
// 立即重置变更状态,为新的变更做准备
|
730
853
|
changedFieldsState.current = {};
|
731
|
-
|
854
|
+
|
732
855
|
const fieldValues = form.getFieldsValue();
|
733
856
|
const lockStatus_ = lockStatus.current;
|
734
857
|
lockStatus.current = 0
|
@@ -758,7 +881,7 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
758
881
|
let needRefresh_ = await handleFieldsWith(field.name, fieldValues, false, fieldId);
|
759
882
|
needRefresh = needRefresh || needRefresh_;
|
760
883
|
}
|
761
|
-
lastFormValues.current[field.name] = field.value;
|
884
|
+
lastFormValues.current[normalizeFieldPath(field.name)] = field.value;
|
762
885
|
}
|
763
886
|
} catch (error) {
|
764
887
|
console.log("debounceHandleFieldsChange error", error)
|
@@ -769,25 +892,77 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
769
892
|
updateFormContent();
|
770
893
|
}
|
771
894
|
}, delay);
|
772
|
-
}, []);
|
895
|
+
}, [denyEdit]);
|
896
|
+
|
897
|
+
// denyEdit 模式专用的防抖处理函数 - 只处理显示/隐藏,不处理填充和数据获取
|
898
|
+
const debounceHandleFieldsChange_ReadOnly = React.useCallback(() => {
|
899
|
+
if (timeoutRef.current) {
|
900
|
+
clearTimeout(timeoutRef.current);
|
901
|
+
}
|
902
|
+
|
903
|
+
// 只读模式使用更短的延迟
|
904
|
+
const delay = 50;
|
905
|
+
|
906
|
+
timeoutRef.current = setTimeout(async () => {
|
907
|
+
const currentChanges = { ...changedFieldsState.current };
|
908
|
+
changedFieldsState.current = {};
|
909
|
+
|
910
|
+
const fieldValues = form.getFieldsValue();
|
911
|
+
let needRefresh = false;
|
912
|
+
if (!lastFormValues.current) lastFormValues.current = {}
|
913
|
+
|
914
|
+
// 创建已处理字段集合,用于避免多次处理同一字段
|
915
|
+
const processedFields = new Set();
|
916
|
+
for (let key in currentChanges) {
|
917
|
+
try {
|
918
|
+
let field = currentChanges[key];
|
919
|
+
if (!isEqual(field.value || "", getLastFieldValue(field.name) || "")) {
|
920
|
+
// 获取字段标识符(字符串形式)
|
921
|
+
const fieldId = Array.isArray(field.name)
|
922
|
+
? field.name.map(item => typeof item == "string" ? item : item.toString()).join(".")
|
923
|
+
: field.name;
|
924
|
+
|
925
|
+
// 跳过已处理的字段
|
926
|
+
if (processedFields.has(fieldId)) {
|
927
|
+
console.log("跳过已处理的字段 processedFields", fieldId)
|
928
|
+
continue;
|
929
|
+
}
|
930
|
+
processedFields.add(fieldId);
|
931
|
+
|
932
|
+
// 只处理显示/隐藏逻辑,不处理填充和数据获取
|
933
|
+
let needRefresh_ = await handleFieldsWithVisibleOnly(field.name, fieldValues, false, fieldId);
|
934
|
+
needRefresh = needRefresh || needRefresh_;
|
935
|
+
|
936
|
+
lastFormValues.current[normalizeFieldPath(field.name)] = field.value;
|
937
|
+
}
|
938
|
+
} catch (error) {
|
939
|
+
console.log("debounceHandleFieldsChange_ReadOnly error", error)
|
940
|
+
}
|
941
|
+
}
|
942
|
+
if (needRefresh) {
|
943
|
+
console.log("needRefresh (ReadOnly mode)", needRefresh)
|
944
|
+
updateFormContent();
|
945
|
+
}
|
946
|
+
}, delay);
|
947
|
+
}, [denyEdit]);
|
773
948
|
|
774
949
|
const handleFieldsChange = React.useCallback((changedFields) => {
|
775
|
-
console.log("handleFieldsChange (disabled, using handleValuesChange instead)", JSON.stringify(changedFields))
|
950
|
+
// console.log("handleFieldsChange (disabled, using handleValuesChange instead)", JSON.stringify(changedFields))
|
776
951
|
// 已禁用,改为使用 handleValuesChange 来处理字段变更
|
777
952
|
// 这样可以避免重复处理和多余的触发
|
778
953
|
}, []);
|
779
954
|
const handleValuesChange = React.useCallback((changedValues, allValues) => {
|
780
955
|
console.log("handleValuesChange changedValues", JSON.stringify(changedValues))
|
781
|
-
console.log("handleValuesChange allValues", JSON.stringify(allValues))
|
782
|
-
|
956
|
+
// console.log("handleValuesChange allValues", JSON.stringify(allValues))
|
957
|
+
|
783
958
|
// 将 changedValues 转换为类似 handleFieldsChange 的格式
|
784
959
|
const convertToFieldsFormat = (values, parentPath = []) => {
|
785
960
|
const fieldsArray = [];
|
786
|
-
|
961
|
+
|
787
962
|
for (let fieldName in values) {
|
788
963
|
const fieldValue = values[fieldName];
|
789
964
|
const currentPath = [...parentPath, fieldName];
|
790
|
-
|
965
|
+
|
791
966
|
// 处理数组类型(如table字段)
|
792
967
|
if (Array.isArray(fieldValue)) {
|
793
968
|
fieldValue.forEach((item, index) => {
|
@@ -822,14 +997,14 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
822
997
|
});
|
823
998
|
}
|
824
999
|
}
|
825
|
-
|
1000
|
+
|
826
1001
|
return fieldsArray;
|
827
1002
|
};
|
828
|
-
|
1003
|
+
|
829
1004
|
// 转换为类似 handleFieldsChange 的格式
|
830
1005
|
const convertedFields = convertToFieldsFormat(changedValues);
|
831
1006
|
console.log("handleValuesChange converted to fields format", JSON.stringify(convertedFields));
|
832
|
-
|
1007
|
+
|
833
1008
|
// 使用转换后的数据,复用原有的处理逻辑
|
834
1009
|
if (convertedFields.length > 0) {
|
835
1010
|
convertedFields.forEach(field => {
|
@@ -837,12 +1012,18 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
837
1012
|
changedFieldsState.current[field.name] = field;
|
838
1013
|
}
|
839
1014
|
});
|
1015
|
+
|
1016
|
+
console.log("handleValuesChange changedFieldsState", JSON.parse(JSON.stringify(changedFieldsState.current)));
|
840
1017
|
|
841
|
-
|
842
|
-
|
1018
|
+
// denyEdit 模式下使用专用的处理函数
|
1019
|
+
if (denyEdit) {
|
1020
|
+
debounceHandleFieldsChange_ReadOnly();
|
1021
|
+
} else {
|
1022
|
+
debounceHandleFieldsChange();
|
1023
|
+
}
|
843
1024
|
}
|
844
|
-
}, []);
|
845
|
-
|
1025
|
+
}, [denyEdit]);
|
1026
|
+
|
846
1027
|
const getTableWithIds = (ids) => {
|
847
1028
|
let withAllIds = []
|
848
1029
|
ids.forEach(id => {
|