@hzab/group-user-selector 0.0.10 → 0.0.11-alpha.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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # @hzab/group-user-selector@0.1.0
2
+
3
+ feat: 新增 iconCustomFunc 自定义返回图片函数
4
+ feat: 新增 LableSlot 插槽
5
+ feat: 新增 ItemRender 列表 item 自定义渲染
6
+ feat: 新增 SelectItemRender 选中 item 自定义渲染
7
+ feat: 新增 modal 计算选中人数模式
8
+
1
9
  # @hzab/group-user-selector@0.0.10
2
10
 
3
11
  feat: 搜索情况下默认不展示下级
package/README.md CHANGED
@@ -1,90 +1,97 @@
1
- # @hzab/group-user-selector
2
-
3
- 组件模板
4
-
5
- - node@16.16.0
6
-
7
- - 注意:首次克隆先执行 npm run prepare 命令
8
-
9
- # 组件
10
-
11
- ## 示例
12
-
13
- ```jsx
14
- import Demo from "@hzab/group-user-selector";
15
-
16
- <Demo />;
17
- ```
18
-
19
- ## API
20
-
21
- ### InfoPanel Attributes
22
-
23
- | 参数 | 类型 | 必填 | 默认值 | 说明 |
24
- | ------------------- | ------- | ---- | -------- | ----------------------------------- |
25
- | value | Object | 否 | [] | 选中的人员数据 |
26
- | model | Object | 否 | - | 列表的请求 model (getListApi) |
27
- | modelGetType | string | 否 | getList | 列表的请求类型 |
28
- | searchModel | Object | 否 | - | 搜索列表的请求 model (getListApi) |
29
- | queryKey | string | 否 | parentId | 列表的请求 model 的入参 key |
30
- | searchQueryKey | string | 否 | search | 搜索列表的请求 model 的入参 key |
31
- | labelKey | string | 否 | label | labelKey |
32
- | valueKey | string | 否 | value | valueKey |
33
- | imgKey | string | 否 | img | imgKey 头像 |
34
- | isUserKey | string | 否 | isUser | 区分部门和人员 |
35
- | hasPagination | boolean | 否 | true | 列表是否分页 |
36
- | hasSearch | boolean | 否 | true | 是否有搜索 |
37
- | hasSearchPagination | boolean | 否 | true | 搜索列表是否分页 |
38
- | searchPlaceholder | string | 否 | "搜索成员"| 搜索框的提示词 |
39
-
40
- # 组件开发流程
41
-
42
- - config/webpack.config.js 中按需修改 library 配置的文件名
43
- - config/webpack.config.js 中按需修改 alias 配置的包名,便于本地调试
44
- - tsconfig.json 中按需修改 paths 配置的包名,解决 ts 报错问题
45
- - npm run dev
46
-
47
- ## 文件目录
48
-
49
- - example 本地开发测试代码
50
- - src 组件源码
51
-
52
- ## 命令
53
-
54
- - Mac 执行该命令,设置 pre-commit 为可执行文件
55
-
56
- - npm run mac-chmod
57
- - chmod +x .husky && chmod +x .husky/pre-commit
58
-
59
- - 生成文档:npm run docs
60
- - 本地运行:npm run dev
61
-
62
- ## 发布
63
-
64
- - npm 源和云效源都需要发布
65
-
66
- - 命令:npm publish --access public
67
- - 发布目录:
68
- - src
69
-
70
- ### nrm
71
-
72
- - 安装
73
- npm install -g nrm
74
- - 增加源
75
- nrm add aliyun https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
76
- - 切换源
77
- nrm use aliyun
78
- nrm use npm
79
- - 登录(账号密码在 https://packages.aliyun.com/npm/npm-registry/guide 查看)
80
- npm login --registry=https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
81
-
82
- ## 配置
83
-
84
- ### 配置文件
85
-
86
- - 本地配置文件:config/config.js
87
-
88
- ### webpack 配置文件
89
-
90
- - config/webpack.config.js
1
+ # @hzab/group-user-selector
2
+
3
+ 组件模板
4
+
5
+ - node@16.16.0
6
+
7
+ - 注意:首次克隆先执行 npm run prepare 命令
8
+
9
+ # 组件
10
+
11
+ ## 示例
12
+
13
+ ```jsx
14
+ import Demo from "@hzab/group-user-selector";
15
+
16
+ <Demo />;
17
+ ```
18
+
19
+ ## API
20
+
21
+ ### InfoPanel Attributes
22
+
23
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
24
+ | ------------------- | -------- | ---- | ----------- | ----------------------------------- |
25
+ | value | Object | 否 | [] | 选中的人员数据 |
26
+ | model | Object | 否 | - | 列表的请求 model (getListApi) |
27
+ | modelGetType | string | 否 | getList | 列表的请求类型 |
28
+ | searchModel | Object | 否 | - | 搜索列表的请求 model (getListApi) |
29
+ | queryKey | string | 否 | parentId | 列表的请求 model 的入参 key |
30
+ | searchQueryKey | string | 否 | search | 搜索列表的请求 model 的入参 key |
31
+ | labelKey | string | 否 | label | labelKey |
32
+ | valueKey | string | 否 | value | valueKey |
33
+ | phoneKey | string | 否 | phoneNumber | phoneKey 电话 |
34
+ | totalKey | string | 否 | total | totalKey 选中总数人 |
35
+ | imgKey | string | 否 | img | imgKey 头像 |
36
+ | isUserKey | string | 否 | isUser | 区分部门和人员 |
37
+ | hasPagination | boolean | 否 | true | 列表是否分页 |
38
+ | hasSearch | boolean | 否 | true | 是否有搜索 |
39
+ | hasSearchPagination | boolean | 否 | true | 搜索列表是否分页 |
40
+ | searchPlaceholder | string | 否 | "搜索成员" | 搜索框的提示词 |
41
+ | modal | string | 否 | default | default:选中总数 other:选中人数 |
42
+ | iconCustomFunc | function | 否 | - | 图片的回调函数,入参 item,返回地址 |
43
+ | LableSlot | function | 否 | - | label 插槽,入参 item,返回 DOM |
44
+ | ItemRender | function | 否 | - | 整行 item 自定义渲染 |
45
+ | SelectItemRender | function | 否 | - | 选中后 item 自定义渲染 |
46
+
47
+ # 组件开发流程
48
+
49
+ - config/webpack.config.js 中按需修改 library 配置的文件名
50
+ - config/webpack.config.js 中按需修改 alias 配置的包名,便于本地调试
51
+ - 在 tsconfig.json 中按需修改 paths 配置的包名,解决 ts 报错问题
52
+ - npm run dev
53
+
54
+ ## 文件目录
55
+
56
+ - example 本地开发测试代码
57
+ - src 组件源码
58
+
59
+ ## 命令
60
+
61
+ - Mac 执行该命令,设置 pre-commit 为可执行文件
62
+
63
+ - npm run mac-chmod
64
+ - chmod +x .husky && chmod +x .husky/pre-commit
65
+
66
+ - 生成文档:npm run docs
67
+ - 本地运行:npm run dev
68
+
69
+ ## 发布
70
+
71
+ - npm 源和云效源都需要发布
72
+
73
+ - 命令:npm publish --access public
74
+ - 发布目录:
75
+ - src
76
+
77
+ ### nrm
78
+
79
+ - 安装
80
+ npm install -g nrm
81
+ - 增加源
82
+ nrm add aliyun https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
83
+ - 切换源
84
+ nrm use aliyun
85
+ nrm use npm
86
+ - 登录(账号密码在 https://packages.aliyun.com/npm/npm-registry/guide 查看)
87
+ npm login --registry=https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
88
+
89
+ ## 配置
90
+
91
+ ### 配置文件
92
+
93
+ - 本地配置文件:config/config.js
94
+
95
+ ### webpack 配置文件
96
+
97
+ - config/webpack.config.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/group-user-selector",
3
- "version": "0.0.10",
3
+ "version": "0.0.11-alpha.0",
4
4
  "description": "",
5
5
  "main": "src",
6
6
  "scripts": {
Binary file
Binary file
Binary file
@@ -1,5 +1,5 @@
1
- import { forwardRef } from "react";
2
- import { Checkbox } from "antd";
1
+ import { forwardRef } from "react";
2
+ import { Checkbox, Avatar } from "antd";
3
3
 
4
4
  import defaultAvatar from "../../assets/imgs/defaultAvatar.png";
5
5
  import department from "../../assets/imgs/department.png";
@@ -12,35 +12,61 @@ function ItemRenter(props, ref) {
12
12
  valueKey = "value",
13
13
  isUserKey = "isUser",
14
14
  imgKey = "img",
15
+ phoneKey = "phoneNumber",
15
16
  isCheck = false,
16
17
  item,
17
18
  handleClickItem,
18
19
  handleCheckItem,
19
- noNextLevel = false
20
+ noNextLevel = false,
21
+ iconFunc,
22
+ LableSlot,
23
+ ItemRender,
20
24
  } = props;
21
25
 
22
-
23
26
  return (
24
27
  <>
25
- <div className="group-selection-list-item" key={item[valueKey]}>
26
- <div className="avatar" onClick={() => handleCheckItem(item)}>
27
- <Checkbox checked={isCheck} />
28
- <img src={item[imgKey] ? item[imgKey] : item[isUserKey] ? defaultAvatar : department} />
29
- <div className="label">{item[labelKey]}</div>
30
- </div>
31
- {(item[isUserKey] || noNextLevel) ? null : <div
32
- className={`next ${isCheck ? "noNext" : ""}`}
33
- onClick={() => {
28
+ {ItemRender ? (
29
+ <ItemRender
30
+ key={item[valueKey]}
31
+ item={item}
32
+ handleCheckItem={() => handleCheckItem(item)}
33
+ handleClickItem={() => {
34
34
  if (isCheck) {
35
35
  return;
36
36
  }
37
37
  handleClickItem(item);
38
38
  }}
39
- >
40
- 下级
41
- </div>}
42
- </div>
43
- </>
39
+ ></ItemRender>
40
+ ) : (
41
+ <div className="group-selection-list-item" key={item[valueKey]}>
42
+ <div className="avatar" onClick={() => handleCheckItem(item)}>
43
+ <Checkbox className="checkbox-item-box" checked={isCheck} />
44
+ <Avatar className="avatar-item" size={32} src={iconFunc(item)} />
45
+ {LableSlot ? (
46
+ <LableSlot item={item}></LableSlot>
47
+ ) : (
48
+ <div className="label">
49
+ <div>{item[labelKey]}</div>
50
+ <div className="label-phone">{item[phoneKey]}</div>
51
+ </div>
52
+ )}
53
+ </div>
54
+ {item[isUserKey] || noNextLevel ? null : (
55
+ <div
56
+ className={`next ${isCheck ? "noNext" : ""}`}
57
+ onClick={() => {
58
+ if (isCheck) {
59
+ return;
60
+ }
61
+ handleClickItem(item);
62
+ }}
63
+ >
64
+ 下级
65
+ </div>
66
+ )}
67
+ </div>
68
+ )}
69
+ </>
44
70
  );
45
71
  }
46
72
 
@@ -1,33 +1,57 @@
1
- .group-selection-list-item {
2
- display: flex;
3
- align-items: center;
4
- justify-content: space-between;
5
- margin-bottom: 24px;
6
-
7
- .avatar {
8
- display: flex;
9
- align-items: center;
10
- cursor: pointer;
11
-
12
- img {
13
- width: 32px;
14
- height: auto;
15
- margin: 0 12px;
16
- }
17
-
18
- .label {
19
- font-size: 16px;
20
- color: #141414;
21
- }
22
- }
23
-
24
- .next {
25
- color: rgb(64, 62, 245);
26
- cursor: pointer;
27
- flex-shrink: 0;
28
- }
29
-
30
- .noNext {
31
- opacity: 0.5;
32
- }
33
- }
1
+ .group-selection-list-item {
2
+ display: flex;
3
+ align-items: center;
4
+ justify-content: space-between;
5
+ padding: 8px 6px;
6
+ margin-bottom: 16px;
7
+ .avatar {
8
+ display: flex;
9
+ align-items: center;
10
+ cursor: pointer;
11
+
12
+ .label {
13
+ font-size: 16px;
14
+ color: #333333;
15
+ .label-phone {
16
+ font-size: 12px;
17
+ color: #999999;
18
+ line-height: 1;
19
+ }
20
+ }
21
+
22
+ .avatar-item {
23
+ margin: 0 6px;
24
+ }
25
+ }
26
+
27
+ .next {
28
+ color: var(--ant-primary-color, rgb(64, 62, 245));
29
+ cursor: pointer;
30
+ flex-shrink: 0;
31
+ }
32
+
33
+ .noNext {
34
+ opacity: 0.5;
35
+ }
36
+
37
+ .checkbox-item-box {
38
+ .ant-checkbox-inner {
39
+ border-radius: 4px;
40
+ }
41
+ .ant-checkbox-checked:after {
42
+ border-radius: 4px;
43
+ }
44
+ // 选中状态:深蓝色底色
45
+ .ant-checkbox-checked {
46
+ .ant-checkbox-inner {
47
+ background-color: var(--ant-primary-color, rgb(64, 62, 245));
48
+ border-color: var(--ant-primary-color, rgb(64, 62, 245));
49
+ }
50
+ }
51
+ }
52
+
53
+ &:hover {
54
+ background: #f7f7f7;
55
+ border-radius: 8px;
56
+ }
57
+ }
@@ -1,6 +1,7 @@
1
1
  import { useEffect, useState, forwardRef } from "react";
2
2
  import { Input, message, Pagination } from "antd";
3
3
 
4
+ import SearchIcon from "../../assets/imgs/searchIcon.png";
4
5
  import "./index.less";
5
6
 
6
7
  function SearchRenter(props, ref) {
@@ -79,7 +80,17 @@ function SearchRenter(props, ref) {
79
80
 
80
81
  return (
81
82
  <>
82
- {hasSearch ? <Input.Search onSearch={onSearch} enterButton placeholder={searchPlaceholder} allowClear /> : null}
83
+ {hasSearch ? (
84
+ <Input.Search
85
+ className="group-selection-search-input"
86
+ prefix={<img className="group-selection-search-icon" src={SearchIcon}></img>}
87
+ onSearch={onSearch}
88
+ enterButton
89
+ placeholder={searchPlaceholder}
90
+ allowClear
91
+ />
92
+ ) : null}
93
+
83
94
  {search ? (
84
95
  <div className="group-selection-search-view">
85
96
  <div className="group-selection-search-list">
@@ -1,36 +1,51 @@
1
- .group-selection-search-view {
2
- display: flex;
3
- flex-direction: column;
4
- box-sizing: border-box;
5
- position: absolute;
6
- top: 56px;
7
- left: 24px;
8
- width: calc(100% - 48px);
9
- height: calc(100% - 80px);
10
- overflow-y: hidden;
11
- z-index: 10;
12
- background-color: #fff;
13
-
14
- .group-selection-search-list {
15
- box-sizing: border-box;
16
- flex: 1;
17
- overflow-y: auto;
18
- padding: 24px ;
19
-
20
- &::-webkit-scrollbar {
21
- display: none;
22
- }
23
- }
24
-
25
- .group-selection-search-pagination {
26
- position: absolute;
27
- left: 0;
28
- bottom: 0;
29
- width: 100%;
30
- height: 40px;
31
- display: flex;
32
- align-items: center;
33
- justify-content: center;
34
- background-color: #fff;
35
- }
36
- }
1
+ .group-selection-search-view {
2
+ display: flex;
3
+ flex-direction: column;
4
+ box-sizing: border-box;
5
+ position: absolute;
6
+ top: 56px;
7
+ left: 14px;
8
+ width: calc(100% - 28px);
9
+ height: calc(100% - 60px);
10
+ overflow-y: hidden;
11
+ z-index: 10;
12
+ background-color: #fff;
13
+
14
+ .group-selection-search-list {
15
+ box-sizing: border-box;
16
+ flex: 1;
17
+ overflow-y: auto;
18
+ padding: 14px;
19
+ margin-bottom: 40px;
20
+
21
+ // &::-webkit-scrollbar {
22
+ // display: none;
23
+ // }
24
+ }
25
+
26
+ .group-selection-search-pagination {
27
+ position: absolute;
28
+ left: 0;
29
+ bottom: 0;
30
+ width: 100%;
31
+ height: 40px;
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ background-color: #fff;
36
+ }
37
+ }
38
+ .group-selection-search-icon {
39
+ width: 16px;
40
+ height: auto;
41
+ margin-right: 6px;
42
+ }
43
+ .group-selection-search-input {
44
+ .ant-input-affix-wrapper {
45
+ border-radius: 8px !important;
46
+ }
47
+
48
+ .ant-input-group-addon {
49
+ display: none;
50
+ }
51
+ }
package/src/index.less CHANGED
@@ -26,7 +26,7 @@
26
26
  position: relative;
27
27
  height: 100%;
28
28
  overflow: hidden;
29
- padding: 24px;
29
+ padding: 14px;
30
30
  border-right: 1px solid #e8e8e8;
31
31
 
32
32
  // .group-selection-search-view {
@@ -75,15 +75,33 @@
75
75
 
76
76
  .group-selection-list-check {
77
77
  margin: 12px 0;
78
+
79
+ .group-selection-all-checkbox-box {
80
+ margin-right: 6px;
81
+
82
+ .ant-checkbox-inner {
83
+ border-radius: 4px;
84
+ }
85
+ .ant-checkbox-checked:after {
86
+ border-radius: 4px;
87
+ }
88
+ // 选中状态:深蓝色底色
89
+ .ant-checkbox-checked {
90
+ .ant-checkbox-inner {
91
+ background-color: var(--ant-primary-color, rgb(64, 62, 245));
92
+ border-color: var(--ant-primary-color, rgb(64, 62, 245));
93
+ }
94
+ }
95
+ }
78
96
  }
79
97
 
80
98
  .group-selection-list-view {
81
99
  flex: 1;
82
100
  overflow: auto;
83
101
 
84
- &::-webkit-scrollbar {
85
- display: none;
86
- }
102
+ // &::-webkit-scrollbar {
103
+ // display: none;
104
+ // }
87
105
  }
88
106
 
89
107
  // .group-selection-list-item {
@@ -124,43 +142,81 @@
124
142
  .group-selection-detail {
125
143
  position: relative;
126
144
  height: 100%;
127
- overflow: auto;
145
+ display: flex;
146
+ flex-direction: column;
147
+ padding: 14px;
148
+ overflow: hidden;
149
+
150
+ // &::-webkit-scrollbar {
151
+ // display: none;
152
+ // }
128
153
 
129
- &::-webkit-scrollbar {
130
- display: none;
154
+ .group-selection-detail-empty {
155
+ height: 100%;
156
+ display: flex;
157
+ flex-direction: column;
158
+ align-items: center;
159
+ justify-content: center;
160
+ .ant-empty-image {
161
+ margin-bottom: 24px;
162
+ }
163
+ .ant-empty-description {
164
+ font-size: 14px;
165
+ color: #777777;
166
+ }
131
167
  }
168
+
132
169
  .group-selection-detail-title {
133
- text-align: end;
134
- color: var(--ant-primary-color);
135
- cursor: pointer;
170
+ height: 36px;
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: space-between;
174
+
175
+ .group-selection-detail-close {
176
+ color: var(--ant-primary-color, rgb(64, 62, 245));
177
+ cursor: pointer;
178
+ }
179
+
180
+ .group-selection-detail-total {
181
+ font-weight: bold;
182
+ font-size: 14px;
183
+ color: #333333;
184
+ }
136
185
  }
137
186
 
138
187
  .group-selection-detail-list {
188
+ flex: 1;
139
189
  display: flex;
140
- align-items: center;
141
- flex-wrap: wrap;
142
- padding: 24px;
190
+ flex-direction: column;
191
+ padding: 14px 0 24px 0;
192
+ overflow: auto;
143
193
 
144
194
  .group-selection-detail-item {
145
195
  flex-shrink: 0;
146
196
  display: flex;
147
197
  align-items: center;
148
- padding: 4px 8px;
149
- margin: 0 12px 12px 0;
150
- color: #e8e8e8;
198
+ justify-content: space-between;
199
+ padding: 8px 6px;
200
+ margin-bottom: 14px;
151
201
  border-radius: 8px;
152
- background-color: aliceblue;
153
-
154
- img {
155
- width: 32px;
156
- height: auto;
157
- margin-right: 12px;
158
- }
159
-
160
- .label {
161
- font-size: 16px;
162
- color: #141414;
163
- margin-right: 12px;
202
+ .avatar-text-box {
203
+ display: flex;
204
+ align-items: center;
205
+
206
+ .label {
207
+ font-size: 16px;
208
+ color: #333333;
209
+ margin-right: 12px;
210
+ .label-phone {
211
+ font-size: 12px;
212
+ color: #999999;
213
+ line-height: 1;
214
+ }
215
+ }
216
+
217
+ .avatar-item {
218
+ margin-right: 7px;
219
+ }
164
220
  }
165
221
  }
166
222
  }
package/src/index.tsx CHANGED
@@ -1,12 +1,13 @@
1
- import { useEffect, useState, useImperativeHandle, forwardRef, useReducer, useRef } from "react";
2
- import { Input, Breadcrumb, Checkbox, message, Spin, Pagination, ConfigProvider } from "antd";
1
+ import { useEffect, useState, useImperativeHandle, forwardRef, useReducer, useRef, useMemo } from "react";
2
+ import { Input, Breadcrumb, Checkbox, message, Spin, Pagination, ConfigProvider, Empty, Avatar } from "antd";
3
3
  import zhCN from "antd/es/locale/zh_CN";
4
- import { CloseCircleFilled, SearchOutlined } from "@ant-design/icons";
4
+ import { CloseOutlined } from "@ant-design/icons";
5
5
  import "moment/locale/zh-cn";
6
6
  import _ from "lodash";
7
7
 
8
8
  import defaultAvatar from "./assets/imgs/defaultAvatar.png";
9
9
  import department from "./assets/imgs/department.png";
10
+ import EmptyIcon from "./assets/imgs/emptyIcon.png";
10
11
  import SearchRenter from "./components/SearchRenter";
11
12
  import ItemRenter from "./components/ItemRenter";
12
13
 
@@ -20,10 +21,27 @@ function GroupSelection(props, ref) {
20
21
  labelKey = "label",
21
22
  valueKey = "value",
22
23
  isUserKey = "isUser",
24
+ /** 手机号字段 */
25
+ phoneKey = "phoneNumber",
26
+ /** 选中总数人字段 */
27
+ totalKey = "total",
28
+ /** default:选中总数,other:根据 totalKey计算人数 */
29
+ modal = "default",
23
30
  imgKey = "img",
24
31
  hasPagination = true,
25
32
  modelGetType = "getList",
26
33
  allowClear = false,
34
+ unit = "人",
35
+ /** icon自定义 */
36
+ iconCustomFunc,
37
+ /** label插槽 */
38
+ LableSlot,
39
+ /** 列表item自定义渲染 */
40
+ ItemRender,
41
+ /** 选中item自定义渲染 */
42
+ SelectItemRender,
43
+ /** 选中文案自定义 */
44
+ SelectTitleRender,
27
45
  } = props;
28
46
  const [breadcrumb, setBreadcrumb] = useState([
29
47
  {
@@ -79,6 +97,12 @@ function GroupSelection(props, ref) {
79
97
  });
80
98
  };
81
99
 
100
+ const totalSum = useMemo(() => {
101
+ return selectedList?.reduce((pre, cur) => {
102
+ return pre + (cur?.[totalKey] || 0);
103
+ }, 0);
104
+ }, [selectedList]);
105
+
82
106
  useEffect(() => {
83
107
  getTreeData();
84
108
  }, []);
@@ -149,17 +173,29 @@ function GroupSelection(props, ref) {
149
173
  return is;
150
174
  };
151
175
 
176
+ const iconFunc = (item) => {
177
+ // 优先执行自定义函数,拿到结果
178
+ const customResult = iconCustomFunc?.(item);
179
+ // 自定义有返回值直接用,否则走默认逻辑
180
+ if (customResult) return customResult;
181
+ // 默认图片逻辑
182
+ return item[imgKey] ? item[imgKey] : item[isUserKey] ? defaultAvatar : department;
183
+ };
184
+
152
185
  const Renter = (item, noNextLevel) => {
153
186
  const isCheck = handleCheck(item);
154
187
  return (
155
188
  <ItemRenter
156
189
  {...props}
157
190
  item={item}
191
+ iconFunc={iconFunc}
158
192
  isCheck={isCheck}
159
193
  handleCheckItem={handleCheckItem}
160
194
  handleCheckDelete={handleCheckDelete}
161
195
  handleClickItem={handleClickItem}
162
196
  noNextLevel={noNextLevel}
197
+ LableSlot={LableSlot}
198
+ ItemRender={ItemRender}
163
199
  />
164
200
  );
165
201
  };
@@ -188,7 +224,12 @@ function GroupSelection(props, ref) {
188
224
  })}
189
225
  </Breadcrumb>
190
226
  <div className="group-selection-list-check">
191
- <Checkbox onChange={handleCheckAll} checked={checkAll && !!selectList.length} /> 全选
227
+ <Checkbox
228
+ className="group-selection-all-checkbox-box"
229
+ onChange={handleCheckAll}
230
+ checked={checkAll && !!selectList.length}
231
+ />
232
+ 全选
192
233
  </div>
193
234
  <div className="group-selection-list-view">
194
235
  {selectList.map((item, index) => {
@@ -209,18 +250,58 @@ function GroupSelection(props, ref) {
209
250
  </div>
210
251
  <div className="group-selection-detail">
211
252
  {allowClear ? (
212
- <div className="group-selection-detail-title" onClick={handleAllowClear}>
213
- 清空
253
+ <div className="group-selection-detail-title">
254
+ <div className="group-selection-detail-total">
255
+ {SelectTitleRender ? (
256
+ <SelectTitleRender value={modal === "default" ? selectedList?.length : totalSum}></SelectTitleRender>
257
+ ) : (
258
+ ` 已选:${modal === "default" ? selectedList?.length : totalSum}
259
+ ${unit}`
260
+ )}
261
+ </div>
262
+ <div className="group-selection-detail-close" onClick={handleAllowClear}>
263
+ 清空
264
+ </div>
214
265
  </div>
215
266
  ) : null}
267
+ {!selectedList?.length && (
268
+ <div className="group-selection-detail-empty">
269
+ <Empty
270
+ description={"请选择部门或人员"}
271
+ image={EmptyIcon}
272
+ imageStyle={{
273
+ width: "250px",
274
+ height: "99px",
275
+ }}
276
+ ></Empty>
277
+ </div>
278
+ )}
216
279
 
217
280
  <div className="group-selection-detail-list">
218
281
  {selectedList.map((item, index) => {
219
- return (
282
+ return SelectItemRender ? (
283
+ <SelectItemRender
284
+ key={item[valueKey]}
285
+ item={item}
286
+ handleCheckDelete={() => handleCheckDelete(item)}
287
+ ></SelectItemRender>
288
+ ) : (
220
289
  <div className="group-selection-detail-item" key={item[valueKey]}>
221
- <img src={item[imgKey] ? item[imgKey] : item[isUserKey] ? defaultAvatar : department} />
222
- <div className="label">{item[labelKey]}</div>
223
- <CloseCircleFilled style={{ cursor: "pointer" }} onClick={() => handleCheckDelete(item)} />
290
+ <div className="avatar-text-box">
291
+ <Avatar className="avatar-item" size={32} src={iconFunc(item)} />
292
+ {LableSlot ? (
293
+ <LableSlot item={item}></LableSlot>
294
+ ) : (
295
+ <div className="label">
296
+ <div>{item[labelKey]}</div>
297
+ <div className="label-phone">{item[phoneKey]}</div>
298
+ </div>
299
+ )}
300
+ </div>
301
+ <CloseOutlined
302
+ style={{ cursor: "pointer", color: "#6a6a6a" }}
303
+ onClick={() => handleCheckDelete(item)}
304
+ />
224
305
  </div>
225
306
  );
226
307
  })}