refactor: data scope cache

This commit is contained in:
AgAngle
2025-04-07 17:28:15 +08:00
committed by Craftsman
parent 942f728bdc
commit e42acffffb
6 changed files with 66 additions and 22 deletions

View File

@@ -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<String, List<Role>> dataScopeRoleMap = getDataScopeRoleMap(userId);
// 从 sessionUser 中获取角色数据权限
Map<String, List<RoleDataScopeDTO>> 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<Role> userDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_AND_CHILD.name());
List<Role> customDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_CUSTOM.name());
List<RoleDataScopeDTO> userDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_AND_CHILD.name());
List<RoleDataScopeDTO> 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<String, List<Role>> dataScopeRoleMap) {
private DeptDataPermissionDTO getDeptDataPermissionForDept(String userId, String orgId, Map<String, List<RoleDataScopeDTO>> dataScopeRoleMap) {
DeptDataPermissionDTO deptDataPermission = new DeptDataPermissionDTO();
List<Role> userDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_AND_CHILD.name());
List<Role> customDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_CUSTOM.name());
List<RoleDataScopeDTO> userDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_AND_CHILD.name());
List<RoleDataScopeDTO> customDeptRoles = dataScopeRoleMap.get(RoleDataScope.DEPT_CUSTOM.name());
// 查询部门树
List<BaseTreeNode> tree = departmentService.getTree(orgId);
@@ -116,7 +128,7 @@ public class DataScopeService {
if (CollectionUtils.isNotEmpty(customDeptRoles)) {
// 查看指定部门及其子部门数据
List<String> customDeptRolesIds = customDeptRoles.stream()
.map(Role::getId)
.map(RoleDataScopeDTO::getId)
.toList();
List<String> parentDeptIds = roleService.getDeptIdsByRoleIds(customDeptRolesIds);
List<String> 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<String, List<Role>> getDataScopeRoleMap(String userId) {
private Map<String, List<RoleDataScopeDTO>> getDataScopeRoleMap(String userId) {
List<String> 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) {

View File

@@ -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<BaseTreeNode>
*/
@Cacheable(value = "dept_tree_cache", key = "#orgId")
public List<BaseTreeNode> getTree(String orgId) {
List<BaseTreeNode> 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,

View File

@@ -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<OptionDTO> getRoleOptions(List<String> roleIds) {
public List<RoleDataScopeDTO> getRoleOptions(List<String> 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();
}
}

View File

@@ -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<String> roleIds = roleService.getRoleIdsByUserId(userDTO.getId());
List<OptionDTO> roleOptions = roleService.getRoleOptions(roleIds);
List<RoleDataScopeDTO> roleOptions = roleService.getRoleOptions(roleIds);
// 设置角色信息,供前端展示
userDTO.setRoles(roleOptions);
// 设置权限

View File

@@ -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;
}

View File

@@ -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<String> permissionIds;
@Schema(description = "权限ID")
private List<OptionDTO> roles;
private List<RoleDataScopeDTO> roles;
@Schema(description = "所在的组织ID")
private Set<String> organizationIds;