17
17
package top .continew .admin .system .service .impl ;
18
18
19
19
import cn .hutool .core .collection .CollUtil ;
20
+ import cn .hutool .core .lang .tree .Tree ;
21
+ import cn .hutool .core .lang .tree .TreeNodeConfig ;
22
+ import cn .hutool .core .lang .tree .TreeUtil ;
23
+ import cn .hutool .core .text .CharSequenceUtil ;
20
24
import cn .hutool .core .util .ObjectUtil ;
25
+ import cn .hutool .core .util .ReflectUtil ;
21
26
import com .baomidou .mybatisplus .core .toolkit .Wrappers ;
22
27
import jakarta .annotation .Resource ;
23
28
import lombok .RequiredArgsConstructor ;
26
31
import top .continew .admin .system .mapper .DeptMapper ;
27
32
import top .continew .admin .system .model .entity .DeptDO ;
28
33
import top .continew .admin .system .model .query .DeptQuery ;
34
+ import top .continew .admin .system .model .query .UserQuery ;
29
35
import top .continew .admin .system .model .req .DeptReq ;
30
36
import top .continew .admin .system .model .resp .DeptResp ;
37
+ import top .continew .admin .system .model .resp .UserResp ;
31
38
import top .continew .admin .system .service .DeptService ;
32
39
import top .continew .admin .system .service .RoleDeptService ;
33
40
import top .continew .admin .system .service .UserService ;
41
+ import top .continew .starter .core .util .ReflectUtils ;
34
42
import top .continew .starter .core .util .validate .CheckUtils ;
35
43
import top .continew .starter .data .core .enums .DatabaseType ;
36
44
import top .continew .starter .data .core .util .MetaUtils ;
45
+ import top .continew .starter .extension .crud .annotation .TreeField ;
46
+ import top .continew .starter .extension .crud .model .query .SortQuery ;
37
47
import top .continew .starter .extension .crud .service .impl .BaseServiceImpl ;
48
+ import top .continew .starter .extension .crud .util .TreeUtils ;
38
49
39
50
import javax .sql .DataSource ;
40
- import java .util .ArrayList ;
41
- import java .util .Collections ;
42
- import java .util .List ;
43
- import java .util .Optional ;
51
+ import java .lang .reflect .Field ;
52
+ import java .util .*;
53
+ import java .util .stream .Collectors ;
44
54
45
55
/**
46
56
* 部门业务实现
@@ -80,6 +90,71 @@ public int countByNames(List<String> deptNames) {
80
90
return (int )this .count (Wrappers .<DeptDO >lambdaQuery ().in (DeptDO ::getName , deptNames ));
81
91
}
82
92
93
+ @ Override
94
+ public List <Tree <String >> treeWithUsers (DeptQuery query , SortQuery sortQuery , boolean isSimple ) {
95
+ List <DeptResp > list = this .list (query , sortQuery );
96
+ if (CollUtil .isEmpty (list )) {
97
+ return new ArrayList <>(0 );
98
+ } else {
99
+ TreeNodeConfig treeNodeConfig = TreeUtils .DEFAULT_CONFIG ;
100
+ TreeField treeField = this .getListClass ().getDeclaredAnnotation (TreeField .class );
101
+ if (!isSimple ) {
102
+ treeNodeConfig = TreeUtils .genTreeNodeConfig (treeField );
103
+ }
104
+
105
+ // 创建一个部门ID到用户的映射
106
+ UserQuery userQuery = new UserQuery ();
107
+ userQuery .setStatus (DisEnableStatusEnum .ENABLE );
108
+ Map <Long , List <UserResp >> userMap = userService .list (userQuery , null ).stream ()
109
+ .collect (Collectors .groupingBy (UserResp ::getDeptId ));
110
+
111
+ String rootId = "dept_0" ;
112
+
113
+ return TreeUtil .build (list , rootId , treeNodeConfig , (node , tree ) -> {
114
+ Long departmentId = ReflectUtil .invoke (node , CharSequenceUtil .genGetter (treeField .value ()), new Object [0 ]);
115
+ String uniqueDeptId = "dept_" + departmentId ;
116
+ tree .setId (uniqueDeptId );
117
+ Long parentId = ReflectUtil .invoke (node , CharSequenceUtil .genGetter (treeField .parentIdKey ()), new Object [0 ]);
118
+ tree .setParentId (parentId != null ? "dept_" + parentId : null );
119
+ tree .setName (ReflectUtil .invoke (node , CharSequenceUtil .genGetter (treeField .nameKey ()), new Object [0 ]));
120
+ tree .setWeight (ReflectUtil .invoke (node , CharSequenceUtil .genGetter (treeField .weightKey ()), new Object [0 ]));
121
+ tree .putExtra ("origId" , departmentId );
122
+ tree .putExtra ("isUser" , false );
123
+
124
+ // 添加用户信息到树节点
125
+ if (userMap .containsKey (departmentId )) {
126
+ List <UserResp > userList = userMap .get (departmentId );
127
+ List <Tree <String >> userTrees = userList .stream ()
128
+ .map (user -> {
129
+ Tree <String > userTree = new Tree <>();
130
+ String uniqueUserId = "user_" + user .getId ();
131
+ String userAliasName = user .getUsername () + "(" + user .getNickname () + ")" ;
132
+ userTree .setId (uniqueUserId );
133
+ userTree .setParentId (uniqueDeptId );
134
+ userTree .setName (userAliasName );
135
+ userTree .setWeight (0 );
136
+ userTree .putExtra ("origId" , user .getId ()); // 添加原始用户ID
137
+ userTree .putExtra ("isUser" , true ); // 添加原始用户ID
138
+ return userTree ;
139
+ })
140
+ .collect (Collectors .toList ());
141
+ tree .setChildren (userTrees );
142
+ }
143
+
144
+ if (!isSimple ) {
145
+ List <Field > fieldList = ReflectUtils .getNonStaticFields (this .getListClass ());
146
+ fieldList .removeIf ((f ) -> {
147
+ return CharSequenceUtil .equalsAnyIgnoreCase (f .getName (), new CharSequence []{treeField .value (), treeField .parentIdKey (), treeField .nameKey (), treeField .weightKey (), treeField .childrenKey ()});
148
+ });
149
+ fieldList .forEach ((f ) -> {
150
+ tree .putExtra (f .getName (), ReflectUtil .invoke (node , CharSequenceUtil .genGetter (f .getName ()), new Object [0 ]));
151
+ });
152
+ }
153
+ });
154
+ }
155
+ }
156
+
157
+
83
158
@ Override
84
159
protected void beforeAdd (DeptReq req ) {
85
160
String name = req .getName ();
@@ -105,13 +180,13 @@ protected void beforeUpdate(DeptReq req, Long id) {
105
180
if (ObjectUtil .notEqual (newStatus , oldDept .getStatus ())) {
106
181
List <DeptDO > children = this .listChildren (id );
107
182
long enabledChildrenCount = children .stream ()
108
- .filter (d -> DisEnableStatusEnum .ENABLE .equals (d .getStatus ()))
109
- .count ();
183
+ .filter (d -> DisEnableStatusEnum .ENABLE .equals (d .getStatus ()))
184
+ .count ();
110
185
CheckUtils .throwIf (DisEnableStatusEnum .DISABLE
111
- .equals (newStatus ) && enabledChildrenCount > 0 , "禁用 [{}] 前,请先禁用其所有下级部门" , oldName );
186
+ .equals (newStatus ) && enabledChildrenCount > 0 , "禁用 [{}] 前,请先禁用其所有下级部门" , oldName );
112
187
DeptDO oldParentDept = this .getByParentId (oldParentId );
113
188
CheckUtils .throwIf (DisEnableStatusEnum .ENABLE .equals (newStatus ) && DisEnableStatusEnum .DISABLE
114
- .equals (oldParentDept .getStatus ()), "启用 [{}] 前,请先启用其所有上级部门" , oldName );
189
+ .equals (oldParentDept .getStatus ()), "启用 [{}] 前,请先启用其所有上级部门" , oldName );
115
190
}
116
191
// 变更上级部门
117
192
if (ObjectUtil .notEqual (req .getParentId (), oldParentId )) {
@@ -126,12 +201,12 @@ protected void beforeUpdate(DeptReq req, Long id) {
126
201
@ Override
127
202
protected void beforeDelete (List <Long > ids ) {
128
203
List <DeptDO > list = baseMapper .lambdaQuery ()
129
- .select (DeptDO ::getName , DeptDO ::getIsSystem )
130
- .in (DeptDO ::getId , ids )
131
- .list ();
204
+ .select (DeptDO ::getName , DeptDO ::getIsSystem )
205
+ .in (DeptDO ::getId , ids )
206
+ .list ();
132
207
Optional <DeptDO > isSystemData = list .stream ().filter (DeptDO ::getIsSystem ).findFirst ();
133
208
CheckUtils .throwIf (isSystemData ::isPresent , "所选部门 [{}] 是系统内置部门,不允许删除" , isSystemData .orElseGet (DeptDO ::new )
134
- .getName ());
209
+ .getName ());
135
210
CheckUtils .throwIf (this .countChildren (ids ) > 0 , "所选部门存在下级部门,不允许删除" );
136
211
CheckUtils .throwIf (userService .countByDeptIds (ids ) > 0 , "所选部门存在用户关联,请解除关联后重试" );
137
212
// 删除角色和部门关联
@@ -148,10 +223,10 @@ protected void beforeDelete(List<Long> ids) {
148
223
*/
149
224
private boolean isNameExists (String name , Long parentId , Long id ) {
150
225
return baseMapper .lambdaQuery ()
151
- .eq (DeptDO ::getName , name )
152
- .eq (DeptDO ::getParentId , parentId )
153
- .ne (null != id , DeptDO ::getId , id )
154
- .exists ();
226
+ .eq (DeptDO ::getName , name )
227
+ .eq (DeptDO ::getParentId , parentId )
228
+ .ne (null != id , DeptDO ::getId , id )
229
+ .exists ();
155
230
}
156
231
157
232
/**
@@ -189,8 +264,8 @@ private Long countChildren(List<Long> ids) {
189
264
}
190
265
DatabaseType databaseType = MetaUtils .getDatabaseTypeOrDefault (dataSource , DatabaseType .MYSQL );
191
266
return ids .stream ()
192
- .mapToLong (id -> baseMapper .lambdaQuery ().apply (databaseType .findInSet (id , "ancestors" )).count ())
193
- .sum ();
267
+ .mapToLong (id -> baseMapper .lambdaQuery ().apply (databaseType .findInSet (id , "ancestors" )).count ())
268
+ .sum ();
194
269
}
195
270
196
271
/**
0 commit comments