lu-lowcode-package-form 0.9.31 → 0.9.32
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 +118 -118
- package/dist/index.es.js +8825 -8853
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/App.jsx +1 -0
- package/src/components/field/base.jsx +18 -11
- package/src/components/field/checkbox/checkbox-tree.jsx +0 -1
- package/src/components/field/table/index copy 2.jsx +268 -0
- package/src/components/field/table/index copy.jsx +268 -0
- package/src/components/field/table/index.jsx +80 -247
- package/src/components/form-container/index copy.jsx +302 -0
- package/src/components/form-container/index.jsx +72 -41
- package/src/components/form-container/layout/form-row.jsx +0 -1
|
@@ -1,268 +1,101 @@
|
|
|
1
|
-
import React, { useEffect, useState
|
|
2
|
-
import { Button } from "antd";
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { Button, Form, Input } from "antd";
|
|
3
3
|
import { DeleteOutlined } from "@ant-design/icons";
|
|
4
|
-
import {
|
|
5
|
-
import { evalFormula } from "../../../utils/formula";
|
|
4
|
+
import { BaseWrapper } from "../base.jsx"
|
|
6
5
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
setSWidth(width);
|
|
11
|
-
}, [width]);
|
|
12
|
-
return <div className="fflex-1" style={{ minWidth: `${sWidth}px` }} {...props}>
|
|
13
|
-
{children}
|
|
14
|
-
</div>
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const TableAction = ({ label, subTableIndex, children, ...props }) => {
|
|
18
|
-
return <div className="">
|
|
6
|
+
const TableAction = ({ label, subTableIndex, children, subTableHead = false, ...props }) => {
|
|
7
|
+
return <div className="fw-12">
|
|
19
8
|
<div className="frelative fw-full fh-full fflex fflex-col foverflow-hidden">
|
|
20
|
-
{label &&
|
|
21
|
-
<div className="fw-full fflex-1 fflex fitems-center fjustify-center fp-2 fbox-border ">
|
|
9
|
+
{label && subTableHead && <div className='fh-12 ffont-semibold fbg-[#fafafa] ftext-sm fflex fflex-nowrap ftext-nowrap fjustify-between fitems-center fpx-2 fborder-b'>{label}</div>}
|
|
10
|
+
{!subTableHead && <div className="fw-full fflex-1 fflex fitems-center fjustify-center fp-2 fbox-border ">
|
|
22
11
|
{children}
|
|
23
12
|
</div>
|
|
13
|
+
}
|
|
24
14
|
</div>
|
|
25
15
|
</div>
|
|
26
16
|
}
|
|
27
17
|
|
|
28
|
-
const Table = ({ children, value, onChange, ...props }) => {
|
|
29
|
-
const [rows, setRows] = useState([{}]);
|
|
30
|
-
const prevRowsRef = useRef(rows);
|
|
31
|
-
const dependencyMap = useRef(new Map());
|
|
32
|
-
const [updateField, setUpdateField] = useState({});
|
|
33
|
-
const tableId = props.componentId || props.__id;
|
|
34
|
-
const setPrevRows = (newValue) => {
|
|
35
|
-
setRows(newValue);
|
|
36
|
-
prevRowsRef.current = newValue;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
console.log("value useEffect ", JSON.stringify(value));
|
|
41
|
-
if (value && typeof value === "string") {
|
|
42
|
-
try {
|
|
43
|
-
value = JSON.parse(value);
|
|
44
|
-
onChange(value);
|
|
45
|
-
} catch (error) { }
|
|
46
|
-
}
|
|
47
|
-
if (value && Array.isArray(value) && !isEqual(prevRowsRef.current, value)) {
|
|
48
|
-
console.log("useEffect setRows");
|
|
49
|
-
setPrevRows(value);
|
|
50
|
-
}
|
|
51
|
-
}, [value]);
|
|
52
|
-
|
|
53
|
-
useEffect(() => {
|
|
54
|
-
console.log("children useEffect ",children);
|
|
55
|
-
initializeDependencyMap();
|
|
56
|
-
}, [children]);
|
|
57
|
-
|
|
58
|
-
const initializeDependencyMap = useCallback(() => {
|
|
59
|
-
dependencyMap.current.clear();
|
|
60
|
-
const childrenArray = React.Children.toArray(children);
|
|
61
|
-
childrenArray.forEach(child => {
|
|
62
|
-
const { componentId, __id, ...props } = child.props;
|
|
63
|
-
const identifier = `${tableId}.${(componentId || __id)}`;
|
|
64
|
-
|
|
65
|
-
dependencyMap.current.set(identifier, {
|
|
66
|
-
children: childrenArray.filter(item => item.props.withId === identifier || item.props.withIds?.includes(identifier)),
|
|
67
|
-
show: true,
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
initializeFieldVisibility();
|
|
71
|
-
}, [children, tableId]);
|
|
72
|
-
|
|
73
|
-
const handleRowValues = useCallback((rowValues) => {
|
|
74
|
-
const result = {};
|
|
75
|
-
for (let key in rowValues) {
|
|
76
|
-
result[`${tableId}.${key}`] = rowValues[key] || '';
|
|
77
|
-
}
|
|
78
|
-
return result;
|
|
79
|
-
}, [tableId]);
|
|
80
|
-
|
|
81
|
-
const initializeFieldVisibility = useCallback(() => {
|
|
82
|
-
rows.forEach((row, rowIndex) => {
|
|
83
|
-
const fieldValues = handleRowValues(row);
|
|
84
|
-
for (let key of dependencyMap.current.keys()) {
|
|
85
|
-
handleFieldsWith(key, fieldValues, rowIndex);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}, [rows, handleRowValues]);
|
|
89
|
-
|
|
90
|
-
const handleFieldsWith = useCallback((identifier, fieldValues, rowIndex) => {
|
|
91
|
-
let needRefresh = false;
|
|
92
|
-
const fullIdentifier = `${tableId}.${identifier}`;
|
|
93
|
-
if (dependencyMap.current.has(fullIdentifier)) {
|
|
94
|
-
const dependentChildren = dependencyMap.current.get(fullIdentifier).children;
|
|
95
|
-
dependentChildren.forEach(child => {
|
|
96
|
-
if (child.props.withFunc && typeof child.props.withFunc === 'function') {
|
|
97
|
-
needRefresh = handleFieldsVisible(fieldValues, child);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (child.props.withFill) {
|
|
101
|
-
handleFieldsWithFill(fieldValues, child, rowIndex);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
return needRefresh;
|
|
106
|
-
}, [tableId, rows]);
|
|
107
|
-
|
|
108
|
-
const handleFieldsVisible = useCallback((fieldValues, child) => {
|
|
109
|
-
let needRefresh = false;
|
|
110
|
-
const childShouldBeVisible = child.props.withFunc(fieldValues);
|
|
111
|
-
const childIdentifier = child.props.componentId || child.props.__id;
|
|
112
|
-
if (dependencyMap.current.has(childIdentifier)) {
|
|
113
|
-
const childData = dependencyMap.current.get(childIdentifier);
|
|
114
|
-
if (childData.show !== childShouldBeVisible) {
|
|
115
|
-
childData.show = childShouldBeVisible;
|
|
116
|
-
dependencyMap.current.set(childIdentifier, childData);
|
|
117
|
-
needRefresh = true;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return needRefresh;
|
|
121
|
-
}, []);
|
|
122
|
-
|
|
123
|
-
const handleFieldsWithFill = useCallback(async (fieldValues, child, rowIndex) => {
|
|
124
|
-
const withFill = child.props.withFill;
|
|
125
|
-
const withDataFetch = child.props.withDataFetch;
|
|
126
|
-
|
|
127
|
-
let withDatas = [];
|
|
128
|
-
if (withFill?.withData && withFill?.withData.length > 0 && withDataFetch && typeof withDataFetch === 'function') {
|
|
129
|
-
for (let index = 0; index < withFill?.withData.length; index++) {
|
|
130
|
-
const element = withFill?.withData[index];
|
|
131
|
-
let params = {}
|
|
132
|
-
params.tableName = element.withTable.table_name;
|
|
133
|
-
params.filter = {};
|
|
134
|
-
for (let index = 0; index < element.withCondition.length; index++) {
|
|
135
|
-
const { value: condition_value, column: condition_column } = element.withCondition[index];
|
|
136
|
-
params.filter[condition_column.column_name] = getParamValue(condition_value.group_key, condition_value.field_key, fieldValues, withDatas);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const response = await withDataFetch(params);
|
|
140
|
-
if (response.code === 0 && response.data.list) {
|
|
141
|
-
withDatas.push({
|
|
142
|
-
id: element.id,
|
|
143
|
-
data: response.data.list
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
let formula;
|
|
150
|
-
if (withFill.value && withFill.value.length > 0) {
|
|
151
|
-
formula = withFill.value.map(item => {
|
|
152
|
-
let result = "";
|
|
153
|
-
const { insert, attributes } = item;
|
|
154
|
-
if (typeof insert !== "string") {
|
|
155
|
-
if (insert?.span && attributes && attributes.tagKey && attributes.id) {
|
|
156
|
-
result = getParamValue(attributes.tagKey, attributes.id, fieldValues, withDatas);
|
|
157
|
-
if(result) result = `"${result}"`
|
|
158
|
-
}
|
|
159
|
-
} else {
|
|
160
|
-
result = insert;
|
|
161
|
-
}
|
|
162
|
-
return result;
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
console.log("formula", formula);
|
|
166
|
-
if (formula && formula.length > 0) {
|
|
167
|
-
const childIdentifier = child.props.componentId || child.props.__id;
|
|
168
|
-
const formulaResult = evalFormula(formula);
|
|
169
|
-
console.log("formulaResult", formulaResult);
|
|
170
|
-
console.log("handleFieldsWithFill setRows");
|
|
171
|
-
const newRows = [...rows]
|
|
172
|
-
newRows[rowIndex][childIdentifier] = formulaResult;
|
|
173
|
-
setPrevRows(newRows)
|
|
174
|
-
}
|
|
175
|
-
}, [rows])
|
|
176
|
-
|
|
177
|
-
const getParamValue = useCallback((tagKey, id, fieldValues, withDatas) => {
|
|
178
|
-
let result = "";
|
|
179
|
-
if (tagKey === "fieldsValue") result = fieldValues?.[id] || "";
|
|
180
|
-
else {
|
|
181
|
-
let withData = withDatas.find(item => item.id === tagKey);
|
|
182
|
-
if (withData && withData.data && withData.data.length > 0) {
|
|
183
|
-
result = withData.data[0]?.[id] || "";
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return result;
|
|
187
|
-
}, []);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const handleInputChange = useCallback((rowIndex, childIndex, e) => {
|
|
192
|
-
console.log(e)
|
|
193
|
-
const newRows = [...rows];
|
|
194
|
-
newRows[rowIndex] = {
|
|
195
|
-
...newRows[rowIndex],
|
|
196
|
-
[childIndex]: e?.target?.value || e || '',
|
|
197
|
-
};
|
|
198
|
-
console.log("handleInputChange setRows")
|
|
199
|
-
setPrevRows(newRows);
|
|
200
|
-
|
|
201
|
-
setUpdateField({
|
|
202
|
-
rowIndex: rowIndex,
|
|
203
|
-
identifier: childIndex,
|
|
204
|
-
value: handleRowValues(newRows[rowIndex]),
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
}, [rows, handleFieldsWith, handleRowValues, onChange]);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const handleDeleteRow = (rowIndex) => {
|
|
211
|
-
const newRows = [...rows];
|
|
212
|
-
newRows.splice(rowIndex, 1);
|
|
213
|
-
console.log("handleDeleteRow setRows")
|
|
214
|
-
setPrevRows(newRows);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const addRow = () => {
|
|
218
|
-
console.log("addRow setRows")
|
|
219
|
-
setPrevRows([...rows, {}]);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
useEffect(() => {
|
|
223
|
-
console.log("rows changed rows", JSON.stringify(prevRowsRef.current));
|
|
224
|
-
console.log("rows changed value", JSON.stringify(value));
|
|
225
|
-
if (isEqual(prevRowsRef.current, value)) return;
|
|
226
|
-
console.log("noreq")
|
|
227
|
-
typeof onChange === "function" && onChange(prevRowsRef.current);
|
|
228
|
-
}, [rows]);
|
|
229
18
|
|
|
19
|
+
const TableCol = ({ children, width, ...props }) => {
|
|
20
|
+
const [sWidth, setSWidth] = useState(0);
|
|
230
21
|
useEffect(() => {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
22
|
+
setSWidth(width);
|
|
23
|
+
}, [width]);
|
|
24
|
+
return <div className="fflex-1 fpx-1" style={{ minWidth: `${sWidth}px` }} {...props}>
|
|
25
|
+
{children}
|
|
26
|
+
</div>
|
|
27
|
+
}
|
|
236
28
|
|
|
237
|
-
|
|
238
|
-
|
|
29
|
+
const Table = ({ children, ...props }) => {
|
|
30
|
+
const name = props.componentId || props.__id
|
|
31
|
+
const rules = []
|
|
32
|
+
if (props.isRequired)
|
|
33
|
+
rules.push({ required: true, message: `子表[${props.label}]必须填写` });
|
|
34
|
+
return <Form.List name={name} rules={rules}>
|
|
35
|
+
{(fields, { add, remove }) => (
|
|
239
36
|
<div className="fw-full frelative fmin-h-20 foverflow-x-auto">
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
37
|
+
<div key={`tableHead`} className="fborder-b fflex flex-nowrap fmin-w-full ">
|
|
38
|
+
{React.Children.map(children, (child, childIndex) => {
|
|
39
|
+
return <TableCol width={150} key={`row_${0}_col_${childIndex}`}>
|
|
40
|
+
{React.cloneElement(child, {
|
|
41
|
+
key: `row_${0}_child_${childIndex}`,
|
|
42
|
+
subTable: true,
|
|
43
|
+
subTableHead: true
|
|
44
|
+
})}
|
|
45
|
+
</TableCol>
|
|
46
|
+
})}
|
|
47
|
+
<TableAction subTableHead={true} key={`row_${0}_action`} subTable={true} subTableIndex={0} label={"操作"}>
|
|
48
|
+
</TableAction>
|
|
49
|
+
</div>
|
|
50
|
+
{fields.map((field, index) => (
|
|
51
|
+
<div key={field.key} className="fborder-b fflex flex-nowrap fmin-w-full ">
|
|
243
52
|
{React.Children.map(children, (child, childIndex) => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
53
|
+
let { props } = child;
|
|
54
|
+
const col_id = child?.props?.componentId || child?.props?.__id || childIndex;
|
|
55
|
+
if (field?.[col_id] === undefined) field[col_id] = "";
|
|
56
|
+
const rules = []
|
|
57
|
+
if (props.isRequired)
|
|
58
|
+
rules.push({ required: true, message: `${props.label}必须填写` });
|
|
59
|
+
if (props.rules)
|
|
60
|
+
if (Array.isArray(props.rules)) {
|
|
61
|
+
const pattern = props.rules.join("|")
|
|
62
|
+
rules.push({ pattern: new RegExp(pattern), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
rules.push({ pattern: new RegExp(props.rules), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return <TableCol width={150} key={`row_${index}_col_${childIndex}`}>
|
|
69
|
+
<Form.Item
|
|
70
|
+
style={{ marginBottom: 0 }}
|
|
71
|
+
label=""
|
|
72
|
+
name={[field.name, col_id]}
|
|
73
|
+
rules={rules}
|
|
74
|
+
>
|
|
75
|
+
{React.cloneElement(child, {
|
|
76
|
+
key: `row_${index}_child_${childIndex}`,
|
|
77
|
+
subTable: true,
|
|
78
|
+
subTableIndex: index,
|
|
79
|
+
})}
|
|
80
|
+
</Form.Item>
|
|
254
81
|
</TableCol>
|
|
255
82
|
})}
|
|
256
|
-
<TableAction key={`row_${
|
|
257
|
-
<DeleteOutlined className="fcursor-pointer" onClick={() =>
|
|
83
|
+
<TableAction key={`row_${index}_action`} subTable={true} subTableIndex={index} label={"操作"}>
|
|
84
|
+
<DeleteOutlined className="fcursor-pointer" onClick={() => remove(index)} />
|
|
258
85
|
</TableAction>
|
|
259
86
|
</div>
|
|
260
87
|
))}
|
|
88
|
+
<Button onClick={() => add()} className="fmy-2">新增一行</Button>
|
|
261
89
|
</div>
|
|
262
|
-
|
|
263
|
-
|
|
90
|
+
)}
|
|
91
|
+
</Form.List>
|
|
92
|
+
}
|
|
93
|
+
const TableWrapper = (props) => {
|
|
94
|
+
return (
|
|
95
|
+
<BaseWrapper {...props} higLabel={true} >
|
|
96
|
+
<Table {...props} />
|
|
97
|
+
</BaseWrapper>
|
|
264
98
|
);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
export
|
|
268
|
-
export { TableCol, TableAction };
|
|
99
|
+
}
|
|
100
|
+
export default TableWrapper;
|
|
101
|
+
export { TableCol, TableAction };
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import React, { forwardRef, useEffect } from "react";
|
|
2
|
+
import { Form, Row, Col, message } from "antd";
|
|
3
|
+
|
|
4
|
+
import { debounce } from 'lodash';
|
|
5
|
+
import { evalFormula } from '../../utils/formula'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
function batchElements(elements, groupSize) {
|
|
9
|
+
const groupedElements = [];
|
|
10
|
+
let tempArray = [];
|
|
11
|
+
|
|
12
|
+
const fillWithReactElement = (size, array) => {
|
|
13
|
+
const missingElementsCount = size - array.length;
|
|
14
|
+
array.push(...new Array(missingElementsCount).fill(React.createElement('div')));
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
for (const element of elements) {
|
|
18
|
+
const { _componentName } = element?.props || {};
|
|
19
|
+
const componentName = element.type?.displayName || _componentName;
|
|
20
|
+
if (componentName && componentName.startsWith('Layout.')) {
|
|
21
|
+
if (tempArray.length > 0) {
|
|
22
|
+
fillWithReactElement(groupSize, tempArray);
|
|
23
|
+
groupedElements.push(tempArray);
|
|
24
|
+
tempArray = [];
|
|
25
|
+
}
|
|
26
|
+
groupedElements.push([element]);
|
|
27
|
+
} else {
|
|
28
|
+
tempArray.push(element);
|
|
29
|
+
if (tempArray.length === groupSize) {
|
|
30
|
+
groupedElements.push(tempArray);
|
|
31
|
+
tempArray = [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (tempArray.length > 0) {
|
|
37
|
+
fillWithReactElement(groupSize, tempArray);
|
|
38
|
+
groupedElements.push(tempArray);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return groupedElements;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) => {
|
|
46
|
+
const [form] = Form.useForm();
|
|
47
|
+
const [formContent, setFormContent] = React.useState(null);
|
|
48
|
+
const dependencyMap = React.useRef(null);
|
|
49
|
+
|
|
50
|
+
React.useImperativeHandle(ref, () => ({
|
|
51
|
+
formRef: form,
|
|
52
|
+
initializeFieldVisibility,
|
|
53
|
+
}), []);
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
initializeDependencyMap();
|
|
57
|
+
setFormContent(renderChildren());
|
|
58
|
+
}, [children, cols]);
|
|
59
|
+
|
|
60
|
+
const initializeDependencyMap = () => {
|
|
61
|
+
const fields = [];
|
|
62
|
+
function traverse(currentNode) {
|
|
63
|
+
var componentName = currentNode.type?.displayName || currentNode.props?._componentName;
|
|
64
|
+
const { props } = currentNode;
|
|
65
|
+
if (componentName && (componentName.startsWith('Field.') || componentName.startsWith('Layout.'))) {
|
|
66
|
+
fields.push(currentNode);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (props?.children) {
|
|
70
|
+
let children = React.Children.toArray(props?.children)
|
|
71
|
+
children.forEach(child => traverse(child));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
dependencyMap.current = new Map();
|
|
75
|
+
const childrenArray = React.Children.toArray(children);
|
|
76
|
+
for (let index = 0; index < childrenArray.length; index++) {
|
|
77
|
+
const element = childrenArray[index];
|
|
78
|
+
traverse(element)
|
|
79
|
+
}
|
|
80
|
+
fields.forEach(child => {
|
|
81
|
+
const { componentId, __id, ...props } = child?.props;
|
|
82
|
+
const identifier = componentId || __id;
|
|
83
|
+
dependencyMap.current.set(identifier, {
|
|
84
|
+
children: childrenArray.filter(item => item.props.withId === identifier || item.props.withIds?.some(item => {
|
|
85
|
+
return identifier == item || item.startsWith(identifier + '.')
|
|
86
|
+
})),
|
|
87
|
+
show: true,
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
console.log("dependencyMap", dependencyMap.current)
|
|
91
|
+
initializeFieldVisibility();
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// 初始化字段的级联关系
|
|
95
|
+
const initializeFieldVisibility = (reloadFields = false) => {
|
|
96
|
+
const fieldValues = form.getFieldsValue();
|
|
97
|
+
for (let key of dependencyMap.current.keys()) {
|
|
98
|
+
handleFieldsWith(key, fieldValues);
|
|
99
|
+
}
|
|
100
|
+
if (reloadFields) setFormContent(renderChildren());
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// 计算字段级联关系
|
|
104
|
+
const handleFieldsWith = (identifier, fieldValues) => {
|
|
105
|
+
let needRefresh = false;
|
|
106
|
+
if (dependencyMap.current.has(identifier)) {
|
|
107
|
+
const dependentChildren = dependencyMap.current.get(identifier).children;
|
|
108
|
+
dependentChildren.forEach(child => {
|
|
109
|
+
if (child.props.withFunc && typeof child.props.withFunc === 'function') {
|
|
110
|
+
needRefresh = handleFieldsVisible(fieldValues, child)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (child.props.withFill)
|
|
114
|
+
handleFieldsWithFill(fieldValues, child)
|
|
115
|
+
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return needRefresh;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// 处理级联显示隐藏 @return {boolean} 是否需要重新渲染表单的字段
|
|
122
|
+
const handleFieldsVisible = (fieldValues, child) => {
|
|
123
|
+
let needRefresh = false;
|
|
124
|
+
const childShouldBeVisible = child.props.withFunc(fieldValues);
|
|
125
|
+
const childIdentifier = child.props.componentId || child.props.__id;
|
|
126
|
+
if (dependencyMap.current.has(childIdentifier)) {
|
|
127
|
+
const childData = dependencyMap.current.get(childIdentifier);
|
|
128
|
+
if (childData.show !== childShouldBeVisible) {
|
|
129
|
+
childData.show = childShouldBeVisible;
|
|
130
|
+
dependencyMap.current.set(childIdentifier, childData);
|
|
131
|
+
needRefresh = true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return needRefresh
|
|
135
|
+
}
|
|
136
|
+
// 处理级联数据源
|
|
137
|
+
// 处理级联填充
|
|
138
|
+
const handleFieldsWithFill = async (fieldValues, child) => {
|
|
139
|
+
const withFill = child.props.withFill;
|
|
140
|
+
const withDataFetch = child.props.withDataFetch;
|
|
141
|
+
console.log("withFill", withFill)
|
|
142
|
+
console.log("fieldValues", fieldValues)
|
|
143
|
+
console.log("child", child)
|
|
144
|
+
|
|
145
|
+
let withDatas = [];
|
|
146
|
+
// 先处理依赖数据
|
|
147
|
+
if (withFill?.withData && withFill?.withData.length > 0 && withDataFetch && typeof withDataFetch === 'function') {
|
|
148
|
+
for (let index = 0; index < withFill?.withData.length; index++) {
|
|
149
|
+
const element = withFill?.withData[index];
|
|
150
|
+
let params = {}
|
|
151
|
+
params.tableName = element.withTable.table_name
|
|
152
|
+
params.filter = {}
|
|
153
|
+
for (let index = 0; index < element.withCondition.length; index++) {
|
|
154
|
+
const { value: condition_value, column: condition_column } = element.withCondition[index];
|
|
155
|
+
params.filter[condition_column.column_name] = getParamValue(condition_value.group_key, condition_value.field_key, fieldValues, withDatas)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 访问接口获取数据
|
|
159
|
+
const response = await withDataFetch(params)
|
|
160
|
+
if (response.code === 0 && response.data.list) {
|
|
161
|
+
withDatas.push({
|
|
162
|
+
id: element.id,
|
|
163
|
+
data: response.data.list
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 构造计算公式
|
|
170
|
+
let formula;
|
|
171
|
+
if (withFill.value && withFill.value.length > 0) {
|
|
172
|
+
formula = withFill.value.map(item => {
|
|
173
|
+
let result = "";
|
|
174
|
+
const { insert, attributes } = item
|
|
175
|
+
if (typeof insert !== "string") {
|
|
176
|
+
if (insert?.span && attributes && attributes.tagKey && attributes.id) {
|
|
177
|
+
result = getParamValue(attributes.tagKey, attributes.id, fieldValues, withDatas)
|
|
178
|
+
if (Array.isArray(result)) result = JSON.stringify(result)
|
|
179
|
+
else if (result) result = `"${result}"`
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
else result = insert
|
|
183
|
+
return result
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
console.log("formula", formula)
|
|
187
|
+
if (formula && formula.length > 0) {
|
|
188
|
+
const childIdentifier = child.props.componentId || child.props.__id;
|
|
189
|
+
form.setFieldValue(childIdentifier, evalFormula(formula))
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const getParamValue = (tagKey, id, fieldValues, withDatas) => {
|
|
194
|
+
let result = "";
|
|
195
|
+
// 从当前表单字段取值
|
|
196
|
+
if (tagKey == "fieldsValue") {
|
|
197
|
+
if (id.indexOf(".") >= 0) {
|
|
198
|
+
const [parentKey, childKey] = id.split(".");
|
|
199
|
+
const parentValue = fieldValues?.[parentKey] || [];
|
|
200
|
+
if (Array.isArray(parentValue))
|
|
201
|
+
result = parentValue.map(item => {
|
|
202
|
+
return item?.[childKey] || ""
|
|
203
|
+
})
|
|
204
|
+
else result = parentValue?.[childKey] || ""
|
|
205
|
+
}
|
|
206
|
+
else result = fieldValues?.[id] || ""
|
|
207
|
+
}
|
|
208
|
+
// 从依赖数据取值
|
|
209
|
+
else {
|
|
210
|
+
let withData = withDatas.find(item => item.id === tagKey)
|
|
211
|
+
if (withData && withData.data && withData.data.length > 0) {
|
|
212
|
+
// 暂时只取一条数据,后续再想 sum 函数等问题
|
|
213
|
+
result = withData.data[0]?.[id] || ""
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return result
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const handleFieldsChange = debounce((changedFields, allFields) => {
|
|
220
|
+
const fieldValues = form.getFieldsValue();
|
|
221
|
+
let needRefresh = false;
|
|
222
|
+
changedFields.forEach(field => {
|
|
223
|
+
if (field.name && field.name.length > 0) {
|
|
224
|
+
needRefresh = handleFieldsWith(field.name[0], fieldValues);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
if (needRefresh) {
|
|
229
|
+
setFormContent(renderChildren());
|
|
230
|
+
}
|
|
231
|
+
}, 200);
|
|
232
|
+
|
|
233
|
+
const renderChildren = () => {
|
|
234
|
+
const childrenArray = React.Children.toArray(children);
|
|
235
|
+
console.log("childrenArray", childrenArray)
|
|
236
|
+
const groupedChildren = batchElements(
|
|
237
|
+
childrenArray.filter(child => {
|
|
238
|
+
const identifier = child.props.componentId || child.props.__id;
|
|
239
|
+
return dependencyMap.current.has(identifier) && dependencyMap.current.get(identifier).show;
|
|
240
|
+
}),
|
|
241
|
+
cols
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
return groupedChildren.map((group, index) => (
|
|
245
|
+
<Row key={`row-${index}`} gutter={[24, 24]}>
|
|
246
|
+
{group.map((child, index) => {
|
|
247
|
+
const { componentId, __id, _componentName, ...props } = child.props;
|
|
248
|
+
const componentName = child.type?.displayName || _componentName;
|
|
249
|
+
const identifier = componentId || __id;
|
|
250
|
+
const isLayoutComponent = componentName && componentName.startsWith('Layout.');
|
|
251
|
+
const rules = []
|
|
252
|
+
if (props.isRequired)
|
|
253
|
+
rules.push({ required: true, message: `${props.label}必须填写` });
|
|
254
|
+
if (props.rules)
|
|
255
|
+
if (Array.isArray(props.rules)) {
|
|
256
|
+
const pattern = props.rules.join("|")
|
|
257
|
+
rules.push({ pattern: new RegExp(pattern), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
rules.push({ pattern: new RegExp(props.rules), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
|
|
261
|
+
}
|
|
262
|
+
return (
|
|
263
|
+
<Col key={identifier || `col-${index}`} span={isLayoutComponent ? 24 : 24 / group.length} style={{ marginBottom: 0 }}>
|
|
264
|
+
{isLayoutComponent && child}
|
|
265
|
+
{!isLayoutComponent && <Form.Item
|
|
266
|
+
style={{ marginBottom: 0 }}
|
|
267
|
+
label=""
|
|
268
|
+
name={identifier}
|
|
269
|
+
rules={rules}
|
|
270
|
+
>
|
|
271
|
+
{child}
|
|
272
|
+
</Form.Item>
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
</Col>
|
|
276
|
+
);
|
|
277
|
+
})}
|
|
278
|
+
</Row>
|
|
279
|
+
));
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<Form form={form} className={"form-container fp-0 fw-full fh-full box-border fflex fflex-col fgap-y-2" + (mode == "desgin" ? " fp-6" : "")} onFieldsChange={handleFieldsChange}>
|
|
284
|
+
{formContent}
|
|
285
|
+
</Form>
|
|
286
|
+
);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
export function withWrap(Component) {
|
|
290
|
+
return forwardRef((props, ref) => <Component {...props} ref={ref} forwardedRef={ref} />);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export class FormContainerClass extends React.PureComponent {
|
|
294
|
+
render() {
|
|
295
|
+
const { forwardedRef, ...otherProps } = this.props;
|
|
296
|
+
return <FormContainer {...otherProps} ref={forwardedRef} />
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const FormContainerWrapper = withWrap(({ forwardedRef, ...props }) => <FormContainer {...props} ref={forwardedRef} />);
|
|
300
|
+
|
|
301
|
+
export { LayoutFormRow, LayoutFormGroupTitle } from './layout';
|
|
302
|
+
export { FormContainer, FormContainerWrapper };
|