zy-react-library 1.0.35 → 1.0.37
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/components/FormBuilder/FormBuilder.d.ts +8 -10
- package/components/FormBuilder/FormBuilder.js +9 -14
- package/components/FormBuilder/FormItemsRenderer.js +49 -49
- package/components/Icon/ResetIcon/index.js +2 -2
- package/components/ImportFile/index.js +1 -1
- package/components/LeftTree/Basic/index.d.ts +25 -0
- package/components/LeftTree/Basic/index.js +184 -0
- package/components/LeftTree/Department/Gwj/index.d.ts +17 -0
- package/components/LeftTree/Department/Gwj/index.js +32 -0
- package/components/SelectTree/Basic/index.d.ts +25 -0
- package/components/SelectTree/Basic/index.js +50 -0
- package/components/SelectTree/Department/Gwj/index.d.ts +17 -0
- package/components/SelectTree/Department/Gwj/index.js +58 -0
- package/components/Upload/index.d.ts +8 -2
- package/components/Upload/index.js +103 -16
- package/enum/uploadFile/gwj/index.js +131 -0
- package/hooks/useDeleteFile/index.d.ts +22 -0
- package/hooks/useDeleteFile/index.js +46 -0
- package/hooks/useGetFile/index.d.ts +29 -0
- package/hooks/useGetFile/index.js +56 -0
- package/hooks/useUploadFile/index.d.ts +64 -0
- package/hooks/useUploadFile/index.js +99 -0
- package/package.json +1 -1
- package/utils/index.d.ts +46 -5
- package/utils/index.js +38 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FormProps } from "antd/es/form";
|
|
2
2
|
import type { Gutter } from "antd/es/grid/row";
|
|
3
3
|
import type { FC, ReactNode } from "react";
|
|
4
4
|
import type { FormOption, FormValues } from "./FormItemsRenderer";
|
|
@@ -6,7 +6,7 @@ import type { FormOption, FormValues } from "./FormItemsRenderer";
|
|
|
6
6
|
/**
|
|
7
7
|
* FormBuilder 组件属性
|
|
8
8
|
*/
|
|
9
|
-
export interface FormBuilderProps extends
|
|
9
|
+
export interface FormBuilderProps extends FormProps {
|
|
10
10
|
/** 表单初始值 */
|
|
11
11
|
values?: FormValues;
|
|
12
12
|
/** 表单配置项数组 */
|
|
@@ -15,24 +15,22 @@ export interface FormBuilderProps extends Omit<FormProps, "form"> {
|
|
|
15
15
|
gutter?: Gutter | [Gutter, Gutter];
|
|
16
16
|
/** 占据栅格列数,默认 12 */
|
|
17
17
|
span?: number | string;
|
|
18
|
-
/** 表单实例(通过 Form.useForm() 创建) */
|
|
19
|
-
form?: FormInstance;
|
|
20
18
|
/** 自动生成必填规则,默认 true */
|
|
21
19
|
useAutoGenerateRequired?: boolean;
|
|
22
|
-
/** 表单提交回调 */
|
|
23
|
-
onFinish?: (values: FormValues) => void;
|
|
24
20
|
/** 是否显示操作按钮区域,默认 true */
|
|
25
21
|
showActionButtons?: boolean;
|
|
26
22
|
/** 提交按钮文字,默认为"提交" */
|
|
27
23
|
submitButtonText?: string;
|
|
28
|
-
/**
|
|
29
|
-
|
|
24
|
+
/** 取消按钮文字,默认为"取消" */
|
|
25
|
+
cancelButtonText?: string;
|
|
30
26
|
/** 是否显示提交按钮,默认 true */
|
|
31
27
|
showSubmitButton?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
|
|
28
|
+
/** 是否显示取消按钮,默认 true */
|
|
29
|
+
showCancelButton?: boolean;
|
|
34
30
|
/** 自定义操作按钮组 */
|
|
35
31
|
customActionButtons?: ReactNode;
|
|
32
|
+
/** 额外操作按钮组 */
|
|
33
|
+
extraActionButtons?: ReactNode;
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
/**
|
|
@@ -11,23 +11,19 @@ const FormBuilder = (props) => {
|
|
|
11
11
|
gutter = 24,
|
|
12
12
|
span = 12,
|
|
13
13
|
labelCol = { span: 4 },
|
|
14
|
-
onFinish,
|
|
15
14
|
useAutoGenerateRequired = true,
|
|
16
15
|
showActionButtons = true,
|
|
17
16
|
submitButtonText = "提交",
|
|
18
|
-
|
|
17
|
+
cancelButtonText = "取消",
|
|
19
18
|
showSubmitButton = true,
|
|
20
|
-
|
|
19
|
+
showCancelButton = true,
|
|
21
20
|
customActionButtons,
|
|
22
|
-
|
|
21
|
+
extraActionButtons,
|
|
23
22
|
...restProps
|
|
24
23
|
} = props;
|
|
25
24
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const handleReset = () => {
|
|
30
|
-
form.resetFields();
|
|
25
|
+
const handleCancel = () => {
|
|
26
|
+
window.history.back();
|
|
31
27
|
};
|
|
32
28
|
|
|
33
29
|
return (
|
|
@@ -35,9 +31,7 @@ const FormBuilder = (props) => {
|
|
|
35
31
|
labelCol={labelCol}
|
|
36
32
|
scrollToFirstError
|
|
37
33
|
wrapperCol={{ span: 24 - labelCol.span }}
|
|
38
|
-
onFinish={onFinish}
|
|
39
34
|
initialValues={values}
|
|
40
|
-
form={form}
|
|
41
35
|
style={{ width: `calc(100% - ${gutter * 2}px)`, margin: `0 auto` }}
|
|
42
36
|
{...restProps}
|
|
43
37
|
>
|
|
@@ -60,11 +54,12 @@ const FormBuilder = (props) => {
|
|
|
60
54
|
{submitButtonText}
|
|
61
55
|
</Button>
|
|
62
56
|
)}
|
|
63
|
-
{
|
|
64
|
-
<Button onClick={
|
|
65
|
-
{
|
|
57
|
+
{showCancelButton && (
|
|
58
|
+
<Button onClick={handleCancel} style={{ marginRight: 8 }}>
|
|
59
|
+
{cancelButtonText}
|
|
66
60
|
</Button>
|
|
67
61
|
)}
|
|
62
|
+
{extraActionButtons}
|
|
68
63
|
</Space>
|
|
69
64
|
)}
|
|
70
65
|
</Col>
|
|
@@ -21,13 +21,13 @@ const { RangePicker } = DatePicker;
|
|
|
21
21
|
* 表单项渲染器组件
|
|
22
22
|
*/
|
|
23
23
|
const FormItemsRenderer = ({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
options,
|
|
25
|
+
labelCol,
|
|
26
|
+
span = 12,
|
|
27
|
+
collapse = false,
|
|
28
|
+
useAutoGenerateRequired = true,
|
|
29
|
+
initialValues,
|
|
30
|
+
}) => {
|
|
31
31
|
const form = Form.useFormInstance();
|
|
32
32
|
|
|
33
33
|
// 获取表单值,优先使用 initialValues
|
|
@@ -298,38 +298,38 @@ const FormItemsRenderer = ({
|
|
|
298
298
|
option.customizeRender
|
|
299
299
|
? (renderFormControl(option))
|
|
300
300
|
: (
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
301
|
+
<Form.Item
|
|
302
|
+
key={option.name || index}
|
|
303
|
+
noStyle
|
|
304
|
+
shouldUpdate={option.shouldUpdate ?? option?.componentProps?.shouldUpdate}
|
|
305
|
+
dependencies={option.dependencies || option?.componentProps?.dependencies}
|
|
306
|
+
>
|
|
307
|
+
{() => {
|
|
308
308
|
// 支持动态计算 hidden
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
309
|
+
const hidden = typeof option.hidden === "function"
|
|
310
|
+
? option.hidden(getFormValues())
|
|
311
|
+
: (option.hidden ?? false);
|
|
312
|
+
|
|
313
|
+
if (hidden)
|
|
314
|
+
return null;
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<Col key={option.name || index} span={itemSpan} style={style}>
|
|
318
|
+
<Form.Item
|
|
319
|
+
name={option.name}
|
|
320
|
+
label={renderLabel(option)}
|
|
321
|
+
rules={getRules(option)}
|
|
322
|
+
labelCol={itemLabelCol}
|
|
323
|
+
wrapperCol={itemWrapperCol}
|
|
324
|
+
{...getFormItemProps(option)}
|
|
325
|
+
>
|
|
326
|
+
{renderFormControl(option)}
|
|
327
|
+
</Form.Item>
|
|
328
|
+
</Col>
|
|
329
|
+
);
|
|
330
|
+
}}
|
|
331
|
+
</Form.Item>
|
|
332
|
+
)
|
|
333
333
|
);
|
|
334
334
|
}
|
|
335
335
|
|
|
@@ -348,17 +348,17 @@ const FormItemsRenderer = ({
|
|
|
348
348
|
option.customizeRender
|
|
349
349
|
? (renderFormControl(option))
|
|
350
350
|
: (
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
351
|
+
<Form.Item
|
|
352
|
+
name={option.name}
|
|
353
|
+
label={renderLabel(option)}
|
|
354
|
+
rules={getRules(option)}
|
|
355
|
+
labelCol={itemLabelCol}
|
|
356
|
+
wrapperCol={itemWrapperCol}
|
|
357
|
+
{...getFormItemProps(option)}
|
|
358
|
+
>
|
|
359
|
+
{renderFormControl(option)}
|
|
360
|
+
</Form.Item>
|
|
361
|
+
)
|
|
362
362
|
}
|
|
363
363
|
</Col>
|
|
364
364
|
);
|
|
@@ -75,7 +75,7 @@ const ImportFile = (props) => {
|
|
|
75
75
|
>
|
|
76
76
|
{children && typeof children === "function" ? children({ form }) : children}
|
|
77
77
|
<Form.Item label="附件" name="file" rules={[{ required: true, message: "附件不能为空" }]}>
|
|
78
|
-
<Upload accept=".xls,.xlsx" listType="text" />
|
|
78
|
+
<Upload accept=".xls,.xlsx" listType="text" maxCount={1} />
|
|
79
79
|
</Form.Item>
|
|
80
80
|
</Form>
|
|
81
81
|
</Modal>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TreeProps } from "antd/es/tree";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 组件属性
|
|
6
|
+
*/
|
|
7
|
+
export interface BasicLeftTreeProps extends TreeProps {
|
|
8
|
+
/** 树形数据 title 字段,默认 name */
|
|
9
|
+
nameKey?: string;
|
|
10
|
+
/** 树形数据 key 字段,默认 id */
|
|
11
|
+
idKey?: string;
|
|
12
|
+
/** 树形数据 children 字段,默认 childrenList */
|
|
13
|
+
childrenKey?: string;
|
|
14
|
+
/** 决定 onGetNodePaths 是否包含自身节点,默认 true */
|
|
15
|
+
onGetNodePathsIsIncludeOneself?: boolean;
|
|
16
|
+
/** 获取父级节点 */
|
|
17
|
+
onGetNodePaths?: () => Record<string, any>[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 基础左侧树组件(不建议直接使用此组件,二次继承使用)
|
|
22
|
+
*/
|
|
23
|
+
declare const BasicLeftTree: FC<BasicLeftTreeProps>;
|
|
24
|
+
|
|
25
|
+
export default BasicLeftTree;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { Input, Tree } from "antd";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
|
|
4
|
+
const { Search } = Input;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 基础左侧树组件(不建议直接使用此组件,二次继承使用)
|
|
8
|
+
*/
|
|
9
|
+
const BasicLeftTree = (props) => {
|
|
10
|
+
const {
|
|
11
|
+
onSelect,
|
|
12
|
+
onGetNodePaths,
|
|
13
|
+
onGetNodePathsIsIncludeOneself = true,
|
|
14
|
+
expandedKeys: externalExpandedKeys,
|
|
15
|
+
treeData = [],
|
|
16
|
+
nameKey = "name",
|
|
17
|
+
idKey = "id",
|
|
18
|
+
childrenKey = "childrenList",
|
|
19
|
+
...restProps
|
|
20
|
+
} = props;
|
|
21
|
+
|
|
22
|
+
const [expandedKeys, setExpandedKeys] = useState([]);
|
|
23
|
+
const [searchValue, setSearchValue] = useState("");
|
|
24
|
+
const [autoExpandParent, setAutoExpandParent] = useState(true);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
setExpandedKeys(externalExpandedKeys);
|
|
28
|
+
}, [externalExpandedKeys]);
|
|
29
|
+
|
|
30
|
+
// 展开所有包含匹配项的父节点
|
|
31
|
+
const getAllExpandedKeys = (data, searchValue, keys = []) => {
|
|
32
|
+
data.forEach((node) => {
|
|
33
|
+
if (node[childrenKey]) {
|
|
34
|
+
if (node[nameKey].includes(searchValue)
|
|
35
|
+
|| node[childrenKey].some(child => child[nameKey].includes(searchValue))) {
|
|
36
|
+
keys.push(node[idKey]);
|
|
37
|
+
}
|
|
38
|
+
getAllExpandedKeys(node[childrenKey], searchValue, keys);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return keys;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// 过滤树数据,只保留匹配的节点
|
|
45
|
+
const filterTreeData = (data, searchValue) => {
|
|
46
|
+
if (!searchValue) {
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return data.reduce((acc, node) => {
|
|
51
|
+
// 检查当前节点是否匹配
|
|
52
|
+
const isMatch = node[nameKey].includes(searchValue);
|
|
53
|
+
|
|
54
|
+
// 递归处理子节点
|
|
55
|
+
const filteredChildren = node[childrenKey] ? filterTreeData(node[childrenKey], searchValue) : [];
|
|
56
|
+
|
|
57
|
+
// 如果当前节点匹配或者有匹配的子节点,则保留该节点
|
|
58
|
+
if (isMatch || filteredChildren.length > 0) {
|
|
59
|
+
acc.push({
|
|
60
|
+
...node,
|
|
61
|
+
[childrenKey]: filteredChildren.length > 0 ? filteredChildren : undefined,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return acc;
|
|
66
|
+
}, []);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const handleExpand = (newExpandedKeys) => {
|
|
70
|
+
setExpandedKeys(newExpandedKeys);
|
|
71
|
+
setAutoExpandParent(false);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const getNodePaths = (data, targetId, idKey, childrenKey, path = [], isIncludeOneself) => {
|
|
75
|
+
for (let i = 0; i < data.length; i++) {
|
|
76
|
+
const node = data[i];
|
|
77
|
+
const newPath = [...path, node];
|
|
78
|
+
|
|
79
|
+
// 找到目标节点,根据isIncludeOneself决定是否包含自身
|
|
80
|
+
if (node[idKey] === targetId) {
|
|
81
|
+
if (isIncludeOneself)
|
|
82
|
+
return newPath; // 包含自身
|
|
83
|
+
else
|
|
84
|
+
return path; // 不包含自身,只返回父节点路径
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 递归查找子节点
|
|
88
|
+
if (node[childrenKey] && node[childrenKey].length > 0) {
|
|
89
|
+
const result = getNodePaths(node[childrenKey], targetId, idKey, childrenKey, newPath, isIncludeOneself);
|
|
90
|
+
if (result) {
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return null;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const handleSelect = (selectedKeys, event) => {
|
|
100
|
+
if (selectedKeys.length > 0) {
|
|
101
|
+
const selectedNodeId = selectedKeys[0];
|
|
102
|
+
const parentNodes = getNodePaths(treeData, selectedNodeId, idKey, childrenKey, onGetNodePathsIsIncludeOneself);
|
|
103
|
+
onGetNodePaths?.(parentNodes);
|
|
104
|
+
}
|
|
105
|
+
onSelect?.(selectedKeys, event);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const onFilterTreeData = (value) => {
|
|
109
|
+
setSearchValue(value);
|
|
110
|
+
setAutoExpandParent(true);
|
|
111
|
+
|
|
112
|
+
if (!value) {
|
|
113
|
+
setExpandedKeys([]);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const expandedKeys = getAllExpandedKeys(treeData, value);
|
|
118
|
+
|
|
119
|
+
setExpandedKeys(expandedKeys);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const onSearch = async (value) => {
|
|
123
|
+
if (value === searchValue)
|
|
124
|
+
return;
|
|
125
|
+
onFilterTreeData(value);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// 渲染带高亮的标题
|
|
129
|
+
const renderTitle = (name) => {
|
|
130
|
+
if (!searchValue)
|
|
131
|
+
return name;
|
|
132
|
+
|
|
133
|
+
const index = name.indexOf(searchValue);
|
|
134
|
+
if (index === -1)
|
|
135
|
+
return name;
|
|
136
|
+
|
|
137
|
+
const beforeStr = name.substring(0, index);
|
|
138
|
+
const afterStr = name.substring(index + searchValue.length);
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<span>
|
|
142
|
+
{beforeStr}
|
|
143
|
+
<span style={{ color: "#f50" }}>{searchValue}</span>
|
|
144
|
+
{afterStr}
|
|
145
|
+
</span>
|
|
146
|
+
);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// 递归处理树节点标题显示
|
|
150
|
+
const processTreeData = (data) => {
|
|
151
|
+
return data.map(node => ({
|
|
152
|
+
...node,
|
|
153
|
+
[nameKey]: renderTitle(node[nameKey]),
|
|
154
|
+
[childrenKey]: node[childrenKey] ? processTreeData(node[childrenKey]) : undefined,
|
|
155
|
+
}));
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// 过滤并处理树数据
|
|
159
|
+
const filteredTreeData = filterTreeData(treeData, searchValue);
|
|
160
|
+
const processedTreeData = processTreeData(filteredTreeData);
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<div style={{ width: 300 }}>
|
|
164
|
+
<Search
|
|
165
|
+
style={{ marginBottom: 8 }}
|
|
166
|
+
placeholder="输入关键字进行过滤"
|
|
167
|
+
onSearch={onSearch}
|
|
168
|
+
/>
|
|
169
|
+
<Tree
|
|
170
|
+
onExpand={handleExpand}
|
|
171
|
+
onSelect={handleSelect}
|
|
172
|
+
autoExpandParent={autoExpandParent}
|
|
173
|
+
expandedKeys={expandedKeys}
|
|
174
|
+
treeData={processedTreeData}
|
|
175
|
+
fieldNames={{ title: nameKey, key: idKey, children: childrenKey }}
|
|
176
|
+
{...restProps}
|
|
177
|
+
/>
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
BasicLeftTree.displayName = "BasicLeftTree";
|
|
183
|
+
|
|
184
|
+
export default BasicLeftTree;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FC } from "react";
|
|
2
|
+
import type { BasicLeftTreeProps } from "../../Basic";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 组件属性
|
|
6
|
+
*/
|
|
7
|
+
export interface DepartmentLeftTreeProps extends Omit<BasicLeftTreeProps, "treeData"> {
|
|
8
|
+
/** 请求参数 */
|
|
9
|
+
params?: Record<string, any>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 部门左侧树组件(港务局版本)
|
|
14
|
+
*/
|
|
15
|
+
declare const DepartmentLeftTree: FC<DepartmentLeftTreeProps>;
|
|
16
|
+
|
|
17
|
+
export default DepartmentLeftTree;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { request } from "@cqsjjb/jjb-common-lib/http";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import BasicLeftTree from "../../Basic";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 部门左侧树组件(港务局版本)
|
|
7
|
+
*/
|
|
8
|
+
function DepartmentLeftTree(props) {
|
|
9
|
+
const {
|
|
10
|
+
params = {},
|
|
11
|
+
...restProps
|
|
12
|
+
} = props;
|
|
13
|
+
|
|
14
|
+
const [treeData, setTreeData] = useState([]);
|
|
15
|
+
|
|
16
|
+
const getData = async () => {
|
|
17
|
+
const { data } = await request("/basic-info/department/listTree", "post", params);
|
|
18
|
+
setTreeData(data);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
getData();
|
|
23
|
+
}, []);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<BasicLeftTree treeData={treeData} {...restProps} />
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
DepartmentLeftTree.displayName = "DepartmentLeftTree";
|
|
31
|
+
|
|
32
|
+
export default DepartmentLeftTree;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TreeSelectProps } from "antd/es/tree-select";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 组件属性
|
|
6
|
+
*/
|
|
7
|
+
export interface BasicSelectTreeProps extends TreeSelectProps {
|
|
8
|
+
/** 树形数据 label 字段,默认 name */
|
|
9
|
+
nameKey?: string;
|
|
10
|
+
/** 树形数据 value 字段,默认 id */
|
|
11
|
+
idKey?: string;
|
|
12
|
+
/** 树形数据 children 字段,默认 childrenList */
|
|
13
|
+
childrenKey?: string;
|
|
14
|
+
/** 决定 onGetNodePaths 是否包含自身节点,默认 true */
|
|
15
|
+
onGetNodePathsIsIncludeOneself?: boolean;
|
|
16
|
+
/** 获取父级节点 */
|
|
17
|
+
onGetNodePaths?: (nodes: Record<string, any>[]) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 基础下拉树组件(不建议直接使用此组件,二次继承使用)
|
|
22
|
+
*/
|
|
23
|
+
declare const BasicSelectTree: FC<BasicSelectTreeProps>;
|
|
24
|
+
|
|
25
|
+
export default BasicSelectTree;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { TreeSelect } from "antd";
|
|
2
|
+
import { getTreeNodePaths } from "../../../utils";
|
|
3
|
+
|
|
4
|
+
function BasicSelectTree(props) {
|
|
5
|
+
const {
|
|
6
|
+
onSelect,
|
|
7
|
+
onGetNodePaths,
|
|
8
|
+
onGetNodePathsIsIncludeOneself = true,
|
|
9
|
+
placeholder = "",
|
|
10
|
+
treeData = [],
|
|
11
|
+
nameKey = "name",
|
|
12
|
+
idKey = "id",
|
|
13
|
+
childrenKey = "childrenList",
|
|
14
|
+
...restProps
|
|
15
|
+
} = props;
|
|
16
|
+
|
|
17
|
+
const handleSelect = (value, node, extra) => {
|
|
18
|
+
if (value.length > 0) {
|
|
19
|
+
const parentNodes = getTreeNodePaths({
|
|
20
|
+
data: treeData,
|
|
21
|
+
targetId: value,
|
|
22
|
+
idKey,
|
|
23
|
+
childrenKey,
|
|
24
|
+
isIncludeOneself: onGetNodePathsIsIncludeOneself
|
|
25
|
+
});
|
|
26
|
+
onGetNodePaths?.(parentNodes);
|
|
27
|
+
}
|
|
28
|
+
onSelect?.(value, node, extra);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<TreeSelect
|
|
33
|
+
showSearch
|
|
34
|
+
style={{ width: "100%" }}
|
|
35
|
+
styles={{
|
|
36
|
+
popup: { root: { maxHeight: 400, overflow: "auto" } },
|
|
37
|
+
}}
|
|
38
|
+
placeholder={`请选择${placeholder}`}
|
|
39
|
+
onSelect={handleSelect}
|
|
40
|
+
allowClear
|
|
41
|
+
treeData={treeData}
|
|
42
|
+
fieldNames={{ label: nameKey, value: idKey, children: childrenKey }}
|
|
43
|
+
{...restProps}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
BasicSelectTree.displayName = "BasicSelectTree";
|
|
49
|
+
|
|
50
|
+
export default BasicSelectTree;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FC } from "react";
|
|
2
|
+
import type { BasicSelectTreeProps } from "../../Basic";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 组件属性
|
|
6
|
+
*/
|
|
7
|
+
export interface DepartmentSelectTreeProps extends Omit<BasicSelectTreeProps, "treeData" | "placeholder"> {
|
|
8
|
+
/** 请求参数 */
|
|
9
|
+
params?: Record<string, any>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 部门下拉树组件(港务局版本)
|
|
14
|
+
*/
|
|
15
|
+
declare const DepartmentSelectTree: FC<DepartmentSelectTreeProps>;
|
|
16
|
+
|
|
17
|
+
export default DepartmentSelectTree;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { request } from "@cqsjjb/jjb-common-lib/http";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import BasicLeftTree from "../../Basic";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 部门左侧树组件(港务局版本)
|
|
7
|
+
*/
|
|
8
|
+
function DepartmentSelectTree(props) {
|
|
9
|
+
const {
|
|
10
|
+
params = {},
|
|
11
|
+
...restProps
|
|
12
|
+
} = props;
|
|
13
|
+
|
|
14
|
+
const [treeData, setTreeData] = useState([
|
|
15
|
+
{
|
|
16
|
+
name: "parent 1",
|
|
17
|
+
id: "0-0",
|
|
18
|
+
childrenList: [
|
|
19
|
+
{
|
|
20
|
+
name: "parent 1-0",
|
|
21
|
+
id: "0-0-0",
|
|
22
|
+
childrenList: [
|
|
23
|
+
{
|
|
24
|
+
name: "leaf",
|
|
25
|
+
id: "0-0-0-0",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "leaf",
|
|
29
|
+
id: "0-0-0-1",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "parent 1-1",
|
|
35
|
+
id: "0-0-1",
|
|
36
|
+
childrenList: [{ name: <span style={{ color: "#1677ff" }}>sss</span>, id: "0-0-1-0" }],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
const getData = async () => {
|
|
43
|
+
const { data } = await request("/basic-info/department/listTree", "post", params);
|
|
44
|
+
setTreeData(data);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
getData();
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<BasicLeftTree treeData={treeData} placeholder="部门" {...restProps} />
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
DepartmentSelectTree.displayName = "DepartmentSelectTree";
|
|
57
|
+
|
|
58
|
+
export default DepartmentSelectTree;
|
|
@@ -11,12 +11,14 @@ export interface UploadProps extends Omit<AntUploadProps, "fileList"> {
|
|
|
11
11
|
ratio?: `${number}*${number}`;
|
|
12
12
|
/** 是否显示提示,默认 true */
|
|
13
13
|
showTip?: boolean;
|
|
14
|
-
/** 文件大小限制(单位:MB
|
|
14
|
+
/** 文件大小限制(单位:MB) */
|
|
15
15
|
size?: number;
|
|
16
16
|
/** 自定义提示内容 */
|
|
17
17
|
tipContent?: ReactNode;
|
|
18
|
-
/** listType 为 text
|
|
18
|
+
/** listType 为 text 时上传按钮文本 */
|
|
19
19
|
uploadButtonText?: string;
|
|
20
|
+
/** 要上传的文件类型,默认为 image */
|
|
21
|
+
fileType?: "image" | "video" | "document";
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
/**
|
|
@@ -26,3 +28,7 @@ export interface UploadProps extends Omit<AntUploadProps, "fileList"> {
|
|
|
26
28
|
declare const Upload: FC<UploadProps>;
|
|
27
29
|
|
|
28
30
|
export default Upload;
|
|
31
|
+
|
|
32
|
+
// 视频:数量默认1个,且只支持mp4格式,单个文件大小默认100M
|
|
33
|
+
// 文件:数量默认4个,且只支持pdf、doc、docx格式
|
|
34
|
+
// 图片:数量默认4个,且只支持jpg、jpeg、png格式
|