@hzab/list-render 1.10.11 → 1.10.12-beta2
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/CHANGELOG.md +8 -1
- package/package.json +5 -3
- package/src/common/cloneSchema.ts +63 -0
- package/src/common/formily-utils.jsx +30 -5
- package/src/common/handleQuerySchema.ts +3 -2
- package/src/common/handleReactions.js +3 -2
- package/src/common/utils.js +305 -279
- package/src/components/Formily/FormilyEditTable.tsx +10 -5
- package/src/components/Formily/FormilyField.tsx +18 -6
- package/src/list-render.jsx +1 -1
- package/src/query-render/index.jsx +2 -2
- package/src/table-render/index.jsx +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
# @hzab/list-render@1.10.12
|
|
2
|
+
|
|
3
|
+
feat: schema title 支持传入 ReactNode,支持通过 schemaScope 传入
|
|
4
|
+
fix: table 响应数据 去除 inTable == false 的字段
|
|
5
|
+
fix: table 响应表单 FormilyField 环境变量 scenario: "tableReactionsForm"
|
|
6
|
+
fix: 行内编辑 清除上一次的数据,解决切换表单数据未清除问题
|
|
7
|
+
|
|
1
8
|
# @hzab/list-render@1.10.11
|
|
2
9
|
|
|
3
|
-
fix: 行内编辑统一onEdit获取数据,单元格编辑支持传入其他参数
|
|
10
|
+
fix: 行内编辑统一 onEdit 获取数据,单元格编辑支持传入其他参数
|
|
4
11
|
|
|
5
12
|
# @hzab/list-render@1.10.10
|
|
6
13
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hzab/list-render",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.12-beta2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src",
|
|
6
6
|
"scripts": {
|
|
@@ -27,15 +27,16 @@
|
|
|
27
27
|
"@hzab/permissions": "^1.0.0",
|
|
28
28
|
"@hzab/schema-descriptions": "^1.3.0",
|
|
29
29
|
"@hzab/webpack-config": "^0.7.2",
|
|
30
|
+
"@hzab/utils": "^1.0.7",
|
|
30
31
|
"@types/react": "^17.0.62",
|
|
31
32
|
"@types/react-dom": "^17.0.20",
|
|
32
33
|
"antd": "^4.24.12",
|
|
33
34
|
"axios": "^1.4.0",
|
|
34
35
|
"eslint": "^8.30.0",
|
|
35
|
-
"mobx": "^6.7.0",
|
|
36
|
-
"mobx-react": "^7.6.0",
|
|
37
36
|
"less": "^4.1.3",
|
|
38
37
|
"lodash": "^4.17.21",
|
|
38
|
+
"mobx": "^6.7.0",
|
|
39
|
+
"mobx-react": "^7.6.0",
|
|
39
40
|
"react": "^17.0.2",
|
|
40
41
|
"react-dom": "^17.0.2",
|
|
41
42
|
"react-router-dom": "^6.8.1",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
"@hzab/form-render": ">=1.0.0",
|
|
50
51
|
"@hzab/formily-result-utils": ">=1.2.0",
|
|
51
52
|
"@hzab/schema-descriptions": ">=1.0.0",
|
|
53
|
+
"@hzab/utils": ">=1.0.7",
|
|
52
54
|
"antd": "4.x",
|
|
53
55
|
"axios": ">=1.4.0",
|
|
54
56
|
"c-formily-antd": "2.3.1",
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 检测是否为原生 HTML DOM 节点
|
|
5
|
+
* @param {any} node 待检测对象
|
|
6
|
+
* @returns {boolean} 是否为原生 DOM 节点
|
|
7
|
+
*/
|
|
8
|
+
function isHtmlDomNode(node) {
|
|
9
|
+
// 先判断浏览器环境,避免 SSR 报错;兼容 Node/HTMLElement 类型
|
|
10
|
+
return !!(typeof window !== "undefined" && node && (node instanceof HTMLElement || node instanceof Node));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 增强版 Formily Schema 克隆函数
|
|
15
|
+
* 解决 lodash cloneDeep 丢失 React DOM/原生 DOM 的问题,兼容多种特殊类型
|
|
16
|
+
* @param {object} schema 待克隆的 Formily Schema
|
|
17
|
+
* @returns {object} 克隆后的 Schema
|
|
18
|
+
*/
|
|
19
|
+
export function cloneSchema(schema) {
|
|
20
|
+
// 1. 基础类型(null/undefined/字符串/数字/布尔)直接返回
|
|
21
|
+
if (schema === null || typeof schema !== "object") {
|
|
22
|
+
return schema;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 2. React 虚拟DOM:直接保留原引用,不拷贝
|
|
26
|
+
if (React.isValidElement(schema)) {
|
|
27
|
+
return schema;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 3. 原生 HTML DOM 节点:直接保留原引用
|
|
31
|
+
if (isHtmlDomNode(schema)) {
|
|
32
|
+
return schema;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 4. 函数:Formily Schema 中的校验/格式化函数等,保留原引用
|
|
36
|
+
if (typeof schema === "function") {
|
|
37
|
+
return schema;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 5. 日期对象:创建新的 Date 实例,保证值相同但引用不同
|
|
41
|
+
if (schema instanceof Date) {
|
|
42
|
+
return new Date(schema.getTime());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 6. 正则对象:创建新的 RegExp 实例,保留源和标志
|
|
46
|
+
if (schema instanceof RegExp) {
|
|
47
|
+
return new RegExp(schema.source, schema.flags);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 7. 数组:递归克隆每一项
|
|
51
|
+
if (Array.isArray(schema)) {
|
|
52
|
+
return schema.map((item) => cloneSchema(item));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 8. 普通对象:递归克隆自有属性
|
|
56
|
+
const clonedObj = {};
|
|
57
|
+
for (const key in schema) {
|
|
58
|
+
if (Object.prototype.hasOwnProperty.call(schema, key)) {
|
|
59
|
+
clonedObj[key] = cloneSchema(schema[key]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return clonedObj;
|
|
63
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { observer } from "@formily/react";
|
|
2
|
-
import {
|
|
2
|
+
import { autorun, observable } from "@formily/reactive";
|
|
3
3
|
|
|
4
4
|
export function handleTableProps(field, { scope, value, record }) {
|
|
5
5
|
if (!field) {
|
|
@@ -45,6 +45,25 @@ export function getColRender(render) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* 根据 formily 函数字符串 {{xxx}},获取变量或可执行函数
|
|
50
|
+
* @param {*} funcStr
|
|
51
|
+
* @param {*} opt
|
|
52
|
+
* @returns
|
|
53
|
+
*/
|
|
54
|
+
export const getScopeVal = function (funcStr = "", opt = {}) {
|
|
55
|
+
if (typeof funcStr !== "string" || !funcStr.startsWith("{{")) {
|
|
56
|
+
return funcStr;
|
|
57
|
+
}
|
|
58
|
+
const stateStr = funcStr.replace(/^\{\{/, "").replace(/\}\}$/, "");
|
|
59
|
+
const res = opt?.scope?.[stateStr];
|
|
60
|
+
// 存在对应变量直接返回
|
|
61
|
+
if (res) {
|
|
62
|
+
return res;
|
|
63
|
+
}
|
|
64
|
+
return getFunc(stateStr, opt);
|
|
65
|
+
};
|
|
66
|
+
|
|
48
67
|
/**
|
|
49
68
|
* 根据 formily 函数字符串 {{xxx}},获取可执行函数
|
|
50
69
|
* @param {string} funcStr
|
|
@@ -52,8 +71,11 @@ export function getColRender(render) {
|
|
|
52
71
|
* @returns
|
|
53
72
|
*/
|
|
54
73
|
export function getStateFunc(funcStr = "", opt) {
|
|
74
|
+
if (typeof funcStr !== "string" || !funcStr.startsWith("{{")) {
|
|
75
|
+
return funcStr;
|
|
76
|
+
}
|
|
55
77
|
const stateStr = funcStr.replace(/^\{\{/, "").replace(/\}\}$/, "");
|
|
56
|
-
return getFunc(
|
|
78
|
+
return getFunc(stateStr, opt);
|
|
57
79
|
}
|
|
58
80
|
|
|
59
81
|
/**
|
|
@@ -79,7 +101,7 @@ export function getFunc(
|
|
|
79
101
|
"opt",
|
|
80
102
|
`const { ${Object.keys(_opt).join(", ")} } = opt || {}; const {${Object.keys(_opt.scope || {}).join(
|
|
81
103
|
", ",
|
|
82
|
-
)}} = scope || {}; ${funcStr}`,
|
|
104
|
+
)}} = scope || {}; return ${funcStr}; `,
|
|
83
105
|
);
|
|
84
106
|
|
|
85
107
|
return function (opt) {
|
|
@@ -100,8 +122,11 @@ export function getFunc(
|
|
|
100
122
|
* @returns
|
|
101
123
|
*/
|
|
102
124
|
export function getStateSyncFunc(funcStr = "", opt) {
|
|
125
|
+
if (typeof funcStr !== "string" || !funcStr.startsWith("{{")) {
|
|
126
|
+
return funcStr;
|
|
127
|
+
}
|
|
103
128
|
const stateStr = funcStr.replace(/^\{\{/, "").replace(/\}\}$/, "");
|
|
104
|
-
return getFuncSync(
|
|
129
|
+
return getFuncSync(stateStr, opt);
|
|
105
130
|
}
|
|
106
131
|
|
|
107
132
|
/**
|
|
@@ -134,7 +159,7 @@ export function getFuncSync(
|
|
|
134
159
|
"opt",
|
|
135
160
|
`try {const {${Object.keys(_opt).join(", ")}} = opt || {}; const {${Object.keys(_opt.scope || {}).join(
|
|
136
161
|
", ",
|
|
137
|
-
)}} = scope || {}; ${funcStr}} catch(err) {console.error("Error Formily Reactive Function: ", err);}`,
|
|
162
|
+
)}} = scope || {}; return ${funcStr}; } catch(err) {console.error("Error Formily Reactive Function: ", err);}`,
|
|
138
163
|
);
|
|
139
164
|
|
|
140
165
|
return function (opt) {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import _ from "lodash";
|
|
2
|
-
import { getFieldMap } from "./utils";
|
|
3
2
|
import {
|
|
4
3
|
isRunStr,
|
|
5
4
|
handleSchemaStrVal,
|
|
6
5
|
isScopeKey as formIsScopeKey,
|
|
7
6
|
getScopeKeyVal,
|
|
8
7
|
} from "@hzab/form-render/src/common/schema-handler";
|
|
8
|
+
import { cloneSchema } from "@hzab/utils/src/formily/cloneSchema";
|
|
9
9
|
import { URL_PARAM_NAME } from "./constant";
|
|
10
|
+
import { getFieldMap } from "./utils";
|
|
10
11
|
|
|
11
12
|
// ===================== 类型定义 =====================
|
|
12
13
|
|
|
@@ -72,7 +73,7 @@ export const handleQuerySchema = (opt) => {
|
|
|
72
73
|
index += 1;
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
const fieldMap = getFieldMap(
|
|
76
|
+
const fieldMap = getFieldMap(cloneSchema(schema));
|
|
76
77
|
filters?.forEach((key) => {
|
|
77
78
|
const item = fieldMap[key];
|
|
78
79
|
if (item) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { cloneDeep } from "lodash";
|
|
2
1
|
import { autorun, observable } from "@formily/reactive";
|
|
2
|
+
|
|
3
|
+
import { cloneSchema } from "@hzab/utils/src/formily/cloneSchema";
|
|
3
4
|
import { getStateFunc } from "./formily-utils";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -14,7 +15,7 @@ export function handleReactions(fieldList, opt = {}) {
|
|
|
14
15
|
return fieldList;
|
|
15
16
|
}
|
|
16
17
|
const resList = [];
|
|
17
|
-
|
|
18
|
+
cloneSchema(fieldList).forEach((item) => {
|
|
18
19
|
handleReaction(item, opt);
|
|
19
20
|
resList.push(item);
|
|
20
21
|
});
|
package/src/common/utils.js
CHANGED
|
@@ -1,279 +1,305 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
1
|
+
import { autorun, observable } from "@formily/reactive";
|
|
2
|
+
import { Schema } from "@formily/json-schema";
|
|
3
|
+
import _ from "lodash";
|
|
4
|
+
import dayjs from "dayjs";
|
|
5
|
+
import advancedFormat from "dayjs/plugin/advancedFormat";
|
|
6
|
+
import weekOfYear from "dayjs/plugin/weekOfYear";
|
|
7
|
+
|
|
8
|
+
import { cloneSchema } from "@hzab/utils/src/formily/cloneSchema";
|
|
9
|
+
import { getScopeVal } from "./formily-utils";
|
|
10
|
+
|
|
11
|
+
dayjs.extend(advancedFormat);
|
|
12
|
+
dayjs.extend(weekOfYear);
|
|
13
|
+
|
|
14
|
+
const dateFormatEnum = {
|
|
15
|
+
time: "YYYY-MM-DD HH:mm:ss",
|
|
16
|
+
date: "YYYY-MM-DD",
|
|
17
|
+
week: "YYYY年 w周",
|
|
18
|
+
quarter: "YYYY年 Q季度",
|
|
19
|
+
month: "YYYY-MM",
|
|
20
|
+
year: "YYYY",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 获取 field 对应的值
|
|
25
|
+
* @param {Object} field schema 项
|
|
26
|
+
* @param {Object} data 数据
|
|
27
|
+
* @param {Object} opt 配置项
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
export function getVal(field = {}, data = {}, opt = {}) {
|
|
31
|
+
const {} = opt;
|
|
32
|
+
let val = _.get(data, field.name);
|
|
33
|
+
const {} = field || {};
|
|
34
|
+
const xComponent = field["x-component"];
|
|
35
|
+
const xComponentProps = field["x-component-props"] || {};
|
|
36
|
+
|
|
37
|
+
if (val && (xComponent === "DatePicker" || xComponent === "DatePicker.RangePicker")) {
|
|
38
|
+
const { picker, showTime } = xComponentProps || {};
|
|
39
|
+
const mode = showTime === true ? "time" : picker || "date";
|
|
40
|
+
const _formatEnum = opt.dateFormatEnum || dateFormatEnum;
|
|
41
|
+
const format = xComponentProps?.format || _formatEnum[mode];
|
|
42
|
+
|
|
43
|
+
if (Array.isArray(val)) {
|
|
44
|
+
return val.map((it) => getDateVal(it, format)).join(" ~ ");
|
|
45
|
+
}
|
|
46
|
+
return getDateVal(val, format);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (val && (xComponent === "TimePicker" || xComponent === "TimePicker.RangePicker")) {
|
|
50
|
+
const format = xComponentProps?.format || "HH:mm:ss";
|
|
51
|
+
if (Array.isArray(val)) {
|
|
52
|
+
return val.map((it) => dayjs(it).format(format)).join(" ~ ");
|
|
53
|
+
}
|
|
54
|
+
return dayjs(val).format(format);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (xComponent === "Switch") {
|
|
58
|
+
if (val === undefined || val === false || val === field.inactiveValue) {
|
|
59
|
+
return field.inactiveText || "否";
|
|
60
|
+
}
|
|
61
|
+
if (val === true || val === field.activeValue) {
|
|
62
|
+
return field.activeText || "是";
|
|
63
|
+
}
|
|
64
|
+
return val;
|
|
65
|
+
}
|
|
66
|
+
if (typeof field.relation === "object") {
|
|
67
|
+
const { key, name, label } = field.relation;
|
|
68
|
+
return data[key]?.[name];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const dataSource = field?.dataSource || field.enum;
|
|
72
|
+
if (
|
|
73
|
+
(xComponent === "Select" || xComponent === "Radio.Group" || xComponent === "Checkbox.Group") &&
|
|
74
|
+
Array.isArray(dataSource)
|
|
75
|
+
) {
|
|
76
|
+
if (!Array.isArray(val)) {
|
|
77
|
+
return getFieldOptItByVal(val, field, opt)?.label || val;
|
|
78
|
+
} else if (Array.isArray(val)) {
|
|
79
|
+
let _val = [];
|
|
80
|
+
val.forEach((valIt) => {
|
|
81
|
+
_val.push(getFieldOptItByVal(val, field, opt)?.label || valIt);
|
|
82
|
+
});
|
|
83
|
+
val = _val;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (Array.isArray(val)) {
|
|
88
|
+
return val.join("、");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return val;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function getDateVal(val, format) {
|
|
95
|
+
return dayjs(val).format(format);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function getFieldList(_schema, fieldList = [], opt = {}, isTableSortXIdex = false) {
|
|
99
|
+
const schema = cloneSchema(_schema?.schema || _schema);
|
|
100
|
+
|
|
101
|
+
// 解决 schema 字符串可执行代码、变量等
|
|
102
|
+
const properties = Schema.getOrderProperties(schema);
|
|
103
|
+
const { boxList = [] } = opt || {};
|
|
104
|
+
let _boxList = ["FormGrid", "FormGrid.GridColumn"];
|
|
105
|
+
if (Array.isArray(boxList)) {
|
|
106
|
+
_boxList = [..._boxList, ...boxList];
|
|
107
|
+
} else if (boxList === false) {
|
|
108
|
+
_boxList = [];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
schema?.properties &&
|
|
112
|
+
properties.forEach((item) => {
|
|
113
|
+
const field = { ...item.schema };
|
|
114
|
+
if (!field.name) {
|
|
115
|
+
field.name = item.key;
|
|
116
|
+
}
|
|
117
|
+
const componentName = field["x-component"];
|
|
118
|
+
// 处理 title 渲染逻辑,解析 scope 字符串变量
|
|
119
|
+
if (typeof field.title === "string" && field.title.startsWith("{{")) {
|
|
120
|
+
field.title = getScopeVal(field.title, { scope: opt.schemaScope });
|
|
121
|
+
if (typeof field.title === "function") {
|
|
122
|
+
field.title = field.title({
|
|
123
|
+
...opt,
|
|
124
|
+
scope: opt.schemaScope,
|
|
125
|
+
scenario: "listRender",
|
|
126
|
+
// $deps,
|
|
127
|
+
$self: field,
|
|
128
|
+
$effect: autorun.effect,
|
|
129
|
+
// $form: $form,
|
|
130
|
+
// $values: $values,
|
|
131
|
+
$observable: observable,
|
|
132
|
+
$memo: autorun.memo,
|
|
133
|
+
$props: {
|
|
134
|
+
// formilyRef.current.fields formilyRef.current.fieldSchemas
|
|
135
|
+
formilyRef: opt.formilyRef,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (_boxList.includes(componentName)) {
|
|
141
|
+
getFieldList(field, fieldList, opt);
|
|
142
|
+
} else {
|
|
143
|
+
fieldList.push(field);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
isTableSortXIdex && fieldList.sort((a, b) => a["x-index"] - b["x-index"]);
|
|
147
|
+
return fieldList;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function getFieldMap(_schema, fieldMap = {}) {
|
|
151
|
+
// const fieldMap = _.keyBy(getFieldList(_schema), "name");
|
|
152
|
+
const schema = _schema?.schema || _schema;
|
|
153
|
+
schema?.properties &&
|
|
154
|
+
Object.keys(schema?.properties).forEach((key) => {
|
|
155
|
+
const field = schema?.properties[key];
|
|
156
|
+
if (field["x-component"] === "FormGrid") {
|
|
157
|
+
getFieldMap(field, fieldMap);
|
|
158
|
+
} else if (field["x-component"] === "FormGrid.GridColumn") {
|
|
159
|
+
getFieldMap(field, fieldMap);
|
|
160
|
+
} else {
|
|
161
|
+
fieldMap[key] = field;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
return fieldMap;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function objToFormData(data) {
|
|
169
|
+
const formData = new FormData();
|
|
170
|
+
Object.keys(data)?.forEach((key) => {
|
|
171
|
+
formData.set(key, data[key]);
|
|
172
|
+
});
|
|
173
|
+
return formData;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 根据 val 获取对应的 options 项数据
|
|
178
|
+
* @param {string|number|boolean} val
|
|
179
|
+
* @param {Object} field
|
|
180
|
+
*/
|
|
181
|
+
export const getFieldOptItByVal = function (val, field, opt) {
|
|
182
|
+
if (!field) {
|
|
183
|
+
return {};
|
|
184
|
+
}
|
|
185
|
+
const options = Array.isArray(field.enum)
|
|
186
|
+
? field.enum
|
|
187
|
+
: Array.isArray(field.options)
|
|
188
|
+
? field.options
|
|
189
|
+
: field.dataSource || [];
|
|
190
|
+
return getOptItByVal(val, options, {
|
|
191
|
+
fieldNames: field.fieldNames || field["x-component-props"]?.fieldNames,
|
|
192
|
+
...opt,
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* 根据 val 获取对应的 options 项数据,并进行数据归一化处理
|
|
198
|
+
* value, label, children
|
|
199
|
+
* @param {string|number|boolean} val
|
|
200
|
+
* @param {Object} field
|
|
201
|
+
*/
|
|
202
|
+
export const getOptItByVal = function (val, options, opt) {
|
|
203
|
+
const { fieldNames } = opt || {};
|
|
204
|
+
const { value = "value", label = "label", children = "children" } = fieldNames || {};
|
|
205
|
+
for (let i = 0; i < options.length; i++) {
|
|
206
|
+
const it = options[i];
|
|
207
|
+
if (it?.[value] === val) {
|
|
208
|
+
return {
|
|
209
|
+
...it,
|
|
210
|
+
value: it?.[value],
|
|
211
|
+
label: it?.[label],
|
|
212
|
+
children: it?.[children],
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// 递归处理
|
|
216
|
+
const _children = it?.[children];
|
|
217
|
+
if (Array.isArray(_children) && _children.length > 0) {
|
|
218
|
+
const child = getOptItByVal(val, _children, opt);
|
|
219
|
+
return {
|
|
220
|
+
...child,
|
|
221
|
+
value: child?.[value],
|
|
222
|
+
label: child?.[label],
|
|
223
|
+
children: child?.[children],
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* 移除 schema.properties 中包含 "inTable": false 的字段
|
|
231
|
+
* @param {Object} data - 原始数据对象
|
|
232
|
+
* @returns {Object} - 处理后的新对象
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* 移除表格中标记为inTable:false的字段
|
|
237
|
+
* @param {Object} data - 原始数据
|
|
238
|
+
* @param {Object} [opt={}] - 配置选项
|
|
239
|
+
* @param {Array} [opt.boxList=[]] - 需要递归处理的组件类型列表
|
|
240
|
+
* @returns {Object} 处理后的数据
|
|
241
|
+
*/
|
|
242
|
+
|
|
243
|
+
export function removeInTableFalseFields(_schema, opt = {}) {
|
|
244
|
+
// 1. 深拷贝原始数据
|
|
245
|
+
const result = cloneSchema(_schema);
|
|
246
|
+
|
|
247
|
+
// 2. 获取schema对象(支持直接传入schema或包含schema的对象)
|
|
248
|
+
const schema = result?.schema || result;
|
|
249
|
+
|
|
250
|
+
// 3. 处理容器组件配置
|
|
251
|
+
const { boxList = [] } = opt;
|
|
252
|
+
const _boxList =
|
|
253
|
+
boxList === false
|
|
254
|
+
? []
|
|
255
|
+
: [
|
|
256
|
+
"Card",
|
|
257
|
+
"FormGrid",
|
|
258
|
+
"ArrayCards",
|
|
259
|
+
"Collapse",
|
|
260
|
+
"Tabs",
|
|
261
|
+
"FormGrid.GridColumn",
|
|
262
|
+
...(Array.isArray(boxList) ? boxList : []),
|
|
263
|
+
];
|
|
264
|
+
|
|
265
|
+
// 4. 递归删除inTable:false的字段
|
|
266
|
+
const processProperties = (properties) => {
|
|
267
|
+
if (!properties || typeof properties !== "object") return;
|
|
268
|
+
|
|
269
|
+
Object.keys(properties).forEach((key) => {
|
|
270
|
+
const item = properties[key];
|
|
271
|
+
|
|
272
|
+
// 处理容器组件递归
|
|
273
|
+
if (item["x-component"] && _boxList.includes(item["x-component"])) {
|
|
274
|
+
if (item.properties) {
|
|
275
|
+
processProperties(item.properties);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// 处理数组类型的子项
|
|
279
|
+
else if (item.items?.properties) {
|
|
280
|
+
processProperties(item.items.properties);
|
|
281
|
+
}
|
|
282
|
+
// 处理普通字段
|
|
283
|
+
else if (item.inTable === false) {
|
|
284
|
+
delete properties[key];
|
|
285
|
+
}
|
|
286
|
+
// 移除x-display
|
|
287
|
+
else if (item["x-display"]) {
|
|
288
|
+
delete item["x-display"];
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// 5. 处理主properties
|
|
294
|
+
if (schema.properties) {
|
|
295
|
+
processProperties(schema.properties);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// 6. 移除form的布局属性
|
|
299
|
+
if (result.form) {
|
|
300
|
+
delete result.form.labelCol;
|
|
301
|
+
delete result.form.wrapperCol;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
@@ -15,7 +15,7 @@ export interface Item {
|
|
|
15
15
|
|
|
16
16
|
export interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
|
|
17
17
|
SchemaField: any;
|
|
18
|
-
|
|
18
|
+
getField: () => {
|
|
19
19
|
type: string;
|
|
20
20
|
name: string;
|
|
21
21
|
};
|
|
@@ -38,7 +38,7 @@ export interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
38
38
|
|
|
39
39
|
export const EditableCell: React.FC<EditableCellProps> = ({
|
|
40
40
|
SchemaField,
|
|
41
|
-
|
|
41
|
+
getField,
|
|
42
42
|
editing,
|
|
43
43
|
dataIndex,
|
|
44
44
|
title,
|
|
@@ -53,6 +53,7 @@ export const EditableCell: React.FC<EditableCellProps> = ({
|
|
|
53
53
|
children,
|
|
54
54
|
...restProps
|
|
55
55
|
}) => {
|
|
56
|
+
const field = getField && getField();
|
|
56
57
|
const fPattern = field?.["x-pattern"];
|
|
57
58
|
const fDisplay = field?.["x-display"];
|
|
58
59
|
const { editMode = "modal" } = topProps || {};
|
|
@@ -80,7 +81,7 @@ export const EditableCell: React.FC<EditableCellProps> = ({
|
|
|
80
81
|
schema={{
|
|
81
82
|
type: "object",
|
|
82
83
|
properties: {
|
|
83
|
-
[field
|
|
84
|
+
[field?.name]: {
|
|
84
85
|
...field,
|
|
85
86
|
title: "",
|
|
86
87
|
["x-component-props"]: {
|
|
@@ -195,6 +196,9 @@ export const useEditTable = (props) => {
|
|
|
195
196
|
const onEdit = async (record: Partial<Item> & { key: React.Key }, key, opt = { fieldRef: null }) => {
|
|
196
197
|
const { fieldRef } = opt || {};
|
|
197
198
|
editingFiledRef.current = fieldRef;
|
|
199
|
+
// 清除上一次的数据,解决切换表单数据未清除问题
|
|
200
|
+
// TODO: 拆分表单解决
|
|
201
|
+
formRender.values = {};
|
|
198
202
|
formRender?.setValues(record);
|
|
199
203
|
setEditingId(record[idKey]);
|
|
200
204
|
setEditingKey(key);
|
|
@@ -222,7 +226,7 @@ export const useEditTable = (props) => {
|
|
|
222
226
|
try {
|
|
223
227
|
// 点击保存,数据抛出
|
|
224
228
|
(await formRender?.validate()) as Item;
|
|
225
|
-
onEditSubmit && (await onEditSubmit(formRender.values, { field }
|
|
229
|
+
onEditSubmit && (await onEditSubmit(formRender.values, { field }));
|
|
226
230
|
// 清除编辑目标
|
|
227
231
|
setEditingId("");
|
|
228
232
|
setEditingKey("");
|
|
@@ -243,7 +247,8 @@ export const useEditTable = (props) => {
|
|
|
243
247
|
...(col.onCell ? col.onCell(record, ...args) : {}),
|
|
244
248
|
record,
|
|
245
249
|
SchemaField,
|
|
246
|
-
|
|
250
|
+
// 函数获取解决 cloneDepp 报错问题
|
|
251
|
+
getField: col.getField,
|
|
247
252
|
dataIndex: col.dataIndex,
|
|
248
253
|
title: col.title,
|
|
249
254
|
editable: col.editable,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { memo,
|
|
1
|
+
import { memo, useMemo, useCallback } from "react";
|
|
2
2
|
import { createForm } from "@formily/core";
|
|
3
|
-
import {
|
|
3
|
+
import { antdComponents, customComponents } from "@hzab/form-render";
|
|
4
|
+
import { createSchemaField, useField, useFieldSchema, Schema } from "@formily/react";
|
|
4
5
|
import { Form } from "c-formily-antd";
|
|
5
|
-
import {
|
|
6
|
+
import { cloneSchema } from "@hzab/utils/src/formily/cloneSchema";
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
+
import { handleReaction } from "../../common/handleReactions";
|
|
8
9
|
|
|
9
10
|
type formilyFieldPropsT = {
|
|
10
11
|
schema: Schema;
|
|
@@ -19,6 +20,17 @@ type formilyFieldPropsT = {
|
|
|
19
20
|
export const FormilyField = memo(function (props: formilyFieldPropsT) {
|
|
20
21
|
const { schema, formilyRef, schemaScope, components, reactionOpts } = props;
|
|
21
22
|
const { fields, fieldSchemas } = formilyRef.current || {};
|
|
23
|
+
const _schema = useMemo(() => {
|
|
24
|
+
const schemaRmInTable = cloneSchema(schema);
|
|
25
|
+
// 去除 inTable = false 的字段
|
|
26
|
+
schemaRmInTable?.properties &&
|
|
27
|
+
Object.keys(schemaRmInTable?.properties)?.forEach((key) => {
|
|
28
|
+
if (schemaRmInTable?.properties?.[key]?.inTable === false) {
|
|
29
|
+
delete schemaRmInTable?.properties?.[key];
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return schemaRmInTable;
|
|
33
|
+
}, [schema]);
|
|
22
34
|
const SchemaField = useCallback(
|
|
23
35
|
createSchemaField({
|
|
24
36
|
// @ts-ignore
|
|
@@ -38,7 +50,7 @@ export const FormilyField = memo(function (props: formilyFieldPropsT) {
|
|
|
38
50
|
return Com && <Com {...props} />;
|
|
39
51
|
},
|
|
40
52
|
},
|
|
41
|
-
scope: { ...schemaScope },
|
|
53
|
+
scope: { ...schemaScope, scenario: "tableReactionsForm" },
|
|
42
54
|
} as any),
|
|
43
55
|
[],
|
|
44
56
|
);
|
|
@@ -60,7 +72,7 @@ export const FormilyField = memo(function (props: formilyFieldPropsT) {
|
|
|
60
72
|
style={{ display: "none", width: 0, height: 0, overflow: "hidden" }}
|
|
61
73
|
form={formRender}
|
|
62
74
|
>
|
|
63
|
-
<SchemaField schema={
|
|
75
|
+
<SchemaField schema={_schema}></SchemaField>
|
|
64
76
|
</Form>
|
|
65
77
|
);
|
|
66
78
|
});
|
package/src/list-render.jsx
CHANGED
|
@@ -512,7 +512,7 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
512
512
|
setShowSearch={handleSetShowSearch}
|
|
513
513
|
loading={listLoading}
|
|
514
514
|
tableProps={props.tableProps}
|
|
515
|
-
getFieldListOpt={props.getFieldListOpt}
|
|
515
|
+
getFieldListOpt={{ ...props.getFieldListOpt, schemaScope: props.schemaScope }}
|
|
516
516
|
components={props.components}
|
|
517
517
|
schemaScope={props.schemaScope}
|
|
518
518
|
i18n={i18n}
|
|
@@ -4,10 +4,10 @@ import dayjs from "dayjs";
|
|
|
4
4
|
import _ from "lodash";
|
|
5
5
|
|
|
6
6
|
import FormRender from "@hzab/form-render";
|
|
7
|
+
import { cloneSchema } from "@hzab/utils/src/formily/cloneSchema";
|
|
7
8
|
import { handleQuerySchema } from "../common/handleQuerySchema";
|
|
8
9
|
|
|
9
10
|
import "./index.less";
|
|
10
|
-
import { onFieldValueChange } from "@formily/core";
|
|
11
11
|
|
|
12
12
|
function QueryRender(props, parentRef) {
|
|
13
13
|
const [schema, setSchema] = useState({});
|
|
@@ -20,7 +20,7 @@ function QueryRender(props, parentRef) {
|
|
|
20
20
|
handleQuerySchema({
|
|
21
21
|
...props?.config,
|
|
22
22
|
schemaScope: { ...props.schemaScope, scenario: "query" },
|
|
23
|
-
schema:
|
|
23
|
+
schema: cloneSchema(props.schema),
|
|
24
24
|
search: props.search,
|
|
25
25
|
filters: _.cloneDeep(props.filters),
|
|
26
26
|
onSearch,
|
|
@@ -102,7 +102,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
102
102
|
if (!(props.schema && props.schema.properties)) {
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
|
-
const fieldList = getFieldList(props.schema, [], props.getFieldListOpt, isTableSortXIdex);
|
|
105
|
+
const fieldList = getFieldList(props.schema, [], { ...props.getFieldListOpt, formilyRef }, isTableSortXIdex);
|
|
106
106
|
const columns = [];
|
|
107
107
|
|
|
108
108
|
// 序号列
|
|
@@ -218,12 +218,14 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
columns.push({
|
|
221
|
-
field,
|
|
221
|
+
// field, // HACK: 直接传入 field 在 title 传入 ReactNode,内部深克隆导致页面报错白屏。使用函数获取解决
|
|
222
|
+
getField: () => field,
|
|
222
223
|
editable: true,
|
|
223
224
|
..._colConf,
|
|
224
225
|
onCell: (record, rowIndex) =>
|
|
225
226
|
_colConf?.onCell?.({ ...record, _field: { ...field, ...(fieldSchemas?.[name] || {}) } }, rowIndex) || {},
|
|
226
|
-
|
|
227
|
+
// 函数式传入,解决 title ReactNode 传入报错问题
|
|
228
|
+
title: () => (isFunction(_colConf?.title) ? _colConf?.title() : _title),
|
|
227
229
|
key: name,
|
|
228
230
|
dataIndex: name,
|
|
229
231
|
render: getColRender(colRender),
|
|
@@ -426,7 +428,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
426
428
|
<Table {...tableProps} />
|
|
427
429
|
)}
|
|
428
430
|
<FormilyField
|
|
429
|
-
schema={
|
|
431
|
+
schema={topProps.schema}
|
|
430
432
|
formilyRef={formilyRef}
|
|
431
433
|
components={props.components}
|
|
432
434
|
schemaScope={{
|