Showing
8 changed files
with
159 additions
and
24 deletions
... | ... | @@ -149,6 +149,9 @@ public class TkUserController extends AbstractUserAccount { |
149 | 149 | @RequestParam(PAGE) int page, |
150 | 150 | @RequestParam(value = ORDER_FILED, required = false) String orderBy, |
151 | 151 | @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType, |
152 | + @RequestParam(value = "organizationId", required = false) String organizationId, | |
153 | + @RequestParam(value = "username", required = false) String username, | |
154 | + @RequestParam(value = "realName", required = false) String realName, | |
152 | 155 | @RequestParam(TENANT_ID) String tenantId) |
153 | 156 | throws ThingsboardException { |
154 | 157 | HashMap<String, Object> queryMap = new HashMap<>(); |
... | ... | @@ -158,15 +161,25 @@ public class TkUserController extends AbstractUserAccount { |
158 | 161 | queryMap.put(ORDER_TYPE, orderType.name()); |
159 | 162 | } |
160 | 163 | queryMap.put(ORDER_FILED, orderBy); |
161 | - if (getCurrentUser().isPtTenantAdmin()) { | |
162 | - queryMap.put("level", FastIotConstants.MagicNumber.FOUR); | |
163 | - }else{ | |
164 | + if(StringUtils.isNotEmpty(username)){ | |
165 | + queryMap.put("username",username); | |
166 | + } | |
167 | + if(StringUtils.isNotEmpty(realName)){ | |
168 | + queryMap.put("realName",realName); | |
169 | + } | |
170 | + if (getCurrentUser().isPtAdmin() || getCurrentUser().isSystemAdmin()) { | |
164 | 171 | queryMap.put("level", FastIotConstants.MagicNumber.TWO); |
172 | + }else{ | |
173 | + queryMap.put("level", FastIotConstants.MagicNumber.FOUR); | |
174 | + queryMap.put("currentUserId",getCurrentUser().getCurrentUserId()); | |
175 | + if(StringUtils.isNotEmpty(organizationId)){ | |
176 | + queryMap.put("organizationId", organizationId); | |
177 | + } | |
165 | 178 | } |
166 | 179 | if (StringUtils.isEmpty(tenantId)) { |
167 | 180 | throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); |
168 | 181 | } |
169 | - return userService.tenantPage(queryMap, tenantId); | |
182 | + return userService.tenantPage(queryMap, tenantId,getCurrentUser().isPtCommonTenant()); | |
170 | 183 | } |
171 | 184 | |
172 | 185 | @PutMapping | ... | ... |
dao/src/main/java/org/thingsboard/server/dao/yunteng/impl/SysUserOrganizationMappingServiceImpl.java
... | ... | @@ -14,8 +14,8 @@ import org.thingsboard.server.common.data.yunteng.dto.BaseDTO; |
14 | 14 | import org.thingsboard.server.common.data.yunteng.dto.OrganizationDTO; |
15 | 15 | import org.thingsboard.server.common.data.yunteng.enums.OrganizationEnum; |
16 | 16 | import org.thingsboard.server.dao.yunteng.entities.TkUserOrganizationMappingEntity; |
17 | +import org.thingsboard.server.dao.yunteng.mapper.OrganizationMapper; | |
17 | 18 | import org.thingsboard.server.dao.yunteng.mapper.UserOrganizationMappingMapper; |
18 | -import org.thingsboard.server.dao.yunteng.service.TkOrganizationService; | |
19 | 19 | import org.thingsboard.server.dao.yunteng.service.UserOrganizationMappingService; |
20 | 20 | |
21 | 21 | import java.util.ArrayList; |
... | ... | @@ -35,12 +35,12 @@ import java.util.stream.Collectors; |
35 | 35 | public class SysUserOrganizationMappingServiceImpl implements UserOrganizationMappingService { |
36 | 36 | |
37 | 37 | private final UserOrganizationMappingMapper userOrganizationMappingMapper; |
38 | - private final TkOrganizationService organizationService; | |
38 | + private final OrganizationMapper organizationMapper; | |
39 | 39 | |
40 | 40 | @Override |
41 | 41 | public List<String> getUserIdByOrganizationIds(String tenantId,OrganizationEnum sort , String... ids) { |
42 | 42 | List<String> collect = |
43 | - organizationService.findOrganizationTreeList(tenantId, sort, List.of(ids)).stream() | |
43 | + organizationMapper.findOrganizationTreeList(tenantId, sort !=null?sort.toString():null, List.of(ids)).stream() | |
44 | 44 | .map(OrganizationDTO::getId) |
45 | 45 | .collect(Collectors.toList()); |
46 | 46 | if (null == collect || collect.size() == 0) { |
... | ... | @@ -48,18 +48,29 @@ public class SysUserOrganizationMappingServiceImpl implements UserOrganizationMa |
48 | 48 | } else { |
49 | 49 | Set<String> clearList = new HashSet<>(); |
50 | 50 | clearList.addAll(collect); |
51 | - return userOrganizationMappingMapper | |
52 | - .selectList( | |
53 | - new LambdaQueryWrapper<TkUserOrganizationMappingEntity>() | |
54 | - .in(TkUserOrganizationMappingEntity::getOrganizationId, clearList)) | |
55 | - .stream() | |
56 | - .map(TkUserOrganizationMappingEntity::getUserId) | |
57 | - .distinct() | |
58 | - .collect(Collectors.toList()); | |
51 | + return getUserIdsByOrganizationIds(clearList,null); | |
59 | 52 | } |
60 | 53 | } |
61 | 54 | |
62 | 55 | @Override |
56 | + public List<String> getUserIdsByOrganizationIds(Set<String> organizationIds,String filterOrganizationId) { | |
57 | + if(null != organizationIds && !organizationIds.isEmpty() && !StringUtils.isEmpty(filterOrganizationId)){ | |
58 | + organizationIds.remove(filterOrganizationId); | |
59 | + } | |
60 | + if(null == organizationIds || organizationIds.isEmpty()){ | |
61 | + return new ArrayList<>(); | |
62 | + } | |
63 | + return userOrganizationMappingMapper | |
64 | + .selectList( | |
65 | + new LambdaQueryWrapper<TkUserOrganizationMappingEntity>() | |
66 | + .in(TkUserOrganizationMappingEntity::getOrganizationId, organizationIds)) | |
67 | + .stream() | |
68 | + .map(TkUserOrganizationMappingEntity::getUserId) | |
69 | + .distinct() | |
70 | + .collect(Collectors.toList()); | |
71 | + } | |
72 | + | |
73 | + @Override | |
63 | 74 | @Transactional |
64 | 75 | public void addOrUpdateUserOrganizationMapping( |
65 | 76 | String userId, List<String> organizationIds, boolean isUpdate) { |
... | ... | @@ -106,8 +117,8 @@ public class SysUserOrganizationMappingServiceImpl implements UserOrganizationMa |
106 | 117 | List<String> organizationIds = null; |
107 | 118 | if (StringUtils.isNotEmpty(organizationId)) { |
108 | 119 | List<OrganizationDTO> organizationList = |
109 | - organizationService.findOrganizationTreeList( | |
110 | - tenantId,null, new HashSet<>(List.of(organizationId))); | |
120 | + organizationMapper.findOrganizationTreeList( | |
121 | + tenantId,OrganizationEnum.DOWN.toString(), new HashSet<>(List.of(organizationId))); | |
111 | 122 | if (organizationList.size() == FastIotConstants.MagicNumber.ZERO) { |
112 | 123 | throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); |
113 | 124 | } | ... | ... |
... | ... | @@ -367,7 +367,31 @@ public class SysUserServiceImpl extends AbstractBaseService<UserMapper, SysUserE |
367 | 367 | } |
368 | 368 | |
369 | 369 | @Override |
370 | - public TkPageData<UserDTO> tenantPage(Map<String, Object> queryMap, String tenantId) { | |
370 | + public TkPageData<UserDTO> tenantPage(Map<String, Object> queryMap, String tenantId,boolean isCommonTenantAdmin) { | |
371 | + String organizationId = null !=queryMap.get("organizationId")?queryMap.get("organizationId").toString():null; | |
372 | + String currentUserId = null !=queryMap.get("currentUserId")?queryMap.get("currentUserId").toString():null; | |
373 | + Integer level = Integer.valueOf(queryMap.get("level").toString()); | |
374 | + List<String> userIds = null; | |
375 | + boolean isTenantAdminOrCommon = MagicNumber.FOUR == level && null != currentUserId; | |
376 | + boolean continueQueryPageData = false; | |
377 | + if(isTenantAdminOrCommon && !isCommonTenantAdmin && StringUtils.isEmpty(organizationId)){ | |
378 | + //如果是租户管理员查询分页,没有传组织ID就直接进行后续分页查询 | |
379 | + continueQueryPageData = true; | |
380 | + } | |
381 | + if(isTenantAdminOrCommon && !isCommonTenantAdmin && StringUtils.isNotEmpty(organizationId)){ | |
382 | + userIds = tenantAdminOperator(tenantId,organizationId); | |
383 | + } | |
384 | + if( isTenantAdminOrCommon && isCommonTenantAdmin){ | |
385 | + userIds = commonTenantAdminOperator(tenantId,currentUserId,organizationId); | |
386 | + } | |
387 | + if(null != userIds && !userIds.isEmpty()){ | |
388 | + queryMap.put("userIds",userIds); | |
389 | + } | |
390 | + if(isTenantAdminOrCommon && !continueQueryPageData){ | |
391 | + if(null == userIds || userIds.isEmpty()){ | |
392 | + return new TkPageData<>(new ArrayList<UserDTO>(),0); | |
393 | + } | |
394 | + } | |
371 | 395 | IPage<SysUserEntity> userIPage = getPage(queryMap, "create_time", false); |
372 | 396 | IPage<UserDTO> userPage = baseMapper.getTenantAdminPage(userIPage, tenantId,queryMap); |
373 | 397 | if (null != userPage) { |
... | ... | @@ -383,6 +407,67 @@ public class SysUserServiceImpl extends AbstractBaseService<UserMapper, SysUserE |
383 | 407 | return getPageData(userPage, UserDTO.class); |
384 | 408 | } |
385 | 409 | |
410 | + private List<String> tenantAdminOperator(String tenantId,String organizationId){ | |
411 | + List<String> userIds = null; | |
412 | + List<String> organizationIds = organizationService.organizationAllIds(tenantId,organizationId); | |
413 | + if(null != organizationIds && !organizationIds.isEmpty()){ | |
414 | + userIds = userOrganizationMappingService.getUserIdByOrganizationIds(tenantId,OrganizationEnum.DOWN, | |
415 | + organizationIds.toArray(new String[organizationIds.size()])); | |
416 | + } | |
417 | + //过滤当前组织的上级组织的账号 | |
418 | + userIds = filterParentUserId(tenantId,organizationId,userIds); | |
419 | + return userIds; | |
420 | + } | |
421 | + | |
422 | + private List<String> commonTenantAdminOperator(String tenantId,String currentUserId,String organizationId){ | |
423 | + List<String> userIds; | |
424 | + //找到当前用户的组织 | |
425 | + List<String> organizationIds = userOrganizationMappingService.getOrganizationIdsByUserId(currentUserId); | |
426 | + //找到当前组织关联的所有账号 | |
427 | + userIds = queryCurrentUser(tenantId,organizationId,organizationIds); | |
428 | + //找到当前用户组织的上级组织的账号 | |
429 | + if(null !=organizationIds && !organizationIds.isEmpty()){ | |
430 | + Set<String> filterUserIds = new HashSet<>(); | |
431 | + for (String orgId :organizationIds){ | |
432 | + List<String> parentUserIds = filterParentUserId(tenantId,orgId,userIds); | |
433 | + if(null != parentUserIds && !parentUserIds.isEmpty()){ | |
434 | + filterUserIds.addAll(parentUserIds); | |
435 | + } | |
436 | + } | |
437 | + if(!filterUserIds.isEmpty()){ | |
438 | + filterUserIds.remove(currentUserId); | |
439 | + userIds = new ArrayList<>(); | |
440 | + userIds.addAll(filterUserIds); | |
441 | + } | |
442 | + } | |
443 | + return userIds; | |
444 | + } | |
445 | + private List<String> queryCurrentUser(String tenantId,String organizationId,List<String> organizationIds){ | |
446 | + if(!StringUtils.isEmpty(organizationId)){ | |
447 | + if(organizationIds.contains(organizationId)){ | |
448 | + //查询当前组织下的所有下级组织 | |
449 | + organizationIds = organizationService.organizationAllIds(tenantId,organizationId); | |
450 | + }else{ | |
451 | + return null; | |
452 | + } | |
453 | + } | |
454 | + if(null != organizationIds && !organizationIds.isEmpty()){ | |
455 | + return userOrganizationMappingService.getUserIdByOrganizationIds(tenantId,OrganizationEnum.DOWN, | |
456 | + organizationIds.toArray(new String[organizationIds.size()])); | |
457 | + } | |
458 | + return null; | |
459 | + } | |
460 | + | |
461 | + private List<String> filterParentUserId(String tenantId,String organizationId,List<String> sourceUserIds){ | |
462 | + Set<String> organizationIds = organizationService.findOrganizationTreeList(tenantId, OrganizationEnum.UP, List.of(organizationId)).stream() | |
463 | + .map(OrganizationDTO::getId) | |
464 | + .collect(Collectors.toSet()); | |
465 | + | |
466 | + List<String> userIds = userOrganizationMappingService.getUserIdsByOrganizationIds(organizationIds,organizationId); | |
467 | + return sourceUserIds.stream() | |
468 | + .filter(element -> !userIds.contains(element)) | |
469 | + .collect(Collectors.toList()); | |
470 | + } | |
386 | 471 | private void fillUserStatus(UserDTO userDTO) { |
387 | 472 | userDTO.setUserStatusEnum(UserStatusEnum.NORMAL); |
388 | 473 | if (!userDTO.isEnabled()) { | ... | ... |
... | ... | @@ -20,6 +20,7 @@ import org.thingsboard.server.dao.yunteng.entities.*; |
20 | 20 | import org.thingsboard.server.dao.yunteng.mapper.*; |
21 | 21 | import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; |
22 | 22 | import org.thingsboard.server.dao.yunteng.service.TkOrganizationService; |
23 | +import org.thingsboard.server.dao.yunteng.service.UserOrganizationMappingService; | |
23 | 24 | |
24 | 25 | import java.util.*; |
25 | 26 | import java.util.stream.Collectors; |
... | ... | @@ -38,6 +39,7 @@ public class TkOrganizationServiceImpl extends AbstractBaseService<OrganizationM |
38 | 39 | private final String cacheName = FastIotConstants.CacheConfigKey.ORGANIZATION; |
39 | 40 | private final CacheUtils cacheUtils; |
40 | 41 | |
42 | + private final UserOrganizationMappingService userOrganizationMappingService; | |
41 | 43 | @Override |
42 | 44 | @Transactional |
43 | 45 | public OrganizationDTO saveOrganization( |
... | ... | @@ -211,7 +213,7 @@ public class TkOrganizationServiceImpl extends AbstractBaseService<OrganizationM |
211 | 213 | //如果源上级组织与目标组织有变更,则需要更新用户组织映射表信息 |
212 | 214 | if(!Objects.equals(sourceParentOrganizationId,parentId)){ |
213 | 215 | //删除当前组织关联的源用户映射 |
214 | - deleteUserOrganizationMappingByOrganizationId(organizationId); | |
216 | + deleteUserOrganizationMappingByOrganizationId(tenantId,organizationId); | |
215 | 217 | //查询目标组织的用户列表,新增当前组织关联的目标用户映射 |
216 | 218 | addUserOrganizationMapping(parentId,organizationId); |
217 | 219 | } |
... | ... | @@ -219,9 +221,17 @@ public class TkOrganizationServiceImpl extends AbstractBaseService<OrganizationM |
219 | 221 | return organizationDTO; |
220 | 222 | } |
221 | 223 | |
222 | - private void deleteUserOrganizationMappingByOrganizationId(String organizationId){ | |
223 | - userOrganizationMappingMapper.delete(new LambdaQueryWrapper<TkUserOrganizationMappingEntity>() | |
224 | - .eq(TkUserOrganizationMappingEntity::getOrganizationId,organizationId)); | |
224 | + private void deleteUserOrganizationMappingByOrganizationId(String tenantId,String organizationId){ | |
225 | + Set<String> organizationIds = findOrganizationTreeList(tenantId, OrganizationEnum.UP, List.of(organizationId)).stream() | |
226 | + .map(OrganizationDTO::getId) | |
227 | + .collect(Collectors.toSet()); | |
228 | + //查询上级组织的账号 | |
229 | + List<String> userIds = userOrganizationMappingService.getUserIdsByOrganizationIds(organizationIds,organizationId); | |
230 | + for (String userId : userIds){ | |
231 | + userOrganizationMappingMapper.delete(new LambdaQueryWrapper<TkUserOrganizationMappingEntity>() | |
232 | + .eq(TkUserOrganizationMappingEntity::getOrganizationId,organizationId) | |
233 | + .eq(TkUserOrganizationMappingEntity::getUserId,userId)); | |
234 | + } | |
225 | 235 | } |
226 | 236 | |
227 | 237 | private void addUserOrganizationMapping(String targetParentId,String organizationId){ | ... | ... |
... | ... | @@ -34,7 +34,7 @@ public interface TkUserService { |
34 | 34 | TkPageData<UserDTO> page( |
35 | 35 | Map<String, Object> queryMap, boolean isPtSysadmin, boolean isTenantAdmin); |
36 | 36 | |
37 | - TkPageData<UserDTO> tenantPage(Map<String, Object> queryMap, String tenantId); | |
37 | + TkPageData<UserDTO> tenantPage(Map<String, Object> queryMap, String tenantId,boolean isCommonTenantAdmin); | |
38 | 38 | |
39 | 39 | UserDTO updateUser(UserDTO userDTO, boolean isPtSysadmin, String tenantId); |
40 | 40 | ... | ... |
... | ... | @@ -14,6 +14,8 @@ public interface UserOrganizationMappingService { |
14 | 14 | |
15 | 15 | List<String> getUserIdByOrganizationIds(String tenantId, OrganizationEnum sort , String... ids); |
16 | 16 | |
17 | + List<String> getUserIdsByOrganizationIds(Set<String> organizationIds,String filterOrganizationId); | |
18 | + | |
17 | 19 | /** |
18 | 20 | * 添加或更新用户组织关系 |
19 | 21 | * | ... | ... |
... | ... | @@ -29,7 +29,7 @@ |
29 | 29 | UNION ALL |
30 | 30 | SELECT ig.id, ig.parent_id, ig.name, ig.sort,ig.creator,ig.create_time,ig.updater,ig.update_time,ig.remark,ig.tenant_id |
31 | 31 | FROM tk_organization ig |
32 | - <if test="sort =='UP'"> | |
32 | + <if test="sort == 'UP'"> | |
33 | 33 | JOIN organization ON ig.id = organization.parent_id |
34 | 34 | </if> |
35 | 35 | <if test="sort == 'DOWN'"> | ... | ... |
... | ... | @@ -128,9 +128,23 @@ |
128 | 128 | FROM sys_user su |
129 | 129 | LEFT JOIN sys_tenant st ON su.tenant_id = st.tenant_id |
130 | 130 | WHERE su.tenant_id = #{tenantId} |
131 | + <if test="queryMap.username !=null and queryMap.username!=''"> | |
132 | + AND su.username LIKE CONCAT('%',#{queryMap.username}::TEXT,'%') | |
133 | + | |
134 | + </if> | |
135 | + <if test="queryMap.realName !=null and queryMap.realName!=''"> | |
136 | + AND su.real_name LIKE CONCAT('%',#{queryMap.realName}::TEXT,'%') | |
137 | + | |
138 | + </if> | |
131 | 139 | <if test="queryMap.level !=null"> |
132 | 140 | AND su.level= #{queryMap.level} |
133 | 141 | </if> |
142 | + <if test="queryMap.userIds !=null"> | |
143 | + AND su.id IN | |
144 | + <foreach collection="queryMap.userIds" item="userId" open="(" separator="," close=")"> | |
145 | + #{userId} | |
146 | + </foreach> | |
147 | + </if> | |
134 | 148 | </select> |
135 | 149 | <select id="getAllIdsByTenantId" resultType="java.lang.String"> |
136 | 150 | SELECT id FROM sys_user WHERE tenant_id IN | ... | ... |