Commit cda4af661d3ec29566a9eb15b605c0d47fb0c324

Authored by xp.Huang
1 parent da458ece

fix: 租户管理员子账号的权限及组织查询

... ... @@ -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
... ...
... ... @@ -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
... ...