lu-lowcode-package-form 0.9.76 → 0.9.78
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 +365 -288
- package/dist/index.es.js +41857 -28594
- package/package.json +2 -1
- package/src/App.jsx +26 -11
- package/src/App.test.js +1 -0
- package/src/components/field/base.jsx +2 -2
- package/src/components/field/select/search-select.jsx +46 -22
- package/src/components/field/table/index.jsx +24 -12
- package/src/components/form-container/index.jsx +120 -39
- package/src/components/form-container/layout/form-row.jsx +9 -4
- package/src/components/index.jsx +2 -0
- package/src/utils/formula.js +1 -0
- package/src/utils/index.jsx +19 -2
- package/frp_0.45.0_linux_amd64.tar.gz +0 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "lu-lowcode-package-form",
|
3
|
-
"version": "0.9.
|
3
|
+
"version": "0.9.78",
|
4
4
|
"dependencies": {
|
5
5
|
"@ant-design/icons": "^4.8.1",
|
6
6
|
"@testing-library/jest-dom": "^5.17.0",
|
@@ -13,6 +13,7 @@
|
|
13
13
|
"@wangeditor/editor-for-react": "^1.0.6",
|
14
14
|
"antd": "^5.13.2",
|
15
15
|
"dayjs": "^1.11.11",
|
16
|
+
"nanoid": "^5.0.7",
|
16
17
|
"postcss-modules": "^6.0.0",
|
17
18
|
"quill": "^2.0.2",
|
18
19
|
"react-draggable": "^4.4.6",
|
package/src/App.jsx
CHANGED
@@ -100,7 +100,7 @@ function App() {
|
|
100
100
|
}
|
101
101
|
const setFormFields = () => {
|
102
102
|
formRef?.current?.formRef?.setFieldsValue({ datetime: "2024-08-25",datetime2: "2024-08-25",datetime3: "",
|
103
|
-
"remark11": { "label": "选项2",
|
103
|
+
"remark11": { "label": "选项2", value: '1'},
|
104
104
|
"remark12": [{ "label": "选项1", "value": "1" }, { "label": "选项2", "value": "2" }],
|
105
105
|
"userselect": "1213131", "DeptSelect": ["leaf11"],
|
106
106
|
"searchuser": [{ "id": 2, "name": "2222", "label": "2222", "value": 2 }, { "id": 4, "name": "4444", "label": "4444", "value": 4 }],
|
@@ -180,7 +180,31 @@ function App() {
|
|
180
180
|
]} label="测试关联单选" options={[{ label: '选项1', value: '1', name: "1111", table: "[{\"price\":1,\"num\":2},{\"price\":2,\"num\":2},{\"price\":3,\"num\":3},{\"price\":3,\"num\":3}]" }, { label: '选项2', value: '2' }]} __id="remark11" />
|
181
181
|
<Layout.FormRow layout={'1'}>
|
182
182
|
<Field.Table label="子表格" __id="table" >
|
183
|
+
<Field.Number label="税率(%)" __id="shuilv_table" withIds={[
|
184
|
+
"shuilv"
|
185
|
+
]}
|
186
|
+
withFill={{
|
187
|
+
"value": [
|
188
|
+
{
|
189
|
+
"insert": {
|
190
|
+
"span": true
|
191
|
+
},
|
192
|
+
"attributes": {
|
193
|
+
"id": "shuilv",
|
194
|
+
"color": "blue",
|
195
|
+
"tagKey": "fieldsValue",
|
196
|
+
"content": "当前表单.税率(%)"
|
197
|
+
}
|
198
|
+
},
|
199
|
+
|
200
|
+
],
|
201
|
+
"version": 1723016911807,
|
202
|
+
"withData": [
|
203
|
+
|
204
|
+
]
|
205
|
+
}}/>
|
183
206
|
<Field.DatePicker defaultNow={true} label="日期时间" prompt="" datetype="date" __id="datetime2" />
|
207
|
+
|
184
208
|
<Field.WithSingleSelect ref={testRef} fillRules={[
|
185
209
|
{
|
186
210
|
"id": "636d3924-0298-4e9b-809a-26d4a10d7b89",
|
@@ -191,15 +215,6 @@ function App() {
|
|
191
215
|
|
192
216
|
]
|
193
217
|
},
|
194
|
-
{
|
195
|
-
"id": "636d3924-0298-4e9b-809a-26d4a10d7b89",
|
196
|
-
"type": 0,
|
197
|
-
"source": "product_price12",
|
198
|
-
"target": "product_price12",
|
199
|
-
"subRules": [
|
200
|
-
|
201
|
-
]
|
202
|
-
},
|
203
218
|
{
|
204
219
|
"id": "636d3924-0298-4e9b-809a-26d4a10d7b89",
|
205
220
|
"type": 0,
|
@@ -210,7 +225,7 @@ function App() {
|
|
210
225
|
]
|
211
226
|
},
|
212
227
|
|
213
|
-
]} label="测试关联单选" options={[{ label: '选项1', value: '1', product_price11: "1111", product_price12: "2222", product_price1: 111 }, { label: '选项2', value: '2' }, { label: '选项
|
228
|
+
]} label="测试关联单选" options={[{ label: '选项1', value: '1', product_price11: "1111", product_price12: "2222", product_price1: 111 }, { label: '选项2', value: '2' }, { label: '选项3', value: '3' }]} __id="remark11" />
|
214
229
|
|
215
230
|
<Field.Switch label="开关" __id="switch_table"></Field.Switch>
|
216
231
|
<Field.Input defaultValue={3} isRequired={true} label="含税单价" __id="product_price11" />
|
package/src/App.test.js
CHANGED
@@ -33,7 +33,7 @@ export const BaseWrapper = ({
|
|
33
33
|
}) => {
|
34
34
|
useEffect(()=>{
|
35
35
|
if (defaultValue && typeof onChange === "function" && !value) {
|
36
|
-
console.log("defaultValue changed", defaultValue)
|
36
|
+
// console.log("defaultValue changed", defaultValue)
|
37
37
|
onChange(defaultValue)
|
38
38
|
}
|
39
39
|
},[])
|
@@ -41,7 +41,7 @@ export const BaseWrapper = ({
|
|
41
41
|
// 不接管只读属性的组件
|
42
42
|
const ignoreReadonly = ["UploadImage", "UploadFile", "Table", "WithMultipleSelect", "WithSingleSelect"]
|
43
43
|
if (readonly) {
|
44
|
-
console.log("children?.type?.displayName", children?.type?.displayName)
|
44
|
+
// console.log("children?.type?.displayName", children?.type?.displayName)
|
45
45
|
}
|
46
46
|
if (ignoreReadonly.includes(children?.type?.displayName) && readonly) readonly = false
|
47
47
|
const formWarpper = (
|
@@ -3,7 +3,7 @@
|
|
3
3
|
import { Input, Select as OriginalSelect, Spin } from 'antd';
|
4
4
|
import React, { useEffect, useState } from 'react';
|
5
5
|
import { BaseWrapper } from "../base"
|
6
|
-
import { debounce } from 'lodash';
|
6
|
+
import { debounce, isEqual } from 'lodash';
|
7
7
|
|
8
8
|
|
9
9
|
const SearchSelect = ({ addWrapper = true, value, type, defaultValue, onChange, option_label, option_value, option_search, options, request, requestParams, callError, subRequest, sub_option_label = "label", mode = "single", sub_option_value = "id", rightIcon, rightIconClick, ...props }) => {
|
@@ -18,8 +18,11 @@ const SearchSelect = ({ addWrapper = true, value, type, defaultValue, onChange,
|
|
18
18
|
|
19
19
|
if (request && typeof request === 'function') {
|
20
20
|
const list = await fetchOptions(params)
|
21
|
-
if (list && Array.isArray(list))
|
21
|
+
if (list && Array.isArray(list)) {
|
22
22
|
item = value ? list.find(item => item.value == value) : null
|
23
|
+
console.log("SearchSelect value", value)
|
24
|
+
console.log("SearchSelect item", item)
|
25
|
+
}
|
23
26
|
}
|
24
27
|
|
25
28
|
if (options && options.length > 0) {
|
@@ -33,6 +36,27 @@ const SearchSelect = ({ addWrapper = true, value, type, defaultValue, onChange,
|
|
33
36
|
|
34
37
|
}
|
35
38
|
|
39
|
+
useEffect(() => {
|
40
|
+
console.log("useEffect SearchSelect value", value)
|
41
|
+
if (value && nOptions.length > 0) {
|
42
|
+
let item = value
|
43
|
+
if (Array.isArray(value)) {
|
44
|
+
item = nOptions.filter(item => {
|
45
|
+
return value.filter(v => item.value == v?.value || item.value == v).length > 0
|
46
|
+
})
|
47
|
+
}
|
48
|
+
else {
|
49
|
+
item = nOptions.find(item => item.value == value?.value || item.value == value)
|
50
|
+
}
|
51
|
+
|
52
|
+
if (item && !isEqual(item, value)) {
|
53
|
+
onChange(item)
|
54
|
+
console.log("SearchSelect onChange value", item)
|
55
|
+
}
|
56
|
+
|
57
|
+
}
|
58
|
+
}, [value, nOptions])
|
59
|
+
|
36
60
|
const handleSearch = debounce(async (value) => {
|
37
61
|
const params = { ...requestParams }
|
38
62
|
params[option_search] = value
|
@@ -88,24 +112,8 @@ const SearchSelect = ({ addWrapper = true, value, type, defaultValue, onChange,
|
|
88
112
|
|
89
113
|
return addWrapper ? (
|
90
114
|
<BaseWrapper {...props}>
|
91
|
-
<OriginalSelect
|
92
|
-
|
93
|
-
notFoundContent={fetching ? <Spin size="small" /> : null}
|
94
|
-
value={value}
|
95
|
-
{...props}
|
96
|
-
filterOption={false}
|
97
|
-
showSearch={request && option_search ? true : false}
|
98
|
-
onSearch={request && option_search ? handleSearch : null}
|
99
|
-
onChange={handleChange}
|
100
|
-
style={{ width: '100%', flex: 1 }}
|
101
|
-
options={nOptions}
|
102
|
-
mode={mode} >
|
103
|
-
|
104
|
-
</OriginalSelect>
|
105
|
-
{!props?.disabled && rightIcon}
|
106
|
-
</BaseWrapper>
|
107
|
-
) : (<>
|
108
115
|
<OriginalSelect
|
116
|
+
|
109
117
|
notFoundContent={fetching ? <Spin size="small" /> : null}
|
110
118
|
value={value}
|
111
119
|
{...props}
|
@@ -113,12 +121,28 @@ const SearchSelect = ({ addWrapper = true, value, type, defaultValue, onChange,
|
|
113
121
|
showSearch={request && option_search ? true : false}
|
114
122
|
onSearch={request && option_search ? handleSearch : null}
|
115
123
|
onChange={handleChange}
|
116
|
-
style={{ width: '100%' }}
|
124
|
+
style={{ width: '100%', flex: 1 }}
|
117
125
|
options={nOptions}
|
118
|
-
mode={mode}
|
126
|
+
mode={mode} >
|
119
127
|
|
120
128
|
</OriginalSelect>
|
121
|
-
{!props?.disabled && rightIcon}
|
129
|
+
{!props?.disabled && rightIcon}
|
130
|
+
</BaseWrapper>
|
131
|
+
) : (<>
|
132
|
+
<OriginalSelect
|
133
|
+
notFoundContent={fetching ? <Spin size="small" /> : null}
|
134
|
+
value={value}
|
135
|
+
{...props}
|
136
|
+
filterOption={false}
|
137
|
+
showSearch={request && option_search ? true : false}
|
138
|
+
onSearch={request && option_search ? handleSearch : null}
|
139
|
+
onChange={handleChange}
|
140
|
+
style={{ width: '100%' }}
|
141
|
+
options={nOptions}
|
142
|
+
mode={mode} >
|
143
|
+
|
144
|
+
</OriginalSelect>
|
145
|
+
{!props?.disabled && rightIcon}</>
|
122
146
|
)
|
123
147
|
|
124
148
|
}
|
@@ -2,6 +2,8 @@ import React, { useEffect, useState } from "react";
|
|
2
2
|
import { Button, Form, Input } from "antd";
|
3
3
|
import { DeleteOutlined } from "@ant-design/icons";
|
4
4
|
import { BaseWrapper } from "../base.jsx"
|
5
|
+
import { type } from "@testing-library/user-event/dist/type/index.js";
|
6
|
+
import { nanoid } from "nanoid";
|
5
7
|
|
6
8
|
const TableAction = ({ label, subTableIndex, children, subTableHead = false, ...props }) => {
|
7
9
|
//fsticky fright-0
|
@@ -26,14 +28,16 @@ const TableCol = ({ children, width, ...props }) => {
|
|
26
28
|
</div>
|
27
29
|
}
|
28
30
|
|
29
|
-
const Table = ({ children, ...props }) => {
|
31
|
+
const Table = ({ children, onTableAddRow,onTableRemoveRow, ...props }) => {
|
30
32
|
const [init, setInit] = useState(false);
|
31
33
|
const name = props.componentId || props.__id
|
34
|
+
const childrenIds = React.Children.map(children, (child) => `${name}.${child.props.componentId || child.props.__id}`)
|
32
35
|
const rules = []
|
33
|
-
const handleAdd = (add)=>{
|
36
|
+
const handleAdd = (add) => {
|
34
37
|
if (!init) setInit(true);
|
35
38
|
typeof add === "function" && add();
|
36
39
|
}
|
40
|
+
|
37
41
|
if (props.isRequired)
|
38
42
|
rules.push({ required: true, message: `子表[${props.label}]必须填写` });
|
39
43
|
return <Form.List name={name} rules={rules}>
|
@@ -41,7 +45,7 @@ const Table = ({ children, ...props }) => {
|
|
41
45
|
if (fields.length === 0 && !init) handleAdd(add);
|
42
46
|
return <div className="fw-full ">
|
43
47
|
<div className="fw-full frelative fmin-h-20 foverflow-x-auto">
|
44
|
-
|
48
|
+
{fields.length === 0 && <div key={`tableHead`} className="fborder-b fflex flex-nowrap fmin-w-full ">
|
45
49
|
{React.Children.map(children, (child, childIndex) => {
|
46
50
|
return <TableCol width={150} key={`row_${0}_col_${childIndex}`}>
|
47
51
|
{React.cloneElement(child, {
|
@@ -52,16 +56,16 @@ const Table = ({ children, ...props }) => {
|
|
52
56
|
})}
|
53
57
|
</TableCol>
|
54
58
|
})}
|
55
|
-
|
56
|
-
</TableAction>}
|
59
|
+
{!props?.readonly && <TableAction subTableHead={true} key={`row_${0}_action`} subTable={true} subTableIndex={0} label={"操作"}>
|
60
|
+
</TableAction>}
|
57
61
|
</div>}
|
58
62
|
{fields.map((field, index) => (
|
59
63
|
<div key={field.key} className="fborder-b fflex flex-nowrap fmin-w-full ">
|
60
|
-
|
64
|
+
{/* {console.log("field",field)} */}
|
61
65
|
{React.Children.map(children, (child, childIndex) => {
|
62
66
|
let { props } = child;
|
63
67
|
const col_id = child?.props?.componentId || child?.props?.__id || childIndex;
|
64
|
-
if (field?.[col_id] === undefined) field[col_id] = "";
|
68
|
+
// if (field?.[col_id] === undefined) field[col_id] = "";
|
65
69
|
const rules = []
|
66
70
|
if (props.isRequired)
|
67
71
|
rules.push({ required: true, message: `${props.label}必须填写` });
|
@@ -74,15 +78,16 @@ const Table = ({ children, ...props }) => {
|
|
74
78
|
rules.push({ pattern: new RegExp(props.rules), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
|
75
79
|
}
|
76
80
|
|
77
|
-
return <TableCol width={150} key={`row_${
|
81
|
+
return <TableCol width={150} key={`row_${field.key}_col_${childIndex}`}>
|
78
82
|
<Form.Item
|
79
83
|
style={{ marginBottom: 0 }}
|
80
84
|
label=""
|
81
85
|
name={[field.name, col_id]}
|
82
86
|
rules={rules}
|
87
|
+
|
83
88
|
>
|
84
89
|
{React.cloneElement(child, {
|
85
|
-
key: `row_${
|
90
|
+
key: `row_${field.key}_child_${childIndex}`,
|
86
91
|
subTable: true,
|
87
92
|
subTableIndex: index,
|
88
93
|
subTableHead: index == 0,
|
@@ -90,13 +95,19 @@ const Table = ({ children, ...props }) => {
|
|
90
95
|
</Form.Item>
|
91
96
|
</TableCol>
|
92
97
|
})}
|
93
|
-
{!props?.readonly && <TableAction subTableHead={index ==0} key={`row_${index}_action`} subTable={true} subTableIndex={index} label={"操作"}>
|
94
|
-
<DeleteOutlined className="fcursor-pointer" onClick={() =>
|
98
|
+
{!props?.readonly && <TableAction subTableHead={index == 0} key={`row_${index}_action`} subTable={true} subTableIndex={index} label={"操作"}>
|
99
|
+
<DeleteOutlined className="fcursor-pointer" onClick={() =>{
|
100
|
+
remove(index)
|
101
|
+
typeof onTableRemoveRow === "function" && onTableRemoveRow(childrenIds);
|
102
|
+
}} />
|
95
103
|
</TableAction>}
|
96
104
|
</div>
|
97
105
|
))}
|
98
106
|
</div>
|
99
|
-
<Button onClick={() =>
|
107
|
+
<Button onClick={() => {
|
108
|
+
add({ key: nanoid() })
|
109
|
+
typeof onTableAddRow === "function" && onTableAddRow(childrenIds);
|
110
|
+
}} className="fmy-2">新增一行</Button>
|
100
111
|
</div>
|
101
112
|
}}
|
102
113
|
</Form.List>
|
@@ -110,5 +121,6 @@ const TableWrapper = (props) => {
|
|
110
121
|
</BaseWrapper>
|
111
122
|
);
|
112
123
|
}
|
124
|
+
TableWrapper.displayName = "Table"
|
113
125
|
export default TableWrapper;
|
114
126
|
export { TableCol, TableAction };
|
@@ -3,6 +3,7 @@ import { Form, Row, Col, message } from "antd";
|
|
3
3
|
|
4
4
|
import { debounce, isEqual } from 'lodash';
|
5
5
|
import { evalFormula } from '../../utils/formula'
|
6
|
+
import { nanoid } from 'nanoid';
|
6
7
|
|
7
8
|
|
8
9
|
function batchElements(elements, groupSize) {
|
@@ -45,7 +46,7 @@ function batchElements(elements, groupSize) {
|
|
45
46
|
const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) => {
|
46
47
|
const [form] = Form.useForm();
|
47
48
|
const [formContent, setFormContent] = React.useState(null);
|
48
|
-
|
49
|
+
|
49
50
|
const dependencyMap = React.useRef(null);
|
50
51
|
|
51
52
|
React.useImperativeHandle(ref, () => ({
|
@@ -60,15 +61,16 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
60
61
|
|
61
62
|
|
62
63
|
const lastFormValues = React.useRef(null);
|
63
|
-
const
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
64
|
+
const getLastFieldValue = (path) => {
|
65
|
+
return lastFormValues.current?.[path]
|
66
|
+
// let current = lastFormValues.current;
|
67
|
+
// for (let i = 0; i < path.length; i++) {
|
68
|
+
// if (current == null) {
|
69
|
+
// return undefined;
|
70
|
+
// }
|
71
|
+
// current = current[path[i]];
|
72
|
+
// }
|
73
|
+
// return current;
|
72
74
|
}
|
73
75
|
const initializeDependencyMap = () => {
|
74
76
|
const fields = [];
|
@@ -95,6 +97,7 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
95
97
|
}
|
96
98
|
}
|
97
99
|
dependencyMap.current = new Map();
|
100
|
+
|
98
101
|
const childrenArray = React.Children.toArray(children);
|
99
102
|
for (let index = 0; index < childrenArray.length; index++) {
|
100
103
|
const element = childrenArray[index];
|
@@ -111,7 +114,7 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
111
114
|
...field
|
112
115
|
});
|
113
116
|
});
|
114
|
-
|
117
|
+
|
115
118
|
initializeFieldVisibility();
|
116
119
|
};
|
117
120
|
|
@@ -127,6 +130,7 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
127
130
|
// 计算字段级联关系
|
128
131
|
const handleFieldsWith = (identifier, fieldValues, init = false) => {
|
129
132
|
let needRefresh = false;
|
133
|
+
|
130
134
|
let parentIdentifier = [];
|
131
135
|
if (Array.isArray(identifier)) {
|
132
136
|
parentIdentifier = [...(identifier.slice(0, -1))]
|
@@ -135,8 +139,8 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
135
139
|
if (dependencyMap.current.has(identifier)) {
|
136
140
|
const dependent = dependencyMap.current.get(identifier)
|
137
141
|
const dependentChildren = dependent.children;
|
138
|
-
|
139
|
-
|
142
|
+
|
143
|
+
|
140
144
|
if (!init && dependent?.fillRules && Array.isArray(dependent?.fillRules) && dependent?.fillRules.length > 0) {
|
141
145
|
handleFillRules(identifier, parentIdentifier, fieldValues, dependent?.fillRules)
|
142
146
|
}
|
@@ -151,12 +155,16 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
151
155
|
});
|
152
156
|
}
|
153
157
|
return needRefresh;
|
158
|
+
|
154
159
|
};
|
155
160
|
|
156
161
|
// 处理填充规则
|
157
162
|
const handleFillRules = (current_identifier, parentIdentifier, fieldValues, fillRules) => {
|
158
163
|
// 获取当前变更的字段数据
|
159
164
|
let current_value = getParamValue("fieldsValue", current_identifier, fieldValues, null)
|
165
|
+
let changedFields = {}
|
166
|
+
|
167
|
+
let ids = []
|
160
168
|
for (let index = 0; index < fillRules.length; index++) {
|
161
169
|
const rule = fillRules[index];
|
162
170
|
let { source, target } = rule
|
@@ -164,21 +172,28 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
164
172
|
let setValue = source_value
|
165
173
|
// 子表
|
166
174
|
if (rule?.type == 1) {
|
175
|
+
if (dependencyMap.current.has(target)) {
|
176
|
+
let tableChildren = dependencyMap.current.get(target)?.component?.props?.children
|
177
|
+
if (Array.isArray(tableChildren) && tableChildren.length > 0) ids = tableChildren.map(item => `${source}.${item?.props?.componentId || item?.props?.__id}`)
|
178
|
+
|
179
|
+
}
|
167
180
|
if (source_value && typeof source_value == "string") {
|
168
181
|
try {
|
169
182
|
source_value = JSON.parse(source_value)
|
170
183
|
} catch (error) {
|
171
|
-
console.
|
184
|
+
console.error("error end", error)
|
172
185
|
}
|
173
186
|
}
|
174
187
|
|
175
188
|
if (!Array.isArray(source_value)) return
|
176
|
-
let target_value = source_value.map(item => {
|
189
|
+
let target_value = source_value.map((item, value_index) => {
|
177
190
|
let target_item_value = {}
|
178
191
|
if (rule?.subRules && Array.isArray(rule?.subRules) && rule?.subRules.length > 0)
|
179
192
|
for (let index = 0; index < rule?.subRules.length; index++) {
|
180
193
|
const { source: subSource, target: subTarget } = rule?.subRules[index];
|
181
194
|
target_item_value[subTarget] = item?.[subSource]
|
195
|
+
let changedField = { name: [target, value_index, subTarget], value: item?.[subSource] }
|
196
|
+
changedFields[changedField.name] = changedField;
|
182
197
|
}
|
183
198
|
return target_item_value
|
184
199
|
})
|
@@ -197,10 +212,31 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
197
212
|
}
|
198
213
|
}
|
199
214
|
}
|
200
|
-
|
201
|
-
|
215
|
+
if (rule?.type == 1) {
|
216
|
+
form.setFieldValue(target, undefined);
|
217
|
+
}
|
218
|
+
|
219
|
+
setTimeout(() => {
|
220
|
+
form.setFieldValue(target, setValue)
|
221
|
+
handleFieldsWith(target, form.getFieldsValue())
|
222
|
+
// if (ids.length > 0) handleTableAddRow(ids)
|
223
|
+
}, 0);
|
224
|
+
|
202
225
|
}
|
203
|
-
|
226
|
+
|
227
|
+
setTimeout(() => {
|
228
|
+
var changedKeys = Object.keys(changedFields)
|
229
|
+
if (changedKeys.length > 0) {
|
230
|
+
changedKeys.forEach(key => {
|
231
|
+
changedFieldsState.current[key] = changedFields[key];
|
232
|
+
})
|
233
|
+
debounceHandleFieldsChange();
|
234
|
+
}
|
235
|
+
|
236
|
+
|
237
|
+
if (ids.length > 0) handleTableAddRow(ids)
|
238
|
+
}, 100)
|
239
|
+
|
204
240
|
}
|
205
241
|
// 处理级联显示隐藏 @return {boolean} 是否需要重新渲染表单的字段
|
206
242
|
const handleFieldsVisible = (fieldValues, child, parentIdentifier) => {
|
@@ -220,10 +256,10 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
220
256
|
// 处理级联数据源
|
221
257
|
// 处理级联填充
|
222
258
|
const handleFieldsWithFill = async (fieldValues, child, parentIdentifier, componentName) => {
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
259
|
+
|
260
|
+
|
261
|
+
|
262
|
+
|
227
263
|
const withFill = child?.component?.props.withFill;
|
228
264
|
const withDataFetch = child?.component?.props.withDataFetch;
|
229
265
|
let withFillIndex = 0
|
@@ -240,7 +276,6 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
240
276
|
else if (childIdentifier.indexOf(".") >= 0) {
|
241
277
|
childIdentifier = childIdentifier.split(".")
|
242
278
|
let table_values = getParamValue("fieldsValue", childIdentifier[0], fieldValues, [])
|
243
|
-
// console.log("table_values", table_values)
|
244
279
|
if (Array.isArray(table_values) && table_values.length > 0)
|
245
280
|
for (let index = 0; index < table_values.length; index++) {
|
246
281
|
await handleFieldsWithFill(fieldValues, child, [childIdentifier[0], index], componentName)
|
@@ -294,18 +329,18 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
294
329
|
}
|
295
330
|
else result = JSON.stringify(result)
|
296
331
|
}
|
297
|
-
else if (result) result = `"${result}"`
|
332
|
+
else if (result.length > 0) result = `"${result}"`
|
298
333
|
}
|
299
334
|
}
|
300
335
|
else result = insert
|
301
336
|
return result
|
302
337
|
})
|
303
338
|
}
|
304
|
-
|
339
|
+
|
305
340
|
if (formula && formula.length > 0) {
|
306
341
|
const formulaResult = evalFormula(formula);
|
307
|
-
|
308
|
-
|
342
|
+
|
343
|
+
|
309
344
|
form.setFieldValue(childIdentifier, formulaResult)
|
310
345
|
handleFieldsWith(childIdentifier, form.getFieldsValue())
|
311
346
|
}
|
@@ -320,38 +355,80 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
320
355
|
const parentValue = fieldValues?.[parentKey] || [];
|
321
356
|
if (Array.isArray(parentValue))
|
322
357
|
result = parentValue.map(item => {
|
323
|
-
return item?.[childKey]
|
358
|
+
return item?.[childKey] ?? ""
|
324
359
|
})
|
325
|
-
else result = parentValue?.[childKey]
|
360
|
+
else result = parentValue?.[childKey] ?? ""
|
326
361
|
}
|
327
|
-
else result = fieldValues?.[id]
|
362
|
+
else result = fieldValues?.[id] ?? ""
|
328
363
|
}
|
329
364
|
// 从依赖数据取值
|
330
365
|
else {
|
331
366
|
let withData = withDatas.find(item => item.id === tagKey)
|
332
367
|
if (withData && withData.data && withData.data.length > 0) {
|
333
368
|
// 暂时只取一条数据,后续再想 sum 函数等问题
|
334
|
-
result = withData.data[0]?.[id]
|
369
|
+
result = withData.data[0]?.[id] ?? ""
|
335
370
|
}
|
336
371
|
}
|
337
372
|
return result
|
338
373
|
}
|
339
374
|
|
340
|
-
const
|
375
|
+
const changedFieldsState = React.useRef({});
|
376
|
+
const debounceHandleFieldsChange = debounce(() => {
|
341
377
|
const fieldValues = form.getFieldsValue();
|
342
378
|
let needRefresh = false;
|
343
|
-
|
344
|
-
|
379
|
+
if (!lastFormValues.current) lastFormValues.current = {}
|
380
|
+
for (let key in changedFieldsState.current) {
|
381
|
+
let field = changedFieldsState.current[key];
|
382
|
+
if (!isEqual(field.value, getLastFieldValue(field.name))) {
|
345
383
|
needRefresh = handleFieldsWith(field.name, fieldValues);
|
384
|
+
lastFormValues.current[field.name] = field.value;
|
346
385
|
}
|
347
|
-
}
|
348
|
-
|
386
|
+
}
|
349
387
|
if (needRefresh) {
|
350
388
|
setFormContent(renderChildren());
|
351
389
|
}
|
352
|
-
lastFormValues.current = form.getFieldsValue();
|
390
|
+
// lastFormValues.current = form.getFieldsValue();
|
391
|
+
changedFieldsState.current = {};
|
353
392
|
}, 200);
|
354
393
|
|
394
|
+
const handleFieldsChange = (changedFields) => {
|
395
|
+
changedFields.filter(field => {
|
396
|
+
if (field.name && field.name.length > 0) {
|
397
|
+
// const fieldKey = field.name.filter(item => typeof item == "string").join(".")
|
398
|
+
changedFieldsState.current[field.name] = field;
|
399
|
+
}
|
400
|
+
})
|
401
|
+
|
402
|
+
debounceHandleFieldsChange();
|
403
|
+
}
|
404
|
+
const handleTableAddRow = (ids) => {
|
405
|
+
let withAllIds = []
|
406
|
+
ids.forEach(id => {
|
407
|
+
if (!dependencyMap.current.has(id)) return
|
408
|
+
let component = dependencyMap.current.get(id)
|
409
|
+
if (component.withIds.length <= 0) return
|
410
|
+
withAllIds.push(...(component.withIds.filter(withid => !withAllIds.includes(withid))))
|
411
|
+
})
|
412
|
+
withAllIds = withAllIds.filter(item => {
|
413
|
+
var withValue = form.getFieldValue(item)
|
414
|
+
if (typeof withValue != "number" && !withValue) return false
|
415
|
+
return true
|
416
|
+
})
|
417
|
+
const fieldValues = form.getFieldsValue();
|
418
|
+
setTimeout(() => {
|
419
|
+
withAllIds.forEach(withid => {
|
420
|
+
handleFieldsWith(withid, fieldValues);
|
421
|
+
})
|
422
|
+
}, 0);
|
423
|
+
}
|
424
|
+
const handleTableRemoveRow = (ids) => {
|
425
|
+
const fieldValues = form.getFieldsValue();
|
426
|
+
setTimeout(() => {
|
427
|
+
ids.forEach(id => {
|
428
|
+
handleFieldsWith(id, fieldValues);
|
429
|
+
})
|
430
|
+
}, 0);
|
431
|
+
}
|
355
432
|
const renderChildren = () => {
|
356
433
|
const childrenArray = React.Children.toArray(children);
|
357
434
|
const groupedChildren = batchElements(
|
@@ -381,15 +458,19 @@ const FormContainer = forwardRef(({ cols = 1, children, mode = "view" }, ref) =>
|
|
381
458
|
else {
|
382
459
|
rules.push({ pattern: new RegExp(props.rules), message: props.rulesFailMessage ? props.rulesFailMessage : `${props.label}格式错误` })
|
383
460
|
}
|
461
|
+
let childComponent = child;
|
462
|
+
if (isTable || isLayoutComponent) {
|
463
|
+
childComponent = React.cloneElement(child, { onTableAddRow: handleTableAddRow ,onTableRemoveRow: handleTableRemoveRow })
|
464
|
+
}
|
384
465
|
return (
|
385
466
|
<Col key={identifier || `col-${index}`} span={isLayoutComponent ? 24 : 24 / group.length} style={{ marginBottom: 0 }}>
|
386
|
-
{(isLayoutComponent || isTable) ?
|
467
|
+
{(isLayoutComponent || isTable) ? childComponent : <Form.Item
|
387
468
|
style={{ marginBottom: 0 }}
|
388
469
|
label=""
|
389
470
|
name={identifier}
|
390
471
|
rules={rules}
|
391
472
|
>
|
392
|
-
{
|
473
|
+
{childComponent}
|
393
474
|
</Form.Item>}
|
394
475
|
</Col>
|
395
476
|
);
|