@qmlight/web-platform-components 1.0.0
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/AsyncExe/index.tsx +9 -0
- package/AsyncExe/src/index.tsx +118 -0
- package/AsyncExe/src/lang/en.tsx +11 -0
- package/AsyncExe/src/lang/index.tsx +21 -0
- package/AsyncExe/src/lang/zh-cn.tsx +11 -0
- package/Demo/index.module.less +11 -0
- package/Demo/index.tsx +32 -0
- package/LICENSE +21 -0
- package/README.md +9 -0
- package/SearchAssistanceSelect/index.tsx +3 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/AdvancedSearch/api/index.js +6 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/AdvancedSearch/api/server.js +14 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/AdvancedSearch/index.less +23 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/AdvancedSearch/index.tsx +115 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/AdvancedSearch/popover.tsx +42 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/AdvancedSearch/searchboard.tsx +359 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/api/server.js +15 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/api/tabList/index.js +55 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/api/treeData/index.js +26 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/customNode/index.tsx +62 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/customNode/style.less +9 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/customOrg/customModal.tsx +234 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/customOrg/index.tsx +245 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/customOrg/style.less +27 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/dept/index.tsx +104 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/dept/style.less +9 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/dropdownList/index.tsx +74 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/dropdownList/style.less +19 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/recently/index.tsx +86 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/roleList/index.tsx +61 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/search/index.tsx +109 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/subordinate/index.tsx +64 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/tabList/index.tsx +99 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/tabList/style.less +86 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/index.tsx +298 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/searchModal.tsx +109 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/searchTabs.tsx +153 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/style.less +41 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/transfer/index.tsx +211 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/transfer/searchTransferRight.tsx +93 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/transfer/style.less +69 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/treeData/index.tsx +407 -0
- package/SearchAssistanceSelect/src/SearchAssistanceComponent/treeData/style.less +9 -0
- package/SearchAssistanceSelect/src/index.tsx +73 -0
- package/SearchAssistanceSelect/src/style.less +29 -0
- package/UploadFileMenu/download.ts +15 -0
- package/UploadFileMenu/index.tsx +3 -0
- package/UploadFileMenu/src/api/index.js +44 -0
- package/UploadFileMenu/src/api/server.js +9 -0
- package/UploadFileMenu/src/index.tsx +256 -0
- package/index.js +10 -0
- package/package.json +22 -0
package/SearchAssistanceSelect/src/SearchAssistanceComponent/component/customOrg/customModal.tsx
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import React, { useRef, useState, useEffect } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
DcpButton,
|
|
4
|
+
DcpForm,
|
|
5
|
+
DcpModal,
|
|
6
|
+
Tabs,
|
|
7
|
+
QmSpace,
|
|
8
|
+
QmButton,
|
|
9
|
+
DcpTable,
|
|
10
|
+
QmTabs,
|
|
11
|
+
} from 'dcp-design-react';
|
|
12
|
+
import SearchAssistanceModel from '../../searchModal';
|
|
13
|
+
import { Message } from '@/utils';
|
|
14
|
+
import { createCustomGroups, getUsersByCustomGroup, updateCustomGroup } from '../../api/tabList';
|
|
15
|
+
|
|
16
|
+
const CustomModal = ({ actionInfo, onClose, setAcitonInfo, mode }) => {
|
|
17
|
+
const [activeKey, setActiveKey] = useState('1');
|
|
18
|
+
const formRef = useRef<any>();
|
|
19
|
+
const [userList, setUserList] = useState<any>([]);
|
|
20
|
+
const [visible, setVisible] = useState(false);
|
|
21
|
+
const [fieldList, setfieldList] = useState<any>([]);
|
|
22
|
+
const [itemList, setItemList] = useState<any>([
|
|
23
|
+
{
|
|
24
|
+
label: '基本信息',
|
|
25
|
+
key: '1',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: '成员',
|
|
29
|
+
key: '2',
|
|
30
|
+
},
|
|
31
|
+
]);
|
|
32
|
+
const getItems = () => {
|
|
33
|
+
return [
|
|
34
|
+
{
|
|
35
|
+
type: 'INPUT',
|
|
36
|
+
label: '名称',
|
|
37
|
+
fieldName: 'title',
|
|
38
|
+
rules: [{ required: true }],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: 'INPUT_NUMBER',
|
|
42
|
+
label: '排序',
|
|
43
|
+
fieldName: 'sortOrder',
|
|
44
|
+
rules: [{ required: true }],
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
};
|
|
48
|
+
const getColumns = () => {
|
|
49
|
+
return [
|
|
50
|
+
{
|
|
51
|
+
title: '操作',
|
|
52
|
+
dataIndex: '__action__',
|
|
53
|
+
render: (_, record) => {
|
|
54
|
+
return (
|
|
55
|
+
<DcpButton
|
|
56
|
+
type="link"
|
|
57
|
+
onClick={() => {
|
|
58
|
+
// const list = userListData.current.filter((item) => item.id !== record.id);
|
|
59
|
+
setUserList((data) => data.filter((item) => item.id !== record.id));
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
删除
|
|
63
|
+
</DcpButton>
|
|
64
|
+
);
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
title: '姓名',
|
|
69
|
+
dataIndex: 'title',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: '分部',
|
|
73
|
+
dataIndex: 'orgName',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
title: '部门',
|
|
77
|
+
dataIndex: 'deptName',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
title: '岗位',
|
|
81
|
+
dataIndex: 'jobName',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
};
|
|
85
|
+
const [columns, setColumns] = useState<any[]>(getColumns());
|
|
86
|
+
const [items, setItems] = useState<any[]>(getItems());
|
|
87
|
+
const onSaveItem = async () => {
|
|
88
|
+
// eslint-disable-next-line no-unsafe-optional-chaining
|
|
89
|
+
const [err, data] = await formRef?.current?.GET_FORM_DATA();
|
|
90
|
+
|
|
91
|
+
if (err) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const field = {
|
|
95
|
+
...data,
|
|
96
|
+
userIds: userList.map((item) => item.key),
|
|
97
|
+
};
|
|
98
|
+
const res = await (!data?.id
|
|
99
|
+
? createCustomGroups(field)
|
|
100
|
+
: updateCustomGroup({ ...field, id: data.id }));
|
|
101
|
+
if (res.code === 200) {
|
|
102
|
+
Message('保存成功', 'success');
|
|
103
|
+
onClose(true);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const onModalDataChange = (data) => {
|
|
107
|
+
setUserList(data);
|
|
108
|
+
if (actionInfo.type === 'add') {
|
|
109
|
+
setItemList([
|
|
110
|
+
{
|
|
111
|
+
label: '基本信息',
|
|
112
|
+
key: '1',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
label: '成员',
|
|
116
|
+
key: '2',
|
|
117
|
+
},
|
|
118
|
+
]);
|
|
119
|
+
setActiveKey('2');
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (actionInfo.type === 'edit') {
|
|
124
|
+
formRef.current?.SET_FIELDS_VALUE(actionInfo.data);
|
|
125
|
+
}
|
|
126
|
+
if (actionInfo.type === 'add') {
|
|
127
|
+
setItemList([
|
|
128
|
+
{
|
|
129
|
+
label: '基本信息',
|
|
130
|
+
key: '1',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
label: '成员',
|
|
134
|
+
key: '2',
|
|
135
|
+
disabled: true,
|
|
136
|
+
},
|
|
137
|
+
]);
|
|
138
|
+
}
|
|
139
|
+
}, [actionInfo]);
|
|
140
|
+
const getUserData = async () => {
|
|
141
|
+
const res = await getUsersByCustomGroup({ ids: [actionInfo.data.id] });
|
|
142
|
+
if (res.code === 200) {
|
|
143
|
+
setUserList(
|
|
144
|
+
res.data[0]?.userList.map((item) => {
|
|
145
|
+
return {
|
|
146
|
+
...item,
|
|
147
|
+
title: item.userName,
|
|
148
|
+
value: item.id,
|
|
149
|
+
label: item.userName,
|
|
150
|
+
};
|
|
151
|
+
})
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
return (
|
|
156
|
+
<>
|
|
157
|
+
<div className="search-assistance-tabs">
|
|
158
|
+
<QmTabs
|
|
159
|
+
size="small"
|
|
160
|
+
activeKey={activeKey}
|
|
161
|
+
items={itemList}
|
|
162
|
+
onChange={(value) => {
|
|
163
|
+
if (value === '2' && actionInfo.type === 'edit') {
|
|
164
|
+
getUserData();
|
|
165
|
+
}
|
|
166
|
+
setActiveKey(value);
|
|
167
|
+
}}
|
|
168
|
+
/>
|
|
169
|
+
<div className={'search-assistance-tabs-content'}>
|
|
170
|
+
<div style={{ display: activeKey === '1' ? 'block' : 'none', marginTop: 10 }}>
|
|
171
|
+
<DcpForm ref={formRef} cols={1} items={items} />
|
|
172
|
+
</div>
|
|
173
|
+
<div style={{ display: activeKey === '2' ? 'block' : 'none', marginTop: 10 }}>
|
|
174
|
+
<DcpTable
|
|
175
|
+
rowKey={'id'}
|
|
176
|
+
height={320}
|
|
177
|
+
webPagination
|
|
178
|
+
columns={columns}
|
|
179
|
+
dataSource={userList}
|
|
180
|
+
>
|
|
181
|
+
<QmButton type="primary" onClick={() => setVisible(true)}>
|
|
182
|
+
添加成员
|
|
183
|
+
</QmButton>
|
|
184
|
+
</DcpTable>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
<QmSpace className="action-footer">
|
|
189
|
+
<QmButton type="primary" onClick={() => onSaveItem()}>
|
|
190
|
+
保存
|
|
191
|
+
</QmButton>
|
|
192
|
+
{actionInfo.type === 'add' ? (
|
|
193
|
+
<QmButton type="primary" onClick={() => setVisible(true)}>
|
|
194
|
+
添加成员
|
|
195
|
+
</QmButton>
|
|
196
|
+
) : (
|
|
197
|
+
<></>
|
|
198
|
+
)}
|
|
199
|
+
|
|
200
|
+
<QmButton onClick={() => onClose()}>取消</QmButton>
|
|
201
|
+
</QmSpace>
|
|
202
|
+
|
|
203
|
+
<SearchAssistanceModel
|
|
204
|
+
data={userList}
|
|
205
|
+
mode={'multiple'}
|
|
206
|
+
items={[
|
|
207
|
+
{
|
|
208
|
+
label: '常用组',
|
|
209
|
+
key: '1',
|
|
210
|
+
},
|
|
211
|
+
// {
|
|
212
|
+
// label: '同部门',
|
|
213
|
+
// key: '2',
|
|
214
|
+
// },
|
|
215
|
+
// {
|
|
216
|
+
// label: '我的下属',
|
|
217
|
+
// key: '3',
|
|
218
|
+
// },
|
|
219
|
+
{
|
|
220
|
+
label: '组织结构',
|
|
221
|
+
key: '4',
|
|
222
|
+
type: 'customOrg',
|
|
223
|
+
},
|
|
224
|
+
]}
|
|
225
|
+
type={'customOrg'}
|
|
226
|
+
onChange={onModalDataChange}
|
|
227
|
+
onClose={() => setVisible(false)}
|
|
228
|
+
visible={visible}
|
|
229
|
+
title={'人力资源'}
|
|
230
|
+
/>
|
|
231
|
+
</>
|
|
232
|
+
);
|
|
233
|
+
};
|
|
234
|
+
export default CustomModal;
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef, useLayoutEffect } from 'react';
|
|
2
|
+
import { DcpButton, DcpModal, DcpSearchTree } from 'dcp-design-react';
|
|
3
|
+
import { PlusOutlined } from '@/icons';
|
|
4
|
+
import {
|
|
5
|
+
getAllCustomGroups,
|
|
6
|
+
createCustomGroups,
|
|
7
|
+
deleteCustomGroup,
|
|
8
|
+
getUsersByCustomGroup,
|
|
9
|
+
} from '../../api/tabList';
|
|
10
|
+
import TabList from '../tabList';
|
|
11
|
+
import './style.less';
|
|
12
|
+
import { Message } from '@/utils';
|
|
13
|
+
import CustomModal from './customModal';
|
|
14
|
+
import { EditOutlined, DeleteOutlined } from '@/icons';
|
|
15
|
+
|
|
16
|
+
const CustomOrg = (props) => {
|
|
17
|
+
const {
|
|
18
|
+
onDoubleClickChange,
|
|
19
|
+
targetKeys,
|
|
20
|
+
selectedKeys,
|
|
21
|
+
mode,
|
|
22
|
+
onItemSelect,
|
|
23
|
+
onValueChange,
|
|
24
|
+
onDataChange,
|
|
25
|
+
} = props;
|
|
26
|
+
const [dataSource, setData] = useState<any>([]);
|
|
27
|
+
const [itemKeys, setItemKeys] = useState<any[]>([]);
|
|
28
|
+
const [actionInfo, setAcitonInfo] = useState<any>({
|
|
29
|
+
type: 'add',
|
|
30
|
+
visible: false,
|
|
31
|
+
});
|
|
32
|
+
const [fetchParams, setFetchParams] = useState({});
|
|
33
|
+
|
|
34
|
+
const [moveKey, setMoveKey] = useState<string | null>(null);
|
|
35
|
+
const getData = async () => {
|
|
36
|
+
const res = await getAllCustomGroups({});
|
|
37
|
+
if (res.code === 200) {
|
|
38
|
+
const list = res.data.map((item) => {
|
|
39
|
+
return {
|
|
40
|
+
...item,
|
|
41
|
+
key: item.id,
|
|
42
|
+
orgtype: 'customOrg',
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
setData(list);
|
|
46
|
+
onDataChange && onDataChange(list);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const getTreeData = async (params) => {
|
|
50
|
+
const res = await (params.id
|
|
51
|
+
? getUsersByCustomGroup({ ids: [params.id] })
|
|
52
|
+
: getAllCustomGroups({}));
|
|
53
|
+
if (res.code === 200) {
|
|
54
|
+
if (params.id) {
|
|
55
|
+
return {
|
|
56
|
+
...res,
|
|
57
|
+
data: res.data[0]?.userList.map((item) => {
|
|
58
|
+
return {
|
|
59
|
+
...item,
|
|
60
|
+
isLeaf: true,
|
|
61
|
+
title: item.userName,
|
|
62
|
+
};
|
|
63
|
+
}),
|
|
64
|
+
};
|
|
65
|
+
} else {
|
|
66
|
+
return {
|
|
67
|
+
...res,
|
|
68
|
+
data: res.data.map((item) => {
|
|
69
|
+
return {
|
|
70
|
+
...item,
|
|
71
|
+
orgtype: 'customOrg',
|
|
72
|
+
};
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return res;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (mode === 'multiple') {
|
|
82
|
+
getData();
|
|
83
|
+
}
|
|
84
|
+
// onDataChange && onDataChange(dataSource);
|
|
85
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
86
|
+
}, []);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
setItemKeys(selectedKeys || []);
|
|
89
|
+
}, [selectedKeys]);
|
|
90
|
+
const itemSelect = (value, checked) => {
|
|
91
|
+
if (mode === 'multiple') {
|
|
92
|
+
onItemSelect && onItemSelect(value, checked);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
setItemKeys([value]);
|
|
96
|
+
const field = dataSource.find((item) => item.id === value);
|
|
97
|
+
onValueChange && onValueChange({ ...field, value: field.id, label: field.title });
|
|
98
|
+
};
|
|
99
|
+
const onItemAction = async (act, item) => {
|
|
100
|
+
if (act === 'edit') {
|
|
101
|
+
setAcitonInfo({
|
|
102
|
+
type: 'edit',
|
|
103
|
+
data: {
|
|
104
|
+
id: item.id,
|
|
105
|
+
title: item.title,
|
|
106
|
+
sortOrder: item.sortOrder,
|
|
107
|
+
},
|
|
108
|
+
visible: true,
|
|
109
|
+
});
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (act === 'del') {
|
|
113
|
+
const res = await deleteCustomGroup({ id: item.id });
|
|
114
|
+
if (res.code === 200) {
|
|
115
|
+
Message('删除成功', 'success');
|
|
116
|
+
if (!mode) {
|
|
117
|
+
setFetchParams({});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
getData();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const onClose = () => {
|
|
126
|
+
setAcitonInfo({
|
|
127
|
+
type: 'add',
|
|
128
|
+
visible: false,
|
|
129
|
+
});
|
|
130
|
+
if (!mode) {
|
|
131
|
+
setFetchParams({});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
getData();
|
|
135
|
+
};
|
|
136
|
+
const actionHandle = (e, flag, info) => {
|
|
137
|
+
e.stopPropagation();
|
|
138
|
+
if (flag === 'edit') {
|
|
139
|
+
onItemAction('edit', info);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (flag === 'del') {
|
|
143
|
+
onItemAction('del', info);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
return (
|
|
147
|
+
<div className="custom-org-page">
|
|
148
|
+
<div className="custom-org-page-extra">
|
|
149
|
+
<DcpButton
|
|
150
|
+
type="primary"
|
|
151
|
+
icon={<PlusOutlined />}
|
|
152
|
+
onClick={() => {
|
|
153
|
+
setAcitonInfo({
|
|
154
|
+
type: 'add',
|
|
155
|
+
visible: true,
|
|
156
|
+
});
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
新建分组
|
|
160
|
+
</DcpButton>
|
|
161
|
+
</div>
|
|
162
|
+
{!mode && (
|
|
163
|
+
<div className="custom-org-page-tree">
|
|
164
|
+
<DcpSearchTree
|
|
165
|
+
showSearchBar={false}
|
|
166
|
+
filterable={false}
|
|
167
|
+
showCollapse={false}
|
|
168
|
+
asyncLoad={true}
|
|
169
|
+
value={itemKeys}
|
|
170
|
+
onSelectChange={(node: any) => {
|
|
171
|
+
if (!mode) {
|
|
172
|
+
if (!node.orgtype) {
|
|
173
|
+
setItemKeys([node.id]);
|
|
174
|
+
onValueChange && onValueChange({ ...node, value: node.id, title: node.title });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}}
|
|
178
|
+
fetch={{
|
|
179
|
+
api: getTreeData,
|
|
180
|
+
params: fetchParams,
|
|
181
|
+
}}
|
|
182
|
+
fieldsDefine={{
|
|
183
|
+
valueKey: 'id',
|
|
184
|
+
textKey: 'title',
|
|
185
|
+
}}
|
|
186
|
+
titleRender={(nodeData) => {
|
|
187
|
+
return nodeData.orgtype === 'customOrg' ? (
|
|
188
|
+
<div
|
|
189
|
+
onMouseEnter={() => setMoveKey(nodeData.id)}
|
|
190
|
+
onMouseLeave={() => setMoveKey(null)}
|
|
191
|
+
className="title-item-field"
|
|
192
|
+
>
|
|
193
|
+
<div>{nodeData.title}</div>
|
|
194
|
+
<div
|
|
195
|
+
className="item-action"
|
|
196
|
+
style={{ display: moveKey === nodeData.id ? 'block' : 'none' }}
|
|
197
|
+
>
|
|
198
|
+
<EditOutlined
|
|
199
|
+
onClick={(e) => actionHandle(e, 'edit', nodeData)}
|
|
200
|
+
style={{ marginRight: 8, fontSize: 14 }}
|
|
201
|
+
/>
|
|
202
|
+
<DeleteOutlined
|
|
203
|
+
onClick={(e) => actionHandle(e, 'del', nodeData)}
|
|
204
|
+
style={{ marginRight: 8, fontSize: 14 }}
|
|
205
|
+
/>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
) : (
|
|
209
|
+
nodeData.title
|
|
210
|
+
);
|
|
211
|
+
}}
|
|
212
|
+
/>
|
|
213
|
+
</div>
|
|
214
|
+
)}
|
|
215
|
+
{mode === 'multiple' && (
|
|
216
|
+
<div className="custom-org-page-list">
|
|
217
|
+
<TabList
|
|
218
|
+
onDoubleClickChange={onDoubleClickChange}
|
|
219
|
+
onItemSelect={itemSelect}
|
|
220
|
+
selectedKeys={itemKeys}
|
|
221
|
+
type={'edit'}
|
|
222
|
+
onItemAction={onItemAction}
|
|
223
|
+
dataSource={dataSource.filter((item) => !targetKeys.includes(item.id))}
|
|
224
|
+
/>
|
|
225
|
+
</div>
|
|
226
|
+
)}
|
|
227
|
+
<DcpModal
|
|
228
|
+
width={800}
|
|
229
|
+
height={540}
|
|
230
|
+
title="分组"
|
|
231
|
+
visible={actionInfo.visible}
|
|
232
|
+
onClose={() => onClose()}
|
|
233
|
+
wrapClassName={'search-assistance-modal'}
|
|
234
|
+
>
|
|
235
|
+
<CustomModal
|
|
236
|
+
actionInfo={actionInfo}
|
|
237
|
+
onClose={onClose}
|
|
238
|
+
mode={mode}
|
|
239
|
+
setAcitonInfo={setAcitonInfo}
|
|
240
|
+
/>
|
|
241
|
+
</DcpModal>
|
|
242
|
+
</div>
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
export default CustomOrg;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.custom-org-page{
|
|
2
|
+
height: 100%;
|
|
3
|
+
&-extra{
|
|
4
|
+
text-align: right;
|
|
5
|
+
padding: 3px ;
|
|
6
|
+
}
|
|
7
|
+
&-tree{
|
|
8
|
+
height: calc(100% - 38px);
|
|
9
|
+
.title-item-field{
|
|
10
|
+
display: flex;
|
|
11
|
+
justify-content: space-between;
|
|
12
|
+
align-items: center;
|
|
13
|
+
}
|
|
14
|
+
.item-action{
|
|
15
|
+
.anticon{
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
margin-left: 8px;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
&-list{
|
|
22
|
+
height: calc(100% - 38px);
|
|
23
|
+
&-field{
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
2
|
+
import DropDownList from '../dropdownList';
|
|
3
|
+
import TabList from '../tabList';
|
|
4
|
+
import { getDeptUsers, updateRecentUser } from '../../api/tabList';
|
|
5
|
+
import { getUserInfo } from '@/utils/cookies';
|
|
6
|
+
import './style.less';
|
|
7
|
+
import { DcpTabs } from 'dcp-design-react';
|
|
8
|
+
const DeptPageIndex = (props) => {
|
|
9
|
+
const {
|
|
10
|
+
mode,
|
|
11
|
+
selectedKeys,
|
|
12
|
+
targetKeys,
|
|
13
|
+
onDataChange,
|
|
14
|
+
onValueChange,
|
|
15
|
+
onDoubleClickChange,
|
|
16
|
+
onItemSelect,
|
|
17
|
+
} = props;
|
|
18
|
+
const [dataSource, setDataSource] = useState<any[]>([]);
|
|
19
|
+
const [activeKey, setActiveKey] = useState('DEPUTY');
|
|
20
|
+
const [fetchParams, setFetchParams] = useState({
|
|
21
|
+
userId: getUserInfo().id,
|
|
22
|
+
displayType: 'DEPUTY',
|
|
23
|
+
orgTypeCode: '',
|
|
24
|
+
});
|
|
25
|
+
const items = [
|
|
26
|
+
{
|
|
27
|
+
label: '副职以上',
|
|
28
|
+
key: 'DEPUTY',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
label: '总监以上',
|
|
32
|
+
key: 'DIRECTOR',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: '全员',
|
|
36
|
+
key: 'ALL',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
const ondrownChange = (field) => {
|
|
40
|
+
setFetchParams((origin) => Object.assign({}, origin, { orgTypeCode: field.key }));
|
|
41
|
+
};
|
|
42
|
+
const getData = async (params) => {
|
|
43
|
+
const res = await getDeptUsers(params);
|
|
44
|
+
if (res.code === 200) {
|
|
45
|
+
const list = res.data.map((item) => {
|
|
46
|
+
return {
|
|
47
|
+
...item,
|
|
48
|
+
key: item.id,
|
|
49
|
+
title: item.userName,
|
|
50
|
+
deptName: item.departmentName,
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
setDataSource(list || []);
|
|
54
|
+
onDataChange && onDataChange(list);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const [itemKeys, setItemKeys] = useState<any[]>([]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
setItemKeys(selectedKeys || []);
|
|
61
|
+
}, [selectedKeys]);
|
|
62
|
+
const itemSelect = (value, checked) => {
|
|
63
|
+
if (mode === 'multiple') {
|
|
64
|
+
const field = dataSource.filter((item) => value.includes(item.id));
|
|
65
|
+
updateRecentUserData(field);
|
|
66
|
+
onItemSelect && onItemSelect(value, checked);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
setItemKeys([value]);
|
|
70
|
+
const field = dataSource.find((item) => item.id === value);
|
|
71
|
+
updateRecentUserData([field]);
|
|
72
|
+
onValueChange && onValueChange({ ...field, value: field.id, label: field.userName });
|
|
73
|
+
};
|
|
74
|
+
const updateRecentUserData = (list) => {
|
|
75
|
+
updateRecentUser(list);
|
|
76
|
+
};
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (fetchParams.orgTypeCode) {
|
|
79
|
+
getData(fetchParams);
|
|
80
|
+
}
|
|
81
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
82
|
+
}, [fetchParams]);
|
|
83
|
+
return (
|
|
84
|
+
<div className="dept-page">
|
|
85
|
+
<DropDownList onDataChange={ondrownChange} />
|
|
86
|
+
<DcpTabs
|
|
87
|
+
items={items}
|
|
88
|
+
size="small"
|
|
89
|
+
defaultActiveKey="DEPUTY"
|
|
90
|
+
onChange={(value) => {
|
|
91
|
+
setActiveKey(value);
|
|
92
|
+
setFetchParams((origin) => Object.assign({}, origin, { displayType: value }));
|
|
93
|
+
}}
|
|
94
|
+
/>
|
|
95
|
+
<TabList
|
|
96
|
+
onDoubleClickChange={onDoubleClickChange}
|
|
97
|
+
onItemSelect={itemSelect}
|
|
98
|
+
selectedKeys={itemKeys}
|
|
99
|
+
dataSource={dataSource.filter((item) => !targetKeys.includes(item.id))}
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
export default DeptPageIndex;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Dropdown } from 'dcp-design-react';
|
|
3
|
+
import { getOrgTypeList } from '../../api/treeData';
|
|
4
|
+
import { ApartmentOutlined, DownOutlined } from '@/icons';
|
|
5
|
+
import './style.less';
|
|
6
|
+
type itemsType = {
|
|
7
|
+
key: string;
|
|
8
|
+
label: string;
|
|
9
|
+
};
|
|
10
|
+
const DropDownList = ({ onDataChange }) => {
|
|
11
|
+
const [items, setItems] = useState<itemsType[]>([]);
|
|
12
|
+
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
|
|
13
|
+
const getOrgTypeListData = async () => {
|
|
14
|
+
const res = await getOrgTypeList({ currentPage: 1, pageSize: 50 });
|
|
15
|
+
if (res.code === 200) {
|
|
16
|
+
const list = res.data.list.map((item) => {
|
|
17
|
+
return {
|
|
18
|
+
key: item.code,
|
|
19
|
+
label: item.name,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
setItems(list);
|
|
23
|
+
setSelectedKeys(list[0]?.key ? [list[0]?.key] : []);
|
|
24
|
+
onDataChange(list[0]);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const onDropDownChange = (value) => {
|
|
28
|
+
setSelectedKeys([value.key]);
|
|
29
|
+
const field = items.find((item) => item.key === value.key) || {};
|
|
30
|
+
onDataChange(field);
|
|
31
|
+
};
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
getOrgTypeListData();
|
|
34
|
+
return () => {
|
|
35
|
+
setItems([]);
|
|
36
|
+
};
|
|
37
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
38
|
+
}, []);
|
|
39
|
+
const valueRender = (keys, data) => {
|
|
40
|
+
if (!keys?.length) {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
const field = data.find((item) => item.key === keys[0]);
|
|
44
|
+
if (!field) {
|
|
45
|
+
return '';
|
|
46
|
+
}
|
|
47
|
+
return field.label;
|
|
48
|
+
};
|
|
49
|
+
return (
|
|
50
|
+
<div className="search-dropdown-page">
|
|
51
|
+
<Dropdown
|
|
52
|
+
menu={{
|
|
53
|
+
items,
|
|
54
|
+
selectedKeys: selectedKeys,
|
|
55
|
+
onClick: (value) => onDropDownChange(value),
|
|
56
|
+
}}
|
|
57
|
+
overlayClassName={'search-dropdown-page-pro'}
|
|
58
|
+
placement="bottom"
|
|
59
|
+
trigger={['click']}
|
|
60
|
+
getPopupContainer={(triggerNode) => triggerNode}
|
|
61
|
+
>
|
|
62
|
+
<div className="search-dropdown-page-org">
|
|
63
|
+
<div>
|
|
64
|
+
<ApartmentOutlined /> <span>{valueRender(selectedKeys, items)}</span>
|
|
65
|
+
</div>
|
|
66
|
+
<div>
|
|
67
|
+
<DownOutlined />
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</Dropdown>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
export default DropDownList;
|