@hzab/form-render 1.6.18 → 1.6.19

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +239 -239
  3. package/package.json +57 -57
  4. package/src/common/formily-utils.ts +125 -125
  5. package/src/common/schema-handler.ts +253 -253
  6. package/src/common/schema-merge.ts +68 -68
  7. package/src/components/ArrayBase/index.tsx +349 -349
  8. package/src/components/ArrayBase/style.less +90 -90
  9. package/src/components/ArrayBase/style.ts +2 -2
  10. package/src/components/ArrayCards/index.tsx +149 -149
  11. package/src/components/ArrayCards/style.less +14 -14
  12. package/src/components/ArrayCards/style.ts +4 -4
  13. package/src/components/ArrayTable/index.tsx +411 -411
  14. package/src/components/ArrayTable/style.less +52 -52
  15. package/src/components/ArrayTable/style.ts +7 -7
  16. package/src/components/DatePicker/index.tsx +108 -108
  17. package/src/components/LocationListPicker/assets/icon.js +1 -1
  18. package/src/components/LocationListPicker/components/AddrList/index.less +55 -55
  19. package/src/components/LocationListPicker/components/AddrList/index.tsx +75 -75
  20. package/src/components/LocationListPicker/components/Popup/address.schema.json +21 -21
  21. package/src/components/LocationListPicker/components/Popup/index.less +22 -22
  22. package/src/components/LocationListPicker/components/Popup/index.tsx +92 -92
  23. package/src/components/LocationListPicker/index.less +34 -34
  24. package/src/components/LocationListPicker/index.tsx +521 -520
  25. package/src/components/LocationPicker/Map/AMap/common/loader.ts +58 -58
  26. package/src/components/LocationPicker/Map/AMap/common/utils.ts +431 -431
  27. package/src/components/LocationPicker/Map/AMap/index.jsx +51 -51
  28. package/src/components/LocationPicker/README.md +44 -44
  29. package/src/components/LocationPicker/common/utils.ts +30 -30
  30. package/src/components/LocationPicker/components/ModalContent/index.tsx +387 -387
  31. package/src/components/LocationPicker/components/PickerInfo/index.tsx +109 -109
  32. package/src/components/LocationPicker/components/ResInfo/index.less +38 -38
  33. package/src/components/LocationPicker/components/ResInfo/index.tsx +65 -65
  34. package/src/components/LocationPicker/index.tsx +197 -197
  35. package/src/components/PersonnelSelect/index.less +21 -21
  36. package/src/components/PersonnelSelect/index.module.less +33 -33
  37. package/src/components/PersonnelSelect/type.ts +92 -92
  38. package/src/components/RichEditor/index.less +38 -38
  39. package/src/components/RichEditor/index.tsx +238 -238
  40. package/src/components/TreeCheckbox/components/CheckboxTable/index.tsx +55 -55
  41. package/src/components/TreeCheckbox/components/TabsRender/index.tsx +58 -58
  42. package/src/components/TreeCheckbox/index.less +12 -12
  43. package/src/components/TreeCheckbox/index.tsx +63 -63
  44. package/src/components/Upload/README.md +64 -64
  45. package/src/components/Upload/common/OfflineUpload.ts +339 -339
  46. package/src/components/Upload/common/customRequest.ts +81 -81
  47. package/src/components/Upload/common/fileName.ts +142 -142
  48. package/src/components/Upload/common/handleIOFileList.ts +393 -393
  49. package/src/components/Upload/common/nanoid.ts +7 -7
  50. package/src/components/Upload/common/ossUpload.js +159 -159
  51. package/src/components/Upload/common/utils.js +194 -194
  52. package/src/components/Upload/components/ItemList/index.tsx +52 -52
  53. package/src/components/Upload/components/PreviewModal/previewRender.tsx +80 -80
  54. package/src/components/Upload/index.tsx +17 -17
  55. package/src/components/Upload/uploader-input.jsx +187 -187
  56. package/src/components/Upload/uploader.jsx +316 -316
  57. package/src/components/UserSelect/index.tsx +123 -123
  58. package/src/components/index.tsx +17 -17
  59. package/src/index.tsx +198 -198
@@ -1,39 +1,39 @@
1
- .wang-editor-warpper {
2
- display: flex;
3
- flex-direction: column;
4
- height: 100%;
5
- position: relative;
6
-
7
- .spin-content {
8
- position: absolute;
9
- top: 0;
10
- left: 0;
11
- right: 0;
12
- bottom: 0;
13
- z-index: 1000;
14
- display: flex;
15
- align-items: center;
16
- justify-content: center;
17
- background: rgba(255, 255, 255, .6);
18
- }
19
-
20
- .wang-editor-container {
21
- flex: 1;
22
- width: 100%;
23
- position: relative;
24
-
25
- .wang-editor-scroll {
26
- position: absolute;
27
- top: 0;
28
- left: 0;
29
- bottom: 0;
30
- right: 0;
31
- overflow-x: hidden;
32
- overflow-y: scroll;
33
-
34
- .w-e-text-container {
35
- min-height: 100%;
36
- }
37
- }
38
- }
1
+ .wang-editor-warpper {
2
+ display: flex;
3
+ flex-direction: column;
4
+ height: 100%;
5
+ position: relative;
6
+
7
+ .spin-content {
8
+ position: absolute;
9
+ top: 0;
10
+ left: 0;
11
+ right: 0;
12
+ bottom: 0;
13
+ z-index: 1000;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ background: rgba(255, 255, 255, .6);
18
+ }
19
+
20
+ .wang-editor-container {
21
+ flex: 1;
22
+ width: 100%;
23
+ position: relative;
24
+
25
+ .wang-editor-scroll {
26
+ position: absolute;
27
+ top: 0;
28
+ left: 0;
29
+ bottom: 0;
30
+ right: 0;
31
+ overflow-x: hidden;
32
+ overflow-y: scroll;
33
+
34
+ .w-e-text-container {
35
+ min-height: 100%;
36
+ }
37
+ }
38
+ }
39
39
  }
@@ -1,238 +1,238 @@
1
- import "@wangeditor/editor/dist/css/style.css"; // 引入 css
2
- import React, { useState, useEffect, useImperativeHandle, forwardRef } from "react";
3
- import { Editor as WangEditor, Toolbar } from "@wangeditor/editor-for-react";
4
- import { IDomEditor, IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
5
- import { getOssUploadRequest, getOfflineUploadRequest } from "../Upload/common/customRequest";
6
- import { handlePreviewUrls } from "../Upload/common/OfflineUpload";
7
- import "./index.less";
8
- import { Spin, message } from "antd";
9
- import { connect, mapProps, observer, useField } from "@formily/react";
10
- import { merge } from "lodash";
11
- interface AnyObject {
12
- [key: string]: any;
13
- }
14
-
15
- interface PropsType {
16
- toolbarConfig?: Partial<IToolbarConfig>;
17
- editorConfig?: Partial<IEditorConfig>;
18
- ossOpt: AnyObject;
19
- uploadParams: AnyObject;
20
- height: string;
21
- ossServerUrl: string;
22
- ossUrl: string;
23
- offlinePreviewUrl: string;
24
- offlineServerUrl: string;
25
- value: string;
26
- onChange: any;
27
- customRequest: any;
28
- uploadMode: string;
29
- zIndex: number;
30
- }
31
-
32
- export const RichEditor = observer(function (props: PropsType, parentRef) {
33
- const {
34
- toolbarConfig, // 工具栏配置
35
- editorConfig, // 编辑器配置
36
- height,
37
- onChange,
38
- value,
39
- ossOpt,
40
- uploadMode = "oss",
41
- offlinePreviewUrl = "",
42
- offlineServerUrl = "",
43
- uploadParams = {},
44
- // ossUrl = "https://test-abt.hzabjt.com:18091/api/v1/user/oss/getWebOssConfig",
45
- ossServerUrl = "/api/v1/user/oss/getWebOssConfig",
46
- ossUrl = "/api/v1/user/oss/getWebOssConfig",
47
- zIndex = 9999,
48
- } = props;
49
- const isPrivateStore =
50
- props.uploadParams?.fileAcl === "private" || props.ossOpt?.signatureParams?.fileAcl === "private";
51
-
52
- useImperativeHandle(parentRef, () => ({
53
- setEditorContent,
54
- getEditorContent,
55
- }));
56
-
57
- const field = useField<any>();
58
-
59
- // editor 实例
60
- const [editor, setEditor] = useState<IDomEditor | null>(null); // TS 语法
61
-
62
- // 编辑器内容
63
- const [html, setHtml] = useState<string>("");
64
-
65
- const [isLoading, setIsLoading] = useState<boolean>(false);
66
-
67
- const setEditorContent = (content) => {
68
- setHtml(content);
69
- };
70
-
71
- const getEditorContent = () => {
72
- return html;
73
- };
74
-
75
- const customUpload = async (file: File, insertFn) => {
76
- let customRequest = props.customRequest;
77
- if (uploadMode === "oss") {
78
- customRequest = getOssUploadRequest({
79
- ...props,
80
- isPrivateStore,
81
- params: uploadParams,
82
- ossServerUrl: ossServerUrl || ossUrl,
83
- });
84
- } else if (uploadMode === "offline") {
85
- customRequest = getOfflineUploadRequest({
86
- ...props,
87
- isPrivateStore,
88
- params: uploadParams,
89
- offlineServerUrl: offlineServerUrl || ossUrl,
90
- offlinePreviewUrl: offlinePreviewUrl,
91
- });
92
- }
93
- setIsLoading(true);
94
- customRequest({
95
- file,
96
- onSuccess: (res) => {
97
- setIsLoading(false);
98
- console.log(res);
99
- insertFn(res.url, "", "");
100
- },
101
- onError: () => {
102
- setIsLoading(false);
103
- message.error(`${file.name} 上传失败`);
104
- },
105
- });
106
- };
107
-
108
- const config: Partial<IEditorConfig> = {
109
- // TS 语法
110
- placeholder: "请输入内容...",
111
- MENU_CONF: {
112
- uploadImage: {
113
- // form-data fieldName ,默认值 'wangeditor-uploaded-image'
114
- fieldName: "wangeditor-uploaded-image",
115
- // 单个文件的最大体积限制,默认为 2M
116
- maxFileSize: 1 * 1024 * 1024, // 1M
117
- // 最多可上传几个文件,默认为 100
118
- maxNumberOfFiles: 1,
119
- // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
120
- allowedFileTypes: ["image/*"],
121
- // 跨域是否传递 cookie ,默认为 false
122
- withCredentials: false,
123
- // 超时时间,默认为 10 秒
124
- timeout: 5 * 1000, // 5 秒
125
- customUpload,
126
- },
127
- uploadVideo: {
128
- // form-data fieldName ,默认值 'wangeditor-uploaded-image'
129
- fieldName: "wangeditor-uploaded-video",
130
- // 最多可上传几个文件,默认为 100
131
- maxNumberOfFiles: 1,
132
- // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
133
- allowedFileTypes: ["video/*"],
134
- // 跨域是否传递 cookie ,默认为 false
135
- withCredentials: false,
136
- customUpload,
137
- },
138
- },
139
- ...merge(editorConfig, {
140
- MENU_CONF: {
141
- uploadImage: {
142
- // form-data fieldName ,默认值 'wangeditor-uploaded-image'
143
- fieldName: "wangeditor-uploaded-image",
144
- // 单个文件的最大体积限制,默认为 2M
145
- maxFileSize: 1 * 1024 * 1024, // 1M
146
- // 最多可上传几个文件,默认为 100
147
- maxNumberOfFiles: 1,
148
- // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
149
- allowedFileTypes: ["image/*"],
150
- // 跨域是否传递 cookie ,默认为 false
151
- withCredentials: false,
152
- // 超时时间,默认为 10 秒
153
- timeout: 5 * 1000, // 5 秒
154
- customUpload,
155
- },
156
- uploadVideo: {
157
- // form-data fieldName ,默认值 'wangeditor-uploaded-image'
158
- fieldName: "wangeditor-uploaded-video",
159
- // 最多可上传几个文件,默认为 100
160
- maxNumberOfFiles: 1,
161
- // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
162
- allowedFileTypes: ["video/*"],
163
- // 跨域是否传递 cookie ,默认为 false
164
- withCredentials: false,
165
- customUpload,
166
- },
167
- },
168
- }),
169
- };
170
- const onEditorChange = (e) => {
171
- const content = e.getHtml();
172
- setHtml(content);
173
- onChange && onChange(content);
174
- };
175
-
176
- // 及时销毁 editor ,重要!
177
- useEffect(() => {
178
- return () => {
179
- if (editor == null) return;
180
- editor.destroy();
181
- setEditor(null);
182
- };
183
- }, [editor]);
184
-
185
- useEffect(() => {
186
- setEditorContent(value);
187
- }, [value]);
188
-
189
- return (
190
- <>
191
- <div className="wang-editor-warpper" style={{ zIndex }}>
192
- {isLoading && (
193
- <div className="spin-content">
194
- <Spin tip="Loading..." />
195
- </div>
196
- )}
197
- <Toolbar
198
- editor={editor}
199
- defaultConfig={toolbarConfig}
200
- mode="default"
201
- style={{ borderBottom: "1px solid #ccc" }}
202
- />
203
- <WangEditor
204
- defaultConfig={config}
205
- value={html}
206
- onCreated={(e) => {
207
- setEditor(e);
208
- field.editor = e;
209
- }}
210
- onChange={(e) => onEditorChange(e)}
211
- mode="default"
212
- style={{ height }}
213
- />
214
- {/* <div className="wang-editor-container">
215
- <div className="wang-editor-scroll">
216
- <WangEditor
217
- defaultConfig={config}
218
- value={html}
219
- onCreated={setEditor}
220
- onChange={(editor) => setHtml(editor.getHtml())}
221
- mode="default"
222
- style={{ height }}
223
- />
224
- </div>
225
- </div> */}
226
- </div>
227
- </>
228
- );
229
- });
230
-
231
- export default connect(
232
- RichEditor,
233
- mapProps((props: any, field) => {
234
- return { ...props, form: field.form, field };
235
- }),
236
- );
237
-
238
- export const Editor = WangEditor;
1
+ import "@wangeditor/editor/dist/css/style.css"; // 引入 css
2
+ import React, { useState, useEffect, useImperativeHandle, forwardRef } from "react";
3
+ import { Editor as WangEditor, Toolbar } from "@wangeditor/editor-for-react";
4
+ import { IDomEditor, IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
5
+ import { getOssUploadRequest, getOfflineUploadRequest } from "../Upload/common/customRequest";
6
+ import { handlePreviewUrls } from "../Upload/common/OfflineUpload";
7
+ import "./index.less";
8
+ import { Spin, message } from "antd";
9
+ import { connect, mapProps, observer, useField } from "@formily/react";
10
+ import { merge } from "lodash";
11
+ interface AnyObject {
12
+ [key: string]: any;
13
+ }
14
+
15
+ interface PropsType {
16
+ toolbarConfig?: Partial<IToolbarConfig>;
17
+ editorConfig?: Partial<IEditorConfig>;
18
+ ossOpt: AnyObject;
19
+ uploadParams: AnyObject;
20
+ height: string;
21
+ ossServerUrl: string;
22
+ ossUrl: string;
23
+ offlinePreviewUrl: string;
24
+ offlineServerUrl: string;
25
+ value: string;
26
+ onChange: any;
27
+ customRequest: any;
28
+ uploadMode: string;
29
+ zIndex: number;
30
+ }
31
+
32
+ export const RichEditor = observer(function (props: PropsType, parentRef) {
33
+ const {
34
+ toolbarConfig, // 工具栏配置
35
+ editorConfig, // 编辑器配置
36
+ height,
37
+ onChange,
38
+ value,
39
+ ossOpt,
40
+ uploadMode = "oss",
41
+ offlinePreviewUrl = "",
42
+ offlineServerUrl = "",
43
+ uploadParams = {},
44
+ // ossUrl = "https://test-abt.hzabjt.com:18091/api/v1/user/oss/getWebOssConfig",
45
+ ossServerUrl = "/api/v1/user/oss/getWebOssConfig",
46
+ ossUrl = "/api/v1/user/oss/getWebOssConfig",
47
+ zIndex = 9999,
48
+ } = props;
49
+ const isPrivateStore =
50
+ props.uploadParams?.fileAcl === "private" || props.ossOpt?.signatureParams?.fileAcl === "private";
51
+
52
+ useImperativeHandle(parentRef, () => ({
53
+ setEditorContent,
54
+ getEditorContent,
55
+ }));
56
+
57
+ const field = useField<any>();
58
+
59
+ // editor 实例
60
+ const [editor, setEditor] = useState<IDomEditor | null>(null); // TS 语法
61
+
62
+ // 编辑器内容
63
+ const [html, setHtml] = useState<string>("");
64
+
65
+ const [isLoading, setIsLoading] = useState<boolean>(false);
66
+
67
+ const setEditorContent = (content) => {
68
+ setHtml(content);
69
+ };
70
+
71
+ const getEditorContent = () => {
72
+ return html;
73
+ };
74
+
75
+ const customUpload = async (file: File, insertFn) => {
76
+ let customRequest = props.customRequest;
77
+ if (uploadMode === "oss") {
78
+ customRequest = getOssUploadRequest({
79
+ ...props,
80
+ isPrivateStore,
81
+ params: uploadParams,
82
+ ossServerUrl: ossServerUrl || ossUrl,
83
+ });
84
+ } else if (uploadMode === "offline") {
85
+ customRequest = getOfflineUploadRequest({
86
+ ...props,
87
+ isPrivateStore,
88
+ params: uploadParams,
89
+ offlineServerUrl: offlineServerUrl || ossUrl,
90
+ offlinePreviewUrl: offlinePreviewUrl,
91
+ });
92
+ }
93
+ setIsLoading(true);
94
+ customRequest({
95
+ file,
96
+ onSuccess: (res) => {
97
+ setIsLoading(false);
98
+ console.log(res);
99
+ insertFn(res.url, "", "");
100
+ },
101
+ onError: () => {
102
+ setIsLoading(false);
103
+ message.error(`${file.name} 上传失败`);
104
+ },
105
+ });
106
+ };
107
+
108
+ const config: Partial<IEditorConfig> = {
109
+ // TS 语法
110
+ placeholder: "请输入内容...",
111
+ MENU_CONF: {
112
+ uploadImage: {
113
+ // form-data fieldName ,默认值 'wangeditor-uploaded-image'
114
+ fieldName: "wangeditor-uploaded-image",
115
+ // 单个文件的最大体积限制,默认为 2M
116
+ maxFileSize: 1 * 1024 * 1024, // 1M
117
+ // 最多可上传几个文件,默认为 100
118
+ maxNumberOfFiles: 1,
119
+ // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
120
+ allowedFileTypes: ["image/*"],
121
+ // 跨域是否传递 cookie ,默认为 false
122
+ withCredentials: false,
123
+ // 超时时间,默认为 10 秒
124
+ timeout: 5 * 1000, // 5 秒
125
+ customUpload,
126
+ },
127
+ uploadVideo: {
128
+ // form-data fieldName ,默认值 'wangeditor-uploaded-image'
129
+ fieldName: "wangeditor-uploaded-video",
130
+ // 最多可上传几个文件,默认为 100
131
+ maxNumberOfFiles: 1,
132
+ // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
133
+ allowedFileTypes: ["video/*"],
134
+ // 跨域是否传递 cookie ,默认为 false
135
+ withCredentials: false,
136
+ customUpload,
137
+ },
138
+ },
139
+ ...merge(editorConfig, {
140
+ MENU_CONF: {
141
+ uploadImage: {
142
+ // form-data fieldName ,默认值 'wangeditor-uploaded-image'
143
+ fieldName: "wangeditor-uploaded-image",
144
+ // 单个文件的最大体积限制,默认为 2M
145
+ maxFileSize: 1 * 1024 * 1024, // 1M
146
+ // 最多可上传几个文件,默认为 100
147
+ maxNumberOfFiles: 1,
148
+ // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
149
+ allowedFileTypes: ["image/*"],
150
+ // 跨域是否传递 cookie ,默认为 false
151
+ withCredentials: false,
152
+ // 超时时间,默认为 10 秒
153
+ timeout: 5 * 1000, // 5 秒
154
+ customUpload,
155
+ },
156
+ uploadVideo: {
157
+ // form-data fieldName ,默认值 'wangeditor-uploaded-image'
158
+ fieldName: "wangeditor-uploaded-video",
159
+ // 最多可上传几个文件,默认为 100
160
+ maxNumberOfFiles: 1,
161
+ // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
162
+ allowedFileTypes: ["video/*"],
163
+ // 跨域是否传递 cookie ,默认为 false
164
+ withCredentials: false,
165
+ customUpload,
166
+ },
167
+ },
168
+ }),
169
+ };
170
+ const onEditorChange = (e) => {
171
+ const content = e.getHtml();
172
+ setHtml(content);
173
+ onChange && onChange(content);
174
+ };
175
+
176
+ // 及时销毁 editor ,重要!
177
+ useEffect(() => {
178
+ return () => {
179
+ if (editor == null) return;
180
+ editor.destroy();
181
+ setEditor(null);
182
+ };
183
+ }, [editor]);
184
+
185
+ useEffect(() => {
186
+ setEditorContent(value);
187
+ }, [value]);
188
+
189
+ return (
190
+ <>
191
+ <div className="wang-editor-warpper" style={{ zIndex }}>
192
+ {isLoading && (
193
+ <div className="spin-content">
194
+ <Spin tip="Loading..." />
195
+ </div>
196
+ )}
197
+ <Toolbar
198
+ editor={editor}
199
+ defaultConfig={toolbarConfig}
200
+ mode="default"
201
+ style={{ borderBottom: "1px solid #ccc" }}
202
+ />
203
+ <WangEditor
204
+ defaultConfig={config}
205
+ value={html}
206
+ onCreated={(e) => {
207
+ setEditor(e);
208
+ field.editor = e;
209
+ }}
210
+ onChange={(e) => onEditorChange(e)}
211
+ mode="default"
212
+ style={{ height }}
213
+ />
214
+ {/* <div className="wang-editor-container">
215
+ <div className="wang-editor-scroll">
216
+ <WangEditor
217
+ defaultConfig={config}
218
+ value={html}
219
+ onCreated={setEditor}
220
+ onChange={(editor) => setHtml(editor.getHtml())}
221
+ mode="default"
222
+ style={{ height }}
223
+ />
224
+ </div>
225
+ </div> */}
226
+ </div>
227
+ </>
228
+ );
229
+ });
230
+
231
+ export default connect(
232
+ RichEditor,
233
+ mapProps((props: any, field) => {
234
+ return { ...props, form: field.form, field };
235
+ }),
236
+ );
237
+
238
+ export const Editor = WangEditor;
@@ -1,55 +1,55 @@
1
- import { Checkbox } from "antd";
2
-
3
- export const CheckboxTable = (props) => {
4
- const { data, onChange } = props;
5
- return (
6
- <table className="tree-checkbox-table">
7
- <tbody>
8
- {data?.map((row, rowIdx) => {
9
- return (
10
- <tr className={`tree-checkbox-row tree-checkbox-row-${rowIdx}`} key={rowIdx}>
11
- {row?.map((col, colIdx) => {
12
- // 隐藏合并项
13
- if (col === false) {
14
- return null;
15
- }
16
- // 注意:col 存在 undefined 的情况
17
- const colKey = col?.value;
18
- return (
19
- <td
20
- className={`tree-checkbox-col tree-checkbox-col-${colIdx}`}
21
- key={colIdx}
22
- rowSpan={col?._maxRow > 1 ? col?._maxRow : null}
23
- >
24
- {Array.isArray(col) ? (
25
- <>
26
- {col?.map((it, itIdx) => {
27
- const itKey = it?.value;
28
- return (
29
- it && (
30
- <Checkbox onChange={onChange} value={itKey} key={itKey}>
31
- {it.label}
32
- </Checkbox>
33
- )
34
- );
35
- })}
36
- </>
37
- ) : (
38
- col && (
39
- <Checkbox onChange={onChange} value={colKey} key={colKey}>
40
- {col.label}
41
- </Checkbox>
42
- )
43
- )}
44
- </td>
45
- );
46
- })}
47
- </tr>
48
- );
49
- })}
50
- </tbody>
51
- </table>
52
- );
53
- };
54
-
55
- export default CheckboxTable;
1
+ import { Checkbox } from "antd";
2
+
3
+ export const CheckboxTable = (props) => {
4
+ const { data, onChange } = props;
5
+ return (
6
+ <table className="tree-checkbox-table">
7
+ <tbody>
8
+ {data?.map((row, rowIdx) => {
9
+ return (
10
+ <tr className={`tree-checkbox-row tree-checkbox-row-${rowIdx}`} key={rowIdx}>
11
+ {row?.map((col, colIdx) => {
12
+ // 隐藏合并项
13
+ if (col === false) {
14
+ return null;
15
+ }
16
+ // 注意:col 存在 undefined 的情况
17
+ const colKey = col?.value;
18
+ return (
19
+ <td
20
+ className={`tree-checkbox-col tree-checkbox-col-${colIdx}`}
21
+ key={colIdx}
22
+ rowSpan={col?._maxRow > 1 ? col?._maxRow : null}
23
+ >
24
+ {Array.isArray(col) ? (
25
+ <>
26
+ {col?.map((it, itIdx) => {
27
+ const itKey = it?.value;
28
+ return (
29
+ it && (
30
+ <Checkbox onChange={onChange} value={itKey} key={itKey}>
31
+ {it.label}
32
+ </Checkbox>
33
+ )
34
+ );
35
+ })}
36
+ </>
37
+ ) : (
38
+ col && (
39
+ <Checkbox onChange={onChange} value={colKey} key={colKey}>
40
+ {col.label}
41
+ </Checkbox>
42
+ )
43
+ )}
44
+ </td>
45
+ );
46
+ })}
47
+ </tr>
48
+ );
49
+ })}
50
+ </tbody>
51
+ </table>
52
+ );
53
+ };
54
+
55
+ export default CheckboxTable;