@lingxiteam/ebe-utils 0.1.26 → 0.1.27

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.
@@ -1,8 +1,18 @@
1
- import { updateNodeChildren } from './formUtils';
1
+ import { useContext } from 'react';
2
+ import { Context } from './Context/context';
3
+ import {
4
+ getAllForm,
5
+ getBoframerOwnForms,
6
+ getBOFramerOwnFormValues,
7
+ getFieldsValue,
8
+ getFormByCompId,
9
+ getOwnFormValues,
10
+ updateNodeChildren,
11
+ } from './formUtils';
2
12
 
3
13
  const toBool = (v: string | boolean, defaultValue?: any) => {
4
14
  let val = v;
5
- if ([null, undefined].includes(val as any) && defaultValue !== undefined) {
15
+ if ([null, undefined].includes(val) && defaultValue !== undefined) {
6
16
  val = defaultValue;
7
17
  }
8
18
 
@@ -25,6 +35,8 @@ export interface ToolsContext {
25
35
  }
26
36
 
27
37
  export const useTool = (refs: Record<string, any>, context: ToolsContext) => {
38
+ const { refs: renderRefs } = useContext(Context);
39
+
28
40
  const { addToAwaitQueue } = context;
29
41
 
30
42
  const asyncGetValue = (id: string, stateName?: string) => {
@@ -195,6 +207,157 @@ export const useTool = (refs: Record<string, any>, context: ToolsContext) => {
195
207
  }
196
208
  });
197
209
 
210
+ /**
211
+ * 获取当前表单值
212
+ */
213
+ const getFormValue = async (compId: string): Promise<any> => {
214
+ // 为了兼容动态渲染引擎,表单不存在 就返回空对象
215
+ if (!refs[compId]) return Promise.resolve({});
216
+
217
+ // 表单的情况 可能是循环容器
218
+ if (refs[compId].compName === 'Form') {
219
+ const forms = getFormByCompId(compId, refs);
220
+ return getFieldsValue(forms, (form) => {
221
+ return form?.getFieldsValue?.();
222
+ });
223
+ }
224
+
225
+ if (refs[compId].compName === 'BOFramer') {
226
+ return getBOFramerOwnFormValues(
227
+ {
228
+ refs,
229
+ renderRefs,
230
+ compId,
231
+ },
232
+ (form) => form?.getFieldsValue?.(),
233
+ );
234
+ }
235
+
236
+ return Promise.reject(
237
+ new Error('该组件不支持使用getFormValues获取表单数据'),
238
+ );
239
+ };
240
+
241
+ /**
242
+ * 验证并取值
243
+ * @param compId
244
+ */
245
+ const validateForm = async (compId: string): Promise<any> => {
246
+ // 为了兼容动态渲染引擎,表单不存在 就返回空对象
247
+ if (!refs[compId]) return Promise.resolve({});
248
+
249
+ // 表单的情况 可能是循环容器
250
+ if (refs[compId].compName === 'Form') {
251
+ const forms = getFormByCompId(compId, refs);
252
+ return getFieldsValue(forms, (form) => {
253
+ return form?.validateFormAndScroll?.();
254
+ });
255
+ }
256
+
257
+ if (refs[compId].compName === 'BOFramer') {
258
+ return getBOFramerOwnFormValues(
259
+ {
260
+ refs,
261
+ renderRefs,
262
+ compId,
263
+ },
264
+ (form) => form?.validateFormAndScroll?.(),
265
+ );
266
+ }
267
+ return Promise.reject(
268
+ new Error('该组件不支持使用getFormValues获取表单数据'),
269
+ );
270
+ };
271
+
272
+ /**
273
+ * 重置表单值
274
+ * @param compId
275
+ */
276
+ const resetForm = (compId: string) => {
277
+ if (!refs[compId]) return;
278
+ const compName = refs[compId].compName;
279
+ if (compName === 'BOFramer') {
280
+ const forms = getBoframerOwnForms({
281
+ currentRefs: refs,
282
+ renderRefs,
283
+ compId,
284
+ });
285
+
286
+ forms.forEach((form) => {
287
+ form?.resetFields?.();
288
+ });
289
+ } else {
290
+ const forms = getFormByCompId(compId, refs);
291
+ // 支持循环容器中的表单重置
292
+ (Array.isArray(forms) ? forms : [forms]).forEach((form) =>
293
+ form?.resetFields(),
294
+ );
295
+ }
296
+ };
297
+
298
+ /**
299
+ * 设置表单值
300
+ * @param compId 组件id
301
+ * @param formValues 表单值
302
+ */
303
+ const setFormValues = (
304
+ compId: string,
305
+ formValues: Record<string, any> = {},
306
+ ) => {
307
+ if (!refs[compId]) return;
308
+ const compName = refs[compId].compName;
309
+
310
+ if (compName === 'BOFramer') {
311
+ const forms = getBoframerOwnForms({
312
+ currentRefs: refs,
313
+ renderRefs,
314
+ compId,
315
+ });
316
+
317
+ forms.forEach((form) => {
318
+ form?.setFieldsValue(formValues);
319
+ });
320
+ } else {
321
+ refs[compId]?.setFieldsValue?.(formValues);
322
+ }
323
+ };
324
+
325
+ /**
326
+ * 校验并获取所有表单值
327
+ * 获取页面下的所有表单,包含当前页面下的表单、页面容器下的表单、业务组件下的表单。
328
+ * 不包含所有弹窗类组件的表单数据
329
+ */
330
+ const validateAllForm = () =>
331
+ getOwnFormValues({ currentRefs: refs, renderRefs }, (form) =>
332
+ form.validateFormAndScroll?.(false),
333
+ );
334
+
335
+ /**
336
+ * 获取所有表单值 但不校验
337
+ * 获取页面下的所有表单,包含当前页面下的表单、页面容器下的表单、业务组件下的表单。
338
+ * 不包含所有弹窗类组件的表单数据
339
+ */
340
+ const getAllFormValues = () =>
341
+ getOwnFormValues({ currentRefs: refs, renderRefs }, (form) =>
342
+ form.getFieldsValue?.(),
343
+ );
344
+
345
+ /**
346
+ * 重置所有表单
347
+ * 获取页面下的所有表单,包含当前页面下的表单、页面容器下的表单、业务组件下的表单。
348
+ * 不包含所有弹窗类组件的表单数据
349
+ */
350
+ const resetAllForm = () => {
351
+ const forms = getAllForm({
352
+ currentRefs: refs,
353
+ renderRefs,
354
+ });
355
+
356
+ forms.forEach((form) => {
357
+ form.resetFields();
358
+ });
359
+ };
360
+
198
361
  /**
199
362
  * 获取联动数据值
200
363
  * @param attrDataMap 静态数据
@@ -250,8 +413,15 @@ export const useTool = (refs: Record<string, any>, context: ToolsContext) => {
250
413
  callComponentMethod,
251
414
  setDisabled,
252
415
  getDisabled,
416
+ getFormValue,
417
+ validateForm,
418
+ resetForm,
253
419
  clearValue,
420
+ setFormValues,
254
421
  asyncCallComponentMethod,
422
+ validateAllForm,
423
+ getAllFormValues,
424
+ resetAllForm,
255
425
  updateNodeChildren,
256
426
  getTriggerRelDataSource,
257
427
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingxiteam/ebe-utils",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "author": "",
@@ -17,9 +17,9 @@
17
17
  "@babel/parser": "^7.12.12",
18
18
  "@babel/traverse": "^7.12.12",
19
19
  "@babel/types": "^7.12.12",
20
- "@lingxiteam/ebe": "0.1.26",
21
20
  "cac": "^6.7.14",
22
- "fs-extra": "9.x"
21
+ "fs-extra": "9.x",
22
+ "@lingxiteam/ebe": "0.1.27"
23
23
  },
24
24
  "publishConfig": {
25
25
  "access": "public"
@@ -1,43 +0,0 @@
1
- .cust-icon-ed {
2
- width: 16px;
3
- height: 16px;
4
- font-size: 16px;
5
- svg {
6
- width: 1em;
7
- height: 1em;
8
- }
9
- }
10
- .cust-icon-theme {
11
- fill: var(--adm-color-primary);
12
- color: var(--adm-color-primary);
13
- }
14
-
15
- .cust-icon-ed-xxs {
16
- width: 12px;
17
- height: 12px;
18
- font-size: 12px;
19
- }
20
-
21
- .cust-icon-ed-xs {
22
- width: 16px;
23
- height: 16px;
24
- font-size: 16px;
25
- }
26
-
27
- .cust-icon-ed-sm {
28
- width: 20px;
29
- height: 20px;
30
- font-size: 20px;
31
- }
32
-
33
- .cust-icon-ed-md {
34
- width: 24px;
35
- height: 24px;
36
- font-size: 24px;
37
- }
38
-
39
- .cust-icon-ed-lg {
40
- width: 36px;
41
- height: 36px;
42
- font-size: 36px;
43
- }
@@ -1,290 +0,0 @@
1
- import { createFromIconfontCN } from '@ant-design/icons';
2
- import { Icon as LegacyIcon } from '@lingxiteam/icons';
3
- import { LingXiEdFC } from '@lingxiteam/types';
4
- import classnames from 'classnames';
5
- import { useEffect, useMemo, useState } from 'react';
6
- import './index.less';
7
-
8
- export interface IconFileEDProps {
9
- fileId: string;
10
- fileCode: string;
11
- fileSubType: 'ICON_IMAGE' | 'ICONFONT';
12
- }
13
-
14
- export interface MyIconEDProps {
15
- type?: string;
16
- isIconFont?: boolean;
17
- fontAddress?: string;
18
- svgContent?: string;
19
- theme?: string;
20
- iconFileInfo?: any;
21
- iconFile?: IconFileEDProps;
22
- }
23
-
24
- export interface IconEDProps {
25
- icon?: MyIconEDProps;
26
- type?: string;
27
- isIconFont?: boolean;
28
- fontAddress?: string;
29
- svgContent?: string;
30
- theme?: string;
31
- style?: any;
32
- className?: any;
33
- rotate?: any;
34
- iconFileInfo?: any;
35
- iconFile?: IconFileEDProps;
36
- size?: any;
37
- color?: any;
38
- mode?: string;
39
- iconItems?: any;
40
- isUsePrimary?: boolean;
41
- }
42
-
43
- const IconED: LingXiEdFC<IconEDProps> = (props) => {
44
- const {
45
- icon = {},
46
- type,
47
- rotate,
48
- size,
49
- style,
50
- mode,
51
- iconItems,
52
- isUsePrimary: curIsUsePrimary,
53
- theme: curTheme,
54
- isIconFont: curIsIconFont,
55
- fontAddress: curFontAddress,
56
- svgContent: curSvgContent,
57
- iconFileInfo: curIconFileInfo,
58
- iconFile: curIconFile,
59
- getEdEngineApi,
60
- $$componentItem,
61
- ...restProps
62
- } = props;
63
- const [scriptUrl, setScripUrl] = useState<any>();
64
-
65
- const {
66
- curType,
67
- iconFile,
68
- iconFileInfo,
69
- fontAddress,
70
- isIconFont,
71
- theme,
72
- svgContent,
73
- isUsePrimary,
74
- color,
75
- } = useMemo(() => {
76
- const iconInfo = Array.isArray(iconItems) && iconItems[0];
77
- if (mode === 'custom' && iconInfo) {
78
- return {
79
- curType: iconInfo?.icon?.type,
80
- theme: iconInfo?.icon?.theme,
81
- isIconFont: iconInfo?.icon?.isIconFont,
82
- fontAddress: iconInfo?.icon?.fontAddress,
83
- svgContent: iconInfo?.icon?.svgContent,
84
- iconFileInfo: iconInfo?.icon?.iconFileInfo,
85
- iconFile: iconInfo?.icon?.iconFile,
86
- isUsePrimary: iconInfo?.isUsePrimary,
87
- color: iconInfo?.color,
88
- };
89
- }
90
- return {
91
- curType: icon?.type || type,
92
- iconFile: icon?.iconFile || curIconFile,
93
- iconFileInfo: icon?.iconFileInfo || curIconFileInfo,
94
- fontAddress: icon?.fontAddress || curFontAddress,
95
- isIconFont: icon?.isIconFont || curIsIconFont,
96
- theme: icon?.theme || curTheme,
97
- svgContent: icon?.svgContent || curSvgContent,
98
- };
99
- }, [
100
- JSON.stringify(icon),
101
- type,
102
- curIconFile,
103
- curIconFileInfo,
104
- curFontAddress,
105
- curIsIconFont,
106
- curTheme,
107
- curSvgContent,
108
- mode,
109
- iconItems,
110
- ]);
111
-
112
- useEffect(() => {
113
- if (iconFile) {
114
- const { fileId, fileCode, fileHttp } = iconFile;
115
- (async () => {
116
- const { getAppFileUrlById, getAppFileUrlByFileCode } =
117
- getEdEngineApi?.() || {};
118
- if (fileId && getAppFileUrlById) {
119
- setScripUrl(getAppFileUrlById(fileId));
120
- } else if (fileCode && getAppFileUrlByFileCode) {
121
- setScripUrl(
122
- getAppFileUrlByFileCode({
123
- appId: $$componentItem?.appId || window.appId,
124
- fileCode,
125
- }),
126
- );
127
- } else if (fileHttp) {
128
- setScripUrl(fileHttp);
129
- }
130
- })();
131
- } else if (fontAddress) {
132
- setScripUrl(fontAddress);
133
- } else if (iconFileInfo && !iconFileInfo.svgContent) {
134
- const { getMaterialFile } = getEdEngineApi?.() || {};
135
- (async () => {
136
- if (iconFileInfo.materialId && iconFileInfo.fileName) {
137
- setScripUrl(
138
- getMaterialFile({
139
- materialId: iconFileInfo.materialId,
140
- fileName: iconFileInfo.fileName,
141
- }),
142
- );
143
- }
144
- })();
145
- } else {
146
- setScripUrl('');
147
- }
148
- }, [iconFile, fontAddress, iconFileInfo]);
149
-
150
- const curClassName = classnames({
151
- [restProps?.className]: restProps?.className,
152
- 'cust-icon-ed': true,
153
- 'cust-icon-theme': isUsePrimary,
154
- [`cust-icon-ed-${size}`]: size,
155
- });
156
- const curStyle = useMemo(
157
- () => ({
158
- width: style?.fontSize || style?.width,
159
- height: style?.fontSize || style?.height,
160
- fontSize: style?.fontSize || style?.width, // 兼容存量数据
161
- ...(style || {}),
162
- color: isUsePrimary
163
- ? undefined
164
- : color || style?.color || restProps?.color,
165
- fill: isUsePrimary
166
- ? undefined
167
- : color || style?.color || restProps?.color,
168
- }),
169
- [isUsePrimary, style, color],
170
- );
171
-
172
- if (svgContent) {
173
- return (
174
- <div
175
- className={curClassName}
176
- style={{
177
- ...curStyle,
178
- transform: `rotate(${rotate}deg)`,
179
- }}
180
- // eslint-disable-next-line react/no-danger
181
- dangerouslySetInnerHTML={{
182
- __html: svgContent,
183
- }}
184
- />
185
- );
186
- }
187
-
188
- if (curType) {
189
- if (fontAddress || iconFile?.fileSubType === 'ICONFONT' || isIconFont) {
190
- if (scriptUrl) {
191
- const IconFont = createFromIconfontCN({
192
- scriptUrl,
193
- });
194
- return (
195
- <IconFont
196
- type={curType}
197
- rotate={rotate}
198
- {...restProps}
199
- style={curStyle}
200
- className={curClassName}
201
- />
202
- );
203
- }
204
- if (!fontAddress) {
205
- // 采用项目本地的iconfont文件
206
- return (
207
- <svg
208
- style={{
209
- ...curStyle,
210
- transform: `rotate(${rotate}deg)`,
211
- }}
212
- aria-hidden="true"
213
- className={curClassName}
214
- >
215
- <use xlinkHref={`#${curType}`} />
216
- </svg>
217
- );
218
- }
219
- } else if (
220
- theme &&
221
- !['cross-circle', 'cross-circle-o'].includes(curType) &&
222
- Object.keys(iconFileInfo || {})?.length < 1
223
- ) {
224
- // 兼容原来的antd-mobile的图标
225
- return (
226
- <LegacyIcon
227
- type={curType}
228
- rotate={rotate}
229
- theme={theme}
230
- {...restProps}
231
- style={curStyle}
232
- className={curClassName}
233
- />
234
- );
235
- } else if (iconFileInfo && Object.keys(iconFileInfo)?.length > 0) {
236
- if (iconFileInfo.svgContent) {
237
- return (
238
- <div
239
- className={curClassName}
240
- style={{
241
- ...curStyle,
242
- transform: `rotate(${rotate}deg)`,
243
- }}
244
- // eslint-disable-next-line react/no-danger
245
- dangerouslySetInnerHTML={{ __html: iconFileInfo.svgContent }}
246
- />
247
- );
248
- }
249
- return (
250
- <img
251
- className={curClassName}
252
- style={{
253
- ...curStyle,
254
- transform: `rotate(${rotate}deg)`,
255
- }}
256
- src={scriptUrl}
257
- alt=""
258
- />
259
- );
260
- } else if (curType) {
261
- return (
262
- <LegacyIcon
263
- type={curType}
264
- rotate={rotate}
265
- theme={theme}
266
- {...restProps}
267
- style={curStyle}
268
- className={curClassName}
269
- />
270
- );
271
- }
272
- }
273
- if (iconFile?.fileSubType === 'ICON_IMAGE' && scriptUrl) {
274
- return (
275
- <img
276
- alt="图片格式错误"
277
- src={scriptUrl}
278
- {...restProps}
279
- style={{
280
- ...curStyle,
281
- transform: `rotate(${rotate}deg)`,
282
- }}
283
- className={curClassName}
284
- />
285
- );
286
- }
287
- return null;
288
- };
289
-
290
- export default IconED;