diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java index 98518200..511e0286 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java @@ -11,7 +11,6 @@ import cn.axzo.tyr.client.model.req.QueryRoleByNameReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleReq; import cn.axzo.tyr.client.model.req.RoleWithUserQueryReq; import cn.axzo.tyr.client.model.req.TreeRoleReq; -import cn.axzo.tyr.client.model.req.UpdateRoleGroupOffsetReq; import cn.axzo.tyr.client.model.req.UpdateRoleOffsetReq; import cn.axzo.tyr.client.model.res.FeatureRoleRelationResp; import cn.axzo.tyr.client.model.res.IsSuperAdminRes; @@ -20,6 +19,7 @@ import cn.axzo.tyr.client.model.res.QueryRoleByNameResp; import cn.axzo.tyr.client.model.res.RoleTreeRes; import cn.axzo.tyr.client.model.res.RoleWithUserRes; import cn.axzo.tyr.client.model.res.SaasRoleRes; +import cn.axzo.tyr.client.model.vo.DeleteRoleVO; import cn.axzo.tyr.client.model.vo.SaasRoleAndGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleCategoryVO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupCodeVO; @@ -77,8 +77,7 @@ public interface TyrSaasRoleApi { * 删除 */ @PostMapping("/api/saasRole/delete") - @Deprecated - ApiResult delete(@RequestBody List id); + ApiResult delete(@RequestBody DeleteRoleVO request); /** diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/DeleteRoleVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/DeleteRoleVO.java new file mode 100644 index 00000000..96f0c10d --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/DeleteRoleVO.java @@ -0,0 +1,36 @@ +package cn.axzo.tyr.client.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeleteRoleVO { + /** + * 待删除角色集合 + */ + @NotEmpty(message = "roleIds不能为空") + private List roleIds; + + /** + * 待删除角色所属workSpaceId 历史接口需要 + */ + private Long workSpaceId; + + /** + * 待删除角色所属单位ID 历史接口需要 + */ + private Long outId; + + /** + * 历史接口对已经有user绑定到role有进行check,不能删除 + */ + private boolean needUsedCheck; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index 985a3469..d2667ed0 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -25,6 +25,7 @@ import cn.axzo.tyr.client.model.res.QueryRoleByNameResp; import cn.axzo.tyr.client.model.res.RoleTreeRes; import cn.axzo.tyr.client.model.res.RoleWithUserRes; import cn.axzo.tyr.client.model.res.SaasRoleRes; +import cn.axzo.tyr.client.model.vo.DeleteRoleVO; import cn.axzo.tyr.client.model.vo.SaasRoleAndGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleCategoryVO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupCodeVO; @@ -135,13 +136,21 @@ public class SaasRoleController implements TyrSaasRoleApi { @Override public ApiResult deleteRole(List roleIds, Long workSpaceId, Long outId) { - roleService.deleteRole(roleIds, workSpaceId, outId); + DeleteRoleVO deleteRoleParam = DeleteRoleVO.builder() + .roleIds(roleIds) + .workSpaceId(workSpaceId) + .outId(outId) + .needUsedCheck(true) + .build(); + roleService.deleteRole(deleteRoleParam); permissionCacheService.markTempDisable(PermissionCacheKey.builder().disableAll(true).build()); return ApiResult.ok(); } @Override - public ApiResult delete(List roleIds) { + public ApiResult delete(DeleteRoleVO reqeust) { + roleService.deleteRole(reqeust); + permissionCacheService.markTempDisable(PermissionCacheKey.builder().disableAll(true).build()); return ApiResult.ok(); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index 69af777c..8e7631aa 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -17,6 +17,7 @@ import cn.axzo.tyr.client.model.res.QueryBatchByIdentityIdTypeRes; import cn.axzo.tyr.client.model.res.QueryRoleByNameResp; import cn.axzo.tyr.client.model.res.RoleWithUserRes; import cn.axzo.tyr.client.model.res.SaasRoleRes; +import cn.axzo.tyr.client.model.vo.DeleteRoleVO; import cn.axzo.tyr.client.model.vo.SaasRoleAndGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleCategoryVO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupCodeVO; @@ -100,11 +101,9 @@ public interface RoleService extends IService { /** * 删除角色列表 - * @param roleIds 待删除角色集合 - * @param workSpaceId 待删除角色所属workSpaceId - * @param outId 待删除角色所属单位ID + * @param deleteRoleParam */ - void deleteRole(List roleIds,Long workSpaceId,Long outId); + void deleteRole(DeleteRoleVO deleteRoleParam); List queryRoleByFeatures(Set matchedFeatureIds); @@ -142,6 +141,9 @@ public interface RoleService extends IService { @CriteriaField(field = "isDisplay", operator = Operator.EQ) private Boolean isDisplay; + @CriteriaField(field = "roleCode", operator = Operator.EQ) + private String roleCode; + @CriteriaField(ignore = true) private Boolean needPermission; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index 6ac8177d..9bcc3fe8 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -27,6 +27,7 @@ import cn.axzo.tyr.client.model.res.RoleWithUserRes; import cn.axzo.tyr.client.model.res.SaasPermissionRes; import cn.axzo.tyr.client.model.res.SaasRoleGroupRes; import cn.axzo.tyr.client.model.res.SaasRoleRes; +import cn.axzo.tyr.client.model.vo.DeleteRoleVO; import cn.axzo.tyr.client.model.vo.SaasPermissionGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleAndGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleCategoryVO; @@ -459,12 +460,39 @@ public class RoleServiceImpl extends ServiceImpl return saasRoleDao.listRoleUserByPermissionGroup(permissionGroupIdList, workspaceIds); } + private void checkRoleCode(SaveOrUpdateRoleVO saveOrUpdateRole) { + + if (StringUtils.isBlank(saveOrUpdateRole.getRoleCode())) { + return; + } + List oldSaasRoles = this.list(ListSaasRoleParam.builder() + .roleCode(saveOrUpdateRole.getRoleCode()) + .build()); + if (CollectionUtils.isNotEmpty(oldSaasRoles)) { + throw new ServiceException("角色编码已存在"); + } + } + + /** + * roleType = 自定义,common,workspaceType = saveOrUpdateRole.workspaceType + * 其他就从角色组取,没有就saveOrUpdateRole.workspaceType + * @param saveOrUpdateRole + * @return + */ + private Integer resolveWorkspaceType(SaveOrUpdateRoleVO saveOrUpdateRole) { + if (COMMON_ROLE_TYPES.contains(saveOrUpdateRole.getRoleType()) || CollectionUtils.isEmpty(saveOrUpdateRole.getGroupTree())) { + return saveOrUpdateRole.getWorkspaceType(); + } + return Integer.parseInt(saveOrUpdateRole.getGroupTree().get(0).getWorkspaceTypeCode()); + } + private SaasRole validAndBuildRole(SaveOrUpdateRoleVO saveOrUpdateRole, Date now) { SaasRole saasRole; if (Objects.isNull(saveOrUpdateRole.getId())) { saasRole = new SaasRole(); saasRole.setCreateBy(saveOrUpdateRole.getOperatorId()); saasRole.setCreateAt(now); + checkRoleCode(saveOrUpdateRole); } else { saasRole = saasRoleDao.getById(saveOrUpdateRole.getId()); if (Objects.isNull(saasRole)) { @@ -479,14 +507,9 @@ public class RoleServiceImpl extends ServiceImpl saasRole.setRoleType(saveOrUpdateRole.getRoleType()); saasRole.setWorkspaceId(saveOrUpdateRole.getWorkspaceId()); saasRole.setOwnerOuId(saveOrUpdateRole.getOwnerOuId()); - // roleType = 自定义,common,workspaceType = saveOrUpdateRole.workspaceType - // 其他就从角色组取,没有就saveOrUpdateRole.workspaceType - Integer workspaceType = null; - if (COMMON_ROLE_TYPES.contains(saveOrUpdateRole.getRoleType()) || CollectionUtils.isEmpty(saveOrUpdateRole.getGroupTree())) { - workspaceType = saveOrUpdateRole.getWorkspaceType(); - } else { - workspaceType = Integer.parseInt(saveOrUpdateRole.getGroupTree().get(0).getWorkspaceTypeCode()); - } + Integer workspaceType = resolveWorkspaceType(saveOrUpdateRole); + saasRole.setWorkspaceType(workspaceType); + if (CollectionUtils.isNotEmpty(saveOrUpdateRole.getGroupTree())) { saasRole.setProductUnitType(setProductUnitType(saveOrUpdateRole.getGroupTree().get(0))); } else { @@ -509,6 +532,7 @@ public class RoleServiceImpl extends ServiceImpl systemAndCustomWorkspaceCodes.add(Long.valueOf(workspaceType)); systemAndCustomWorkspaceCodes.add(-1L); + List systemAndCustomOuIds = new ArrayList<>(); systemAndCustomOuIds.add(saveOrUpdateRole.getOwnerOuId()); systemAndCustomOuIds.add(-1L); @@ -542,14 +566,19 @@ public class RoleServiceImpl extends ServiceImpl } }); } - saasRole.setSort(saveOrUpdateRole.getSort()); assembleSort(saveOrUpdateRole, saasRole); return saasRole; } private void assembleSort(SaveOrUpdateRoleVO saveOrUpdateRole, SaasRole saasRole) { - if (saasRole.getSort() != null || saasRole.getId() != null || CollectionUtils.isEmpty(saveOrUpdateRole.getGroupTree())) { + if (saveOrUpdateRole.getSort() != null) { + saasRole.setSort(saveOrUpdateRole.getSort()); + return; + } + + // 新增时且没有传sort时,才自动维护一个最大的sort + if (saasRole.getId() != null || CollectionUtils.isEmpty(saveOrUpdateRole.getGroupTree())) { return; } @@ -834,20 +863,26 @@ public class RoleServiceImpl extends ServiceImpl @Override @Transactional(rollbackFor = Exception.class) - public void deleteRole(List roleIds, Long workSpaceId, Long ouId) { - List saasRoleUserRelations = roleUserRelationDao.lambdaQuery() - .in(CollectionUtil.isNotEmpty(roleIds), SaasRoleUserRelation::getRoleId, roleIds) - .eq(workSpaceId != null, SaasRoleUserRelation::getWorkspaceId, workSpaceId) - .eq(ouId != null, SaasRoleUserRelation::getOuId, ouId) - .eq(BaseEntity::getIsDelete, TableIsDeleteEnum.NORMAL.value) - .list(); + public void deleteRole(DeleteRoleVO deleteRoleParam) { - if (CollectionUtil.isNotEmpty(saasRoleUserRelations)) { - throw new cn.axzo.basics.common.exception.ServiceException("当前角色已被用户使用,无法删除!"); + if (BooleanUtils.isTrue(deleteRoleParam.isNeedUsedCheck())) { + List saasRoleUserRelations = roleUserRelationDao.lambdaQuery() + .in(CollectionUtil.isNotEmpty(deleteRoleParam.getRoleIds()), SaasRoleUserRelation::getRoleId, deleteRoleParam.getRoleIds()) + .eq(deleteRoleParam.getWorkSpaceId() != null, SaasRoleUserRelation::getWorkspaceId, deleteRoleParam.getWorkSpaceId()) + .eq(deleteRoleParam.getOutId() != null, SaasRoleUserRelation::getOuId, deleteRoleParam.getOutId()) + .eq(BaseEntity::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .list(); + + if (CollectionUtil.isNotEmpty(saasRoleUserRelations)) { + throw new cn.axzo.basics.common.exception.ServiceException("当前角色已被用户使用,无法删除!"); + } } - saasRoleDao.delete(roleIds); - roleUserRelationDao.deleteByRoleId(roleIds); - roleGroupRelationDao.deleteGroupRelation(roleIds); + + saasRoleDao.delete(deleteRoleParam.getRoleIds()); + // 未根据id进行更新,会存在死锁的风险,但是角色的操作频率很低,可以先不考虑 + roleUserRelationDao.deleteByRoleId(deleteRoleParam.getRoleIds()); + roleGroupRelationDao.deleteGroupRelation(deleteRoleParam.getRoleIds()); + saasPgroupRoleRelationDao.deleteByRoleId(deleteRoleParam.getRoleIds()); } @Override @@ -1162,14 +1197,7 @@ public class RoleServiceImpl extends ServiceImpl return permissionIds.stream() .map(permissionId -> { SaasPermissionRes saasPermissionRes = resourcePermissions.get(permissionId); - if (saasPermissionRes == null) { - return null; - } - return SaasPermissionWrapper.builder() - .id(saasPermissionRes.getId()) - .featureCode(saasPermissionRes.getFeatureCode()) - .roleId(e.getRoleId()) - .build(); + return SaasPermissionWrapper.from(e, saasPermissionRes); }) .filter(Objects::nonNull) .collect(Collectors.toList()); @@ -1196,6 +1224,18 @@ public class RoleServiceImpl extends ServiceImpl private String featureCode; private Long roleId; + + public static SaasPermissionWrapper from(SaasPgroupRoleRelation saasPgroupRoleRelation, + SaasPermissionRes saasPermissionRes) { + if (saasPermissionRes == null) { + return null; + } + return SaasPermissionWrapper.builder() + .id(saasPermissionRes.getId()) + .featureCode(saasPermissionRes.getFeatureCode()) + .roleId(saasPgroupRoleRelation.getRoleId()) + .build(); + } } private Map> listRoleGroups(PageSaasRoleParam param, @@ -1220,18 +1260,23 @@ public class RoleServiceImpl extends ServiceImpl .collect(Collectors.toMap(SaasRoleGroup::getId, Function.identity())); return roleGroupRelations.stream() + .filter(e -> saasRoleGroups.get(e.getSaasRoleGroupId()) != null) .collect(Collectors.groupingBy(SaasRoleGroupRelation::getRoleId, Collectors.mapping(e -> { SaasRoleGroup saasRoleGroup = saasRoleGroups.get(e.getSaasRoleGroupId()); - if (saasRoleGroup == null) { - return null; - } - SaasRoleGroupRes saasRoleGroupRes = SaasRoleGroupRes.builder().build(); - BeanUtils.copyProperties(saasRoleGroup, saasRoleGroupRes); - return saasRoleGroupRes; + return toRoleGroupRes(saasRoleGroup); }, Collectors.toList()))); } + private SaasRoleGroupRes toRoleGroupRes(SaasRoleGroup saasRoleGroup) { + if (saasRoleGroup == null) { + return null; + } + SaasRoleGroupRes saasRoleGroupRes = SaasRoleGroupRes.builder().build(); + BeanUtils.copyProperties(saasRoleGroup, saasRoleGroupRes); + return saasRoleGroupRes; + } + @Transactional(rollbackFor = Exception.class) public void saveOrUpdateFeatureRoleRelation(List req, Long operatorId) { for (FeatureRoleRelationReq item : req) {