From e42acffffbbd6775de33923de0bd145f435866ea Mon Sep 17 00:00:00 2001 From: AgAngle <1323481023@qq.com> Date: Mon, 7 Apr 2025 17:28:15 +0800 Subject: [PATCH] refactor: data scope cache --- .../common/service/DataScopeService.java | 36 ++++++++++++------- .../crm/system/service/DepartmentService.java | 6 ++++ .../crm/system/service/RoleService.java | 9 ++--- .../crm/system/service/UserLoginService.java | 4 +-- .../cordys/common/dto/RoleDataScopeDTO.java | 29 +++++++++++++++ .../main/java/io/cordys/security/UserDTO.java | 4 +-- 6 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 backend/framework/src/main/java/io/cordys/common/dto/RoleDataScopeDTO.java diff --git a/backend/crm/src/main/java/io/cordys/common/service/DataScopeService.java b/backend/crm/src/main/java/io/cordys/common/service/DataScopeService.java index 5e22d2a2d..24677bce8 100644 --- a/backend/crm/src/main/java/io/cordys/common/service/DataScopeService.java +++ b/backend/crm/src/main/java/io/cordys/common/service/DataScopeService.java @@ -5,15 +5,19 @@ import io.cordys.common.constants.InternalUser; import io.cordys.common.constants.RoleDataScope; import io.cordys.common.dto.BaseTreeNode; import io.cordys.common.dto.DeptDataPermissionDTO; +import io.cordys.common.dto.RoleDataScopeDTO; import io.cordys.common.dto.UserDeptDTO; import io.cordys.common.exception.GenericException; import io.cordys.common.response.result.CrmHttpResultCode; +import io.cordys.common.util.BeanUtils; import io.cordys.crm.system.domain.OrganizationUser; -import io.cordys.crm.system.domain.Role; + import io.cordys.crm.system.domain.UserRole; import io.cordys.crm.system.service.DepartmentService; import io.cordys.crm.system.service.RoleService; import io.cordys.mybatis.BaseMapper; +import io.cordys.security.SessionUser; +import io.cordys.security.SessionUtils; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -67,7 +71,6 @@ public class DataScopeService { * @param orgId * @return */ -// @Cacheable(value = "dept_data_permission_cache", key = "#userId + '_' + #orgId") todo 缓存 public DeptDataPermissionDTO getDeptDataPermission(String userId, String orgId) { DeptDataPermissionDTO deptDataPermission = new DeptDataPermissionDTO(); @@ -77,7 +80,16 @@ public class DataScopeService { return deptDataPermission; } - Map> dataScopeRoleMap = getDataScopeRoleMap(userId); + // 从 sessionUser 中获取角色数据权限 + Map> dataScopeRoleMap; + SessionUser user = SessionUtils.getUser(); + if (user != null) { + dataScopeRoleMap = user.getRoles() + .stream() + .collect(Collectors.groupingBy(RoleDataScopeDTO::getDataScope, Collectors.toList())); + } else { + dataScopeRoleMap = getDataScopeRoleMap(userId); + } if (CollectionUtils.isNotEmpty(dataScopeRoleMap.get(RoleDataScope.ALL.name()))) { // 可以查看所有数据 @@ -85,8 +97,8 @@ public class DataScopeService { return deptDataPermission; } - List userDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_AND_CHILD.name()); - List customDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_CUSTOM.name()); + List userDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_AND_CHILD.name()); + List customDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_CUSTOM.name()); if (CollectionUtils.isEmpty(userDeptRoles) && CollectionUtils.isEmpty(customDeptRoles)) { @@ -98,10 +110,10 @@ public class DataScopeService { return getDeptDataPermissionForDept(userId, orgId, dataScopeRoleMap); } - private DeptDataPermissionDTO getDeptDataPermissionForDept(String userId, String orgId, Map> dataScopeRoleMap) { + private DeptDataPermissionDTO getDeptDataPermissionForDept(String userId, String orgId, Map> dataScopeRoleMap) { DeptDataPermissionDTO deptDataPermission = new DeptDataPermissionDTO(); - List userDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_AND_CHILD.name()); - List customDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_CUSTOM.name()); + List userDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_AND_CHILD.name()); + List customDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_CUSTOM.name()); // 查询部门树 List tree = departmentService.getTree(orgId); @@ -116,7 +128,7 @@ public class DataScopeService { if (CollectionUtils.isNotEmpty(customDeptRoles)) { // 查看指定部门及其子部门数据 List customDeptRolesIds = customDeptRoles.stream() - .map(Role::getId) + .map(RoleDataScopeDTO::getId) .toList(); List parentDeptIds = roleService.getDeptIdsByRoleIds(customDeptRolesIds); List deptIds = getDeptIdsWithChild(tree, new HashSet<>(parentDeptIds)); @@ -126,7 +138,6 @@ public class DataScopeService { } /** - * todo 缓存 * @param userId * @param orgId * @return @@ -135,7 +146,7 @@ public class DataScopeService { return getDeptDataPermissionForDept(userId, orgId, getDataScopeRoleMap(userId)); } - private Map> getDataScopeRoleMap(String userId) { + private Map> getDataScopeRoleMap(String userId) { List roleIds = roleService.getUserRolesByUserId(userId) .stream() .map(UserRole::getRoleId) @@ -143,7 +154,8 @@ public class DataScopeService { return roleService.getByIds(roleIds) .stream() - .collect(Collectors.groupingBy(Role::getDataScope, Collectors.toList())); + .map(role -> BeanUtils.copyBean(new RoleDataScopeDTO(), role)) + .collect(Collectors.groupingBy(RoleDataScopeDTO::getDataScope, Collectors.toList())); } private OrganizationUser getOrganizationUser(String userId, String orgId) { diff --git a/backend/crm/src/main/java/io/cordys/crm/system/service/DepartmentService.java b/backend/crm/src/main/java/io/cordys/crm/system/service/DepartmentService.java index 08d394949..78f1db637 100644 --- a/backend/crm/src/main/java/io/cordys/crm/system/service/DepartmentService.java +++ b/backend/crm/src/main/java/io/cordys/crm/system/service/DepartmentService.java @@ -32,6 +32,8 @@ import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionUtils; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -59,6 +61,7 @@ public class DepartmentService extends MoveNodeService { * * @return List */ + @Cacheable(value = "dept_tree_cache", key = "#orgId") public List getTree(String orgId) { List departmentList = extDepartmentMapper.selectTreeNode(orgId); return BaseTreeNode.buildTree(departmentList); @@ -71,6 +74,7 @@ public class DepartmentService extends MoveNodeService { * @param orgId */ @OperationLog(module = LogModule.SYSTEM_DEPARTMENT, type = LogType.ADD) + @CacheEvict(value = "dept_tree_cache", key = "#orgId", beforeInvocation = true) public Department addDepartment(DepartmentAddRequest request, String orgId, String userId) { //同一层级部门名称唯一 checkDepartmentName(request.getName(), request.getParentId(), orgId); @@ -216,6 +220,7 @@ public class DepartmentService extends MoveNodeService { * @param id */ @OperationLog(module = LogModule.SYSTEM_DEPARTMENT, type = LogType.DELETE, resourceId = "{#id}") + @CacheEvict(value = "dept_tree_cache", key = "#orgId", beforeInvocation = true) public void delete(String id, String orgId) { Department department = checkDepartment(id); if (deleteCheck(id, orgId)) { @@ -382,6 +387,7 @@ public class DepartmentService extends MoveNodeService { * @param operatorId * @param orgId */ + @CacheEvict(value = "dept_tree_cache", key = "#orgId", beforeInvocation = true) public void sort(NodeMoveRequest request, String operatorId, String orgId) { NodeSortDTO nodeSortDTO = super.getNodeSortDTO(request, extDepartmentMapper::selectBaseTreeById, diff --git a/backend/crm/src/main/java/io/cordys/crm/system/service/RoleService.java b/backend/crm/src/main/java/io/cordys/crm/system/service/RoleService.java index 7d1df23ed..fa897f716 100644 --- a/backend/crm/src/main/java/io/cordys/crm/system/service/RoleService.java +++ b/backend/crm/src/main/java/io/cordys/crm/system/service/RoleService.java @@ -7,7 +7,7 @@ import io.cordys.aspectj.context.OperationLogContext; import io.cordys.aspectj.dto.LogContextInfo; import io.cordys.common.constants.InternalRole; import io.cordys.common.constants.RoleDataScope; -import io.cordys.common.dto.OptionDTO; +import io.cordys.common.dto.RoleDataScopeDTO; import io.cordys.common.exception.GenericException; import io.cordys.common.permission.Permission; import io.cordys.common.permission.PermissionDefinitionItem; @@ -482,7 +482,7 @@ public class RoleService { return roleMapper.selectByIds(ids.toArray(new String[0])); } - public List getRoleOptions(List roleIds) { + public List getRoleOptions(List roleIds) { if (CollectionUtils.isEmpty(roleIds)) { return List.of(); } @@ -490,10 +490,7 @@ public class RoleService { return roles.stream() .map(role -> { role = translateInternalRole(role); - OptionDTO option = new OptionDTO(); - option.setId(role.getId()); - option.setName(role.getName()); - return option; + return BeanUtils.copyBean(new RoleDataScopeDTO(), role); }).toList(); } } \ No newline at end of file diff --git a/backend/crm/src/main/java/io/cordys/crm/system/service/UserLoginService.java b/backend/crm/src/main/java/io/cordys/crm/system/service/UserLoginService.java index 147221373..81af4338d 100644 --- a/backend/crm/src/main/java/io/cordys/crm/system/service/UserLoginService.java +++ b/backend/crm/src/main/java/io/cordys/crm/system/service/UserLoginService.java @@ -1,6 +1,6 @@ package io.cordys.crm.system.service; -import io.cordys.common.dto.OptionDTO; +import io.cordys.common.dto.RoleDataScopeDTO; import io.cordys.common.exception.GenericException; import io.cordys.common.request.LoginRequest; import io.cordys.common.uid.IDGenerator; @@ -63,7 +63,7 @@ public class UserLoginService { } List roleIds = roleService.getRoleIdsByUserId(userDTO.getId()); - List roleOptions = roleService.getRoleOptions(roleIds); + List roleOptions = roleService.getRoleOptions(roleIds); // 设置角色信息,供前端展示 userDTO.setRoles(roleOptions); // 设置权限 diff --git a/backend/framework/src/main/java/io/cordys/common/dto/RoleDataScopeDTO.java b/backend/framework/src/main/java/io/cordys/common/dto/RoleDataScopeDTO.java new file mode 100644 index 000000000..f52e69e07 --- /dev/null +++ b/backend/framework/src/main/java/io/cordys/common/dto/RoleDataScopeDTO.java @@ -0,0 +1,29 @@ +package io.cordys.common.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author jianxing + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RoleDataScopeDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "选项ID") + private String id; + @Schema(description = "选项名称") + private String name; + @Schema(description = "数据权限") + private String dataScope; + @Schema(description = "组织ID") + private String organizationId; +} diff --git a/backend/framework/src/main/java/io/cordys/security/UserDTO.java b/backend/framework/src/main/java/io/cordys/security/UserDTO.java index 9ae684ab2..b251a2f22 100644 --- a/backend/framework/src/main/java/io/cordys/security/UserDTO.java +++ b/backend/framework/src/main/java/io/cordys/security/UserDTO.java @@ -1,6 +1,6 @@ package io.cordys.security; -import io.cordys.common.dto.OptionDTO; +import io.cordys.common.dto.RoleDataScopeDTO; import io.cordys.common.groups.Created; import io.cordys.common.groups.Updated; import io.swagger.v3.oas.annotations.media.Schema; @@ -77,7 +77,7 @@ public class UserDTO implements java.io.Serializable { private Set permissionIds; @Schema(description = "权限ID") - private List roles; + private List roles; @Schema(description = "所在的组织ID") private Set organizationIds;