Commit 3d8fc3a7f615d1de5b9934394a3da528789cd8b7
Merge remote-tracking branch 'origin/dev' into dev
Showing
7 changed files
with
185 additions
and
7 deletions
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/admin/user/UserController.java
| @@ -11,9 +11,12 @@ import com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils; | @@ -11,9 +11,12 @@ import com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils; | ||
| 11 | import com.zteits.urbanops.module.system.controller.admin.user.vo.user.*; | 11 | import com.zteits.urbanops.module.system.controller.admin.user.vo.user.*; |
| 12 | import com.zteits.urbanops.module.system.convert.user.UserConvert; | 12 | import com.zteits.urbanops.module.system.convert.user.UserConvert; |
| 13 | import com.zteits.urbanops.module.system.dal.dataobject.dept.DeptDO; | 13 | import com.zteits.urbanops.module.system.dal.dataobject.dept.DeptDO; |
| 14 | +import com.zteits.urbanops.module.system.dal.dataobject.permission.RoleDO; | ||
| 14 | import com.zteits.urbanops.module.system.dal.dataobject.user.AdminUserDO; | 15 | import com.zteits.urbanops.module.system.dal.dataobject.user.AdminUserDO; |
| 15 | import com.zteits.urbanops.module.system.enums.common.SexEnum; | 16 | import com.zteits.urbanops.module.system.enums.common.SexEnum; |
| 16 | import com.zteits.urbanops.module.system.service.dept.DeptService; | 17 | import com.zteits.urbanops.module.system.service.dept.DeptService; |
| 18 | +import com.zteits.urbanops.module.system.service.permission.PermissionService; | ||
| 19 | +import com.zteits.urbanops.module.system.service.permission.RoleService; | ||
| 17 | import com.zteits.urbanops.module.system.service.user.AdminUserService; | 20 | import com.zteits.urbanops.module.system.service.user.AdminUserService; |
| 18 | import io.swagger.v3.oas.annotations.Operation; | 21 | import io.swagger.v3.oas.annotations.Operation; |
| 19 | import io.swagger.v3.oas.annotations.Parameter; | 22 | import io.swagger.v3.oas.annotations.Parameter; |
| @@ -31,6 +34,8 @@ import java.io.IOException; | @@ -31,6 +34,8 @@ import java.io.IOException; | ||
| 31 | import java.util.Arrays; | 34 | import java.util.Arrays; |
| 32 | import java.util.List; | 35 | import java.util.List; |
| 33 | import java.util.Map; | 36 | import java.util.Map; |
| 37 | +import java.util.Objects; | ||
| 38 | +import java.util.stream.Collectors; | ||
| 34 | 39 | ||
| 35 | import static com.zteits.urbanops.framework.apilog.core.enums.OperateTypeEnum.EXPORT; | 40 | import static com.zteits.urbanops.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| 36 | import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; | 41 | import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; |
| @@ -47,6 +52,12 @@ public class UserController { | @@ -47,6 +52,12 @@ public class UserController { | ||
| 47 | @Resource | 52 | @Resource |
| 48 | private DeptService deptService; | 53 | private DeptService deptService; |
| 49 | 54 | ||
| 55 | + @Resource | ||
| 56 | + private PermissionService permissionService; | ||
| 57 | + | ||
| 58 | + @Resource | ||
| 59 | + private RoleService roleService; | ||
| 60 | + | ||
| 50 | @PostMapping("/create") | 61 | @PostMapping("/create") |
| 51 | @Operation(summary = "新增用户") | 62 | @Operation(summary = "新增用户") |
| 52 | @PreAuthorize("@ss.hasPermission('system:user:create')") | 63 | @PreAuthorize("@ss.hasPermission('system:user:create')") |
| @@ -101,16 +112,47 @@ public class UserController { | @@ -101,16 +112,47 @@ public class UserController { | ||
| 101 | @Operation(summary = "获得用户分页列表") | 112 | @Operation(summary = "获得用户分页列表") |
| 102 | @PreAuthorize("@ss.hasPermission('system:user:query')") | 113 | @PreAuthorize("@ss.hasPermission('system:user:query')") |
| 103 | public CommonResult<PageResult<UserRespVO>> getUserPage(@Valid UserPageReqVO pageReqVO) { | 114 | public CommonResult<PageResult<UserRespVO>> getUserPage(@Valid UserPageReqVO pageReqVO) { |
| 104 | - // 获得用户分页列表 | 115 | + // 1. 获得用户分页列表(AdminUserDO 是数据库实体) |
| 105 | PageResult<AdminUserDO> pageResult = userService.getUserPage(pageReqVO); | 116 | PageResult<AdminUserDO> pageResult = userService.getUserPage(pageReqVO); |
| 106 | if (CollUtil.isEmpty(pageResult.getList())) { | 117 | if (CollUtil.isEmpty(pageResult.getList())) { |
| 107 | - return success(new PageResult<>(pageResult.getTotal())); | 118 | + // 无数据时,返回空分页结果(保持返回结构一致) |
| 119 | + return CommonResult.success(new PageResult<>(pageResult.getTotal())); | ||
| 108 | } | 120 | } |
| 109 | - // 拼接数据 | 121 | + |
| 122 | + // 2. 提取当前页所有用户ID(用于批量查询,避免N+1查询问题) | ||
| 123 | + List<Long> userIdList = pageResult.getList().stream() | ||
| 124 | + .map(AdminUserDO::getId) | ||
| 125 | + .collect(Collectors.toList()); | ||
| 126 | + | ||
| 127 | + // 3. 批量拼接关联数据:部门信息(原有逻辑,保持不变) | ||
| 110 | Map<Long, DeptDO> deptMap = deptService.getDeptMap( | 128 | Map<Long, DeptDO> deptMap = deptService.getDeptMap( |
| 111 | - convertList(pageResult.getList(), AdminUserDO::getDeptId)); | ||
| 112 | - return success(new PageResult<>(UserConvert.INSTANCE.convertList(pageResult.getList(), deptMap), | ||
| 113 | - pageResult.getTotal())); | 129 | + pageResult.getList().stream().map(AdminUserDO::getDeptId).collect(Collectors.toList()) |
| 130 | + ); | ||
| 131 | + | ||
| 132 | + // 4. 批量拼接关联数据:角色信息(核心修正与完善) | ||
| 133 | + // 4.1 批量获取「用户ID-角色ID列表」的映射(从权限服务获取,批量查询提升效率) | ||
| 134 | + Map<Long, List<Long>> userId2RoleIdListMap = permissionService.getUserRoleIdListByUserIds(userIdList); | ||
| 135 | + // 4.2 提取所有涉及的角色ID,去重后批量查询角色信息(从缓存获取,符合芋道缓存规范) | ||
| 136 | + List<Long> allRoleIdList = userId2RoleIdListMap.values().stream() | ||
| 137 | + .flatMap(List::stream) | ||
| 138 | + .distinct() | ||
| 139 | + .collect(Collectors.toList()); | ||
| 140 | + Map<Long, RoleDO> roleMap = roleService.getRoleMapFromCache(allRoleIdList); // 批量查询角色缓存,返回「角色ID-角色DO」映射 | ||
| 141 | + // 4.3 封装「用户ID-角色列表」的映射(供转换VO使用) | ||
| 142 | + Map<Long, List<RoleDO>> userId2RoleListMap = userId2RoleIdListMap.entrySet().stream() | ||
| 143 | + .collect(Collectors.toMap( | ||
| 144 | + Map.Entry::getKey, | ||
| 145 | + entry -> entry.getValue().stream() | ||
| 146 | + .map(roleMap::get) // 从角色映射中获取对应RoleDO(可能返回null) | ||
| 147 | + .filter(Objects::nonNull) // 过滤null的RoleDO对象,解决报错核心 | ||
| 148 | + .collect(Collectors.toList()) | ||
| 149 | + )); | ||
| 150 | + | ||
| 151 | + // 5. 转换VO并拼接关联数据(修改转换器,支持接收角色映射) | ||
| 152 | + List<UserRespVO> userRespVOList = UserConvert.INSTANCE.convertList(pageResult.getList(), deptMap, userId2RoleListMap); | ||
| 153 | + | ||
| 154 | + // 6. 封装并返回结果 | ||
| 155 | + return CommonResult.success(new PageResult<>(userRespVOList, pageResult.getTotal())); | ||
| 114 | } | 156 | } |
| 115 | 157 | ||
| 116 | @PostMapping("/listForPage") | 158 | @PostMapping("/listForPage") |
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/admin/user/vo/user/UserRespVO.java
| @@ -38,6 +38,9 @@ public class UserRespVO{ | @@ -38,6 +38,9 @@ public class UserRespVO{ | ||
| 38 | @ExcelProperty("部门名称") | 38 | @ExcelProperty("部门名称") |
| 39 | private String deptName; | 39 | private String deptName; |
| 40 | 40 | ||
| 41 | + @Schema(description = "角色名称") | ||
| 42 | + private String roleNames; | ||
| 43 | + | ||
| 41 | @Schema(description = "岗位编号数组", example = "1") | 44 | @Schema(description = "岗位编号数组", example = "1") |
| 42 | private Set<Long> postIds; | 45 | private Set<Long> postIds; |
| 43 | 46 |
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/convert/user/UserConvert.java
| 1 | package com.zteits.urbanops.module.system.convert.user; | 1 | package com.zteits.urbanops.module.system.convert.user; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import com.zteits.urbanops.framework.common.util.collection.CollectionUtils; | 4 | import com.zteits.urbanops.framework.common.util.collection.CollectionUtils; |
| 4 | import com.zteits.urbanops.framework.common.util.collection.MapUtils; | 5 | import com.zteits.urbanops.framework.common.util.collection.MapUtils; |
| 5 | import com.zteits.urbanops.framework.common.util.object.BeanUtils; | 6 | import com.zteits.urbanops.framework.common.util.object.BeanUtils; |
| @@ -16,14 +17,79 @@ import com.zteits.urbanops.module.system.dal.dataobject.user.AdminUserDO; | @@ -16,14 +17,79 @@ import com.zteits.urbanops.module.system.dal.dataobject.user.AdminUserDO; | ||
| 16 | import org.mapstruct.Mapper; | 17 | import org.mapstruct.Mapper; |
| 17 | import org.mapstruct.factory.Mappers; | 18 | import org.mapstruct.factory.Mappers; |
| 18 | 19 | ||
| 20 | +import java.util.ArrayList; | ||
| 19 | import java.util.List; | 21 | import java.util.List; |
| 20 | import java.util.Map; | 22 | import java.util.Map; |
| 23 | +import java.util.stream.Collectors; | ||
| 21 | 24 | ||
| 22 | -@Mapper | 25 | +@Mapper(componentModel = "spring") |
| 23 | public interface UserConvert { | 26 | public interface UserConvert { |
| 24 | 27 | ||
| 25 | UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); | 28 | UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); |
| 26 | 29 | ||
| 30 | + /** | ||
| 31 | + * 转换单个用户VO,拼接部门和角色信息 | ||
| 32 | + */ | ||
| 33 | + default UserRespVO convert(AdminUserDO adminUserDO, Map<Long, DeptDO> deptMap, Map<Long, List<RoleDO>> userId2RoleListMap) { | ||
| 34 | + // 1. 判空处理,避免空指针 | ||
| 35 | + if (adminUserDO == null) { | ||
| 36 | + return null; | ||
| 37 | + } | ||
| 38 | + // 2. 新建VO对象,手动拷贝所有字段(对应原MapStruct自动映射的同名字段) | ||
| 39 | + UserRespVO userRespVO = BeanUtils.toBean(adminUserDO,UserRespVO.class); | ||
| 40 | + // 3. 手动调用辅助方法,设置拼接后的部门名称和角色名称 | ||
| 41 | + userRespVO.setDeptName(getDeptName(adminUserDO.getDeptId(), deptMap)); | ||
| 42 | + userRespVO.setRoleNames(getRoleNames(adminUserDO.getId(), userId2RoleListMap)); | ||
| 43 | + | ||
| 44 | + return userRespVO; | ||
| 45 | + } | ||
| 46 | + /** | ||
| 47 | + * 批量转换用户VO | ||
| 48 | + */ | ||
| 49 | + default List<UserRespVO> convertList(List<AdminUserDO> adminUserDOList, Map<Long, DeptDO> deptMap, Map<Long, List<RoleDO>> userId2RoleListMap) { | ||
| 50 | + // 1. 判空处理 | ||
| 51 | + if (CollUtil.isEmpty(adminUserDOList)) { | ||
| 52 | + return new ArrayList<>(); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + // 2. 遍历单个转换,收集结果 | ||
| 56 | + List<UserRespVO> userRespVOList = new ArrayList<>(); | ||
| 57 | + for (AdminUserDO adminUserDO : adminUserDOList) { | ||
| 58 | + UserRespVO userRespVO = convert(adminUserDO, deptMap, userId2RoleListMap); | ||
| 59 | + if (userRespVO != null) { | ||
| 60 | + userRespVOList.add(userRespVO); | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + return userRespVOList; | ||
| 65 | + } | ||
| 66 | + /** | ||
| 67 | + * 从部门映射中获取部门名称 | ||
| 68 | + */ | ||
| 69 | + default String getDeptName(Long deptId, Map<Long, DeptDO> deptMap) { | ||
| 70 | + if (deptId == null || deptMap == null) { | ||
| 71 | + return null; | ||
| 72 | + } | ||
| 73 | + DeptDO deptDO = deptMap.get(deptId); | ||
| 74 | + return deptDO != null ? deptDO.getName() : null; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * 从角色映射中获取角色名称(拼接为逗号分隔字符串) | ||
| 79 | + */ | ||
| 80 | + default String getRoleNames(Long userId, Map<Long, List<RoleDO>> userId2RoleListMap) { | ||
| 81 | + if (userId == null || userId2RoleListMap == null) { | ||
| 82 | + return null; | ||
| 83 | + } | ||
| 84 | + List<RoleDO> roleDOList = userId2RoleListMap.get(userId); | ||
| 85 | + if (CollUtil.isEmpty(roleDOList)) { | ||
| 86 | + return null; | ||
| 87 | + } | ||
| 88 | + // 拼接角色名称为逗号分隔的字符串(如:"管理员,普通用户") | ||
| 89 | + return roleDOList.stream() | ||
| 90 | + .map(RoleDO::getName) | ||
| 91 | + .collect(Collectors.joining(",")); | ||
| 92 | + } | ||
| 27 | default List<UserRespVO> convertList(List<AdminUserDO> list, Map<Long, DeptDO> deptMap) { | 93 | default List<UserRespVO> convertList(List<AdminUserDO> list, Map<Long, DeptDO> deptMap) { |
| 28 | return CollectionUtils.convertList(list, user -> convert(user, deptMap.get(user.getDeptId()))); | 94 | return CollectionUtils.convertList(list, user -> convert(user, deptMap.get(user.getDeptId()))); |
| 29 | } | 95 | } |
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/service/permission/PermissionService.java
| @@ -3,6 +3,8 @@ package com.zteits.urbanops.module.system.service.permission; | @@ -3,6 +3,8 @@ package com.zteits.urbanops.module.system.service.permission; | ||
| 3 | import com.zteits.urbanops.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO; | 3 | import com.zteits.urbanops.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO; |
| 4 | 4 | ||
| 5 | import java.util.Collection; | 5 | import java.util.Collection; |
| 6 | +import java.util.List; | ||
| 7 | +import java.util.Map; | ||
| 6 | import java.util.Set; | 8 | import java.util.Set; |
| 7 | 9 | ||
| 8 | import static java.util.Collections.singleton; | 10 | import static java.util.Collections.singleton; |
| @@ -26,6 +28,13 @@ public interface PermissionService { | @@ -26,6 +28,13 @@ public interface PermissionService { | ||
| 26 | boolean hasAnyPermissions(Long userId, String... permissions); | 28 | boolean hasAnyPermissions(Long userId, String... permissions); |
| 27 | 29 | ||
| 28 | /** | 30 | /** |
| 31 | + * 获取多个用户的角色信息 | ||
| 32 | + * @param userIdList | ||
| 33 | + * @return | ||
| 34 | + */ | ||
| 35 | + public Map<Long, List<Long>> getUserRoleIdListByUserIds(List<Long> userIdList); | ||
| 36 | + | ||
| 37 | + /** | ||
| 29 | * 判断是否有角色,任一一个即可 | 38 | * 判断是否有角色,任一一个即可 |
| 30 | * | 39 | * |
| 31 | * @param roles 角色数组 | 40 | * @param roles 角色数组 |
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/service/permission/PermissionServiceImpl.java
| @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; | @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.collection.CollectionUtil; | 4 | import cn.hutool.core.collection.CollectionUtil; |
| 5 | import cn.hutool.core.util.ArrayUtil; | 5 | import cn.hutool.core.util.ArrayUtil; |
| 6 | import cn.hutool.extra.spring.SpringUtil; | 6 | import cn.hutool.extra.spring.SpringUtil; |
| 7 | +import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||
| 7 | import com.zteits.urbanops.framework.common.enums.CommonStatusEnum; | 8 | import com.zteits.urbanops.framework.common.enums.CommonStatusEnum; |
| 8 | import com.zteits.urbanops.framework.common.util.collection.CollectionUtils; | 9 | import com.zteits.urbanops.framework.common.util.collection.CollectionUtils; |
| 9 | import com.zteits.urbanops.framework.datapermission.core.annotation.DataPermission; | 10 | import com.zteits.urbanops.framework.datapermission.core.annotation.DataPermission; |
| @@ -32,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional; | @@ -32,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional; | ||
| 32 | import jakarta.annotation.Resource; | 33 | import jakarta.annotation.Resource; |
| 33 | import java.util.*; | 34 | import java.util.*; |
| 34 | import java.util.function.Supplier; | 35 | import java.util.function.Supplier; |
| 36 | +import java.util.stream.Collectors; | ||
| 35 | 37 | ||
| 36 | import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertSet; | 38 | import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertSet; |
| 37 | import static com.zteits.urbanops.framework.common.util.json.JsonUtils.toJsonString; | 39 | import static com.zteits.urbanops.framework.common.util.json.JsonUtils.toJsonString; |
| @@ -60,6 +62,22 @@ public class PermissionServiceImpl implements PermissionService { | @@ -60,6 +62,22 @@ public class PermissionServiceImpl implements PermissionService { | ||
| 60 | private AdminUserService userService; | 62 | private AdminUserService userService; |
| 61 | 63 | ||
| 62 | @Override | 64 | @Override |
| 65 | + public Map<Long, List<Long>> getUserRoleIdListByUserIds(List<Long> userIdList) { | ||
| 66 | + if (CollUtil.isEmpty(userIdList)) { | ||
| 67 | + return Collections.emptyMap(); | ||
| 68 | + } | ||
| 69 | + // 查询用户-角色关联数据 | ||
| 70 | + List<UserRoleDO> userRoleDOList = userRoleMapper.selectList(Wrappers.<UserRoleDO>lambdaQuery() | ||
| 71 | + .in(UserRoleDO::getUserId, userIdList)); | ||
| 72 | + // 分组封装为「用户ID-角色ID列表」 | ||
| 73 | + return userRoleDOList.stream() | ||
| 74 | + .collect(Collectors.groupingBy( | ||
| 75 | + UserRoleDO::getUserId, | ||
| 76 | + Collectors.mapping(UserRoleDO::getRoleId, Collectors.toList()) | ||
| 77 | + )); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + @Override | ||
| 63 | public boolean hasAnyPermissions(Long userId, String... permissions) { | 81 | public boolean hasAnyPermissions(Long userId, String... permissions) { |
| 64 | // 如果为空,说明已经有权限 | 82 | // 如果为空,说明已经有权限 |
| 65 | if (ArrayUtil.isEmpty(permissions)) { | 83 | if (ArrayUtil.isEmpty(permissions)) { |
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/service/permission/RoleService.java
| @@ -9,6 +9,7 @@ import jakarta.validation.Valid; | @@ -9,6 +9,7 @@ import jakarta.validation.Valid; | ||
| 9 | 9 | ||
| 10 | import java.util.Collection; | 10 | import java.util.Collection; |
| 11 | import java.util.List; | 11 | import java.util.List; |
| 12 | +import java.util.Map; | ||
| 12 | import java.util.Set; | 13 | import java.util.Set; |
| 13 | 14 | ||
| 14 | /** | 15 | /** |
| @@ -19,6 +20,13 @@ import java.util.Set; | @@ -19,6 +20,13 @@ import java.util.Set; | ||
| 19 | public interface RoleService { | 20 | public interface RoleService { |
| 20 | 21 | ||
| 21 | /** | 22 | /** |
| 23 | + * 从缓存中批量获取角色信息,返回「角色ID-角色DO」的映射 | ||
| 24 | + * @param roleIdList 角色ID列表 | ||
| 25 | + * @return Map<Long, RoleDO> 角色ID为key,RoleDO为value | ||
| 26 | + */ | ||
| 27 | + Map<Long, RoleDO> getRoleMapFromCache(List<Long> roleIdList); | ||
| 28 | + | ||
| 29 | + /** | ||
| 22 | * 创建角色 | 30 | * 创建角色 |
| 23 | * | 31 | * |
| 24 | * @param createReqVO 创建角色信息 | 32 | * @param createReqVO 创建角色信息 |
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/service/permission/RoleServiceImpl.java
| @@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollectionUtil; | @@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollectionUtil; | ||
| 5 | import cn.hutool.core.util.ObjUtil; | 5 | import cn.hutool.core.util.ObjUtil; |
| 6 | import cn.hutool.core.util.ObjectUtil; | 6 | import cn.hutool.core.util.ObjectUtil; |
| 7 | import cn.hutool.extra.spring.SpringUtil; | 7 | import cn.hutool.extra.spring.SpringUtil; |
| 8 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 8 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 9 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| 9 | import com.zteits.urbanops.framework.common.enums.CommonStatusEnum; | 10 | import com.zteits.urbanops.framework.common.enums.CommonStatusEnum; |
| 10 | import com.zteits.urbanops.framework.common.pojo.PageResult; | 11 | import com.zteits.urbanops.framework.common.pojo.PageResult; |
| @@ -34,6 +35,7 @@ import org.springframework.transaction.annotation.Transactional; | @@ -34,6 +35,7 @@ import org.springframework.transaction.annotation.Transactional; | ||
| 34 | import org.springframework.util.StringUtils; | 35 | import org.springframework.util.StringUtils; |
| 35 | 36 | ||
| 36 | import java.util.*; | 37 | import java.util.*; |
| 38 | +import java.util.stream.Collectors; | ||
| 37 | 39 | ||
| 38 | import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; | 40 | import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 39 | import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertMap; | 41 | import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertMap; |
| @@ -58,6 +60,36 @@ public class RoleServiceImpl implements RoleService { | @@ -58,6 +60,36 @@ public class RoleServiceImpl implements RoleService { | ||
| 58 | @Resource | 60 | @Resource |
| 59 | private UserRoleMapper userRoleMapper; | 61 | private UserRoleMapper userRoleMapper; |
| 60 | 62 | ||
| 63 | + /** | ||
| 64 | + * 从缓存中批量获取角色信息,缓存未命中则查询数据库并缓存结果 | ||
| 65 | + */ | ||
| 66 | + @Override | ||
| 67 | + @Cacheable(value = "role", key = "#roleIdList.toString()", unless = "#result.isEmpty()") | ||
| 68 | + // 缓存注解说明: | ||
| 69 | + // value:缓存名称,区分不同模块缓存 | ||
| 70 | + // key:缓存键,用角色ID列表拼接作为唯一键 | ||
| 71 | + // unless:结果为空时不缓存,避免无效缓存 | ||
| 72 | + public Map<Long, RoleDO> getRoleMapFromCache(List<Long> roleIdList) { | ||
| 73 | + // 1. 空值处理,避免无效查询 | ||
| 74 | + if (CollUtil.isEmpty(roleIdList)) { | ||
| 75 | + return Map.of(); // 返回空不可变Map,避免空指针 | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + // 2. 批量查询数据库(缓存未命中时执行) | ||
| 79 | + List<RoleDO> roleDOList = roleMapper.selectList( | ||
| 80 | + new LambdaQueryWrapper<RoleDO>() | ||
| 81 | + .in(RoleDO::getId, roleIdList) // 批量查询,仅一次数据库访问 | ||
| 82 | + ); | ||
| 83 | + | ||
| 84 | + // 3. 转换为「角色ID-角色DO」的Map,方便后续取值 | ||
| 85 | + return roleDOList.stream() | ||
| 86 | + .collect(Collectors.toMap( | ||
| 87 | + RoleDO::getId, // 以角色ID作为key | ||
| 88 | + roleDO -> roleDO, // 以角色DO作为value | ||
| 89 | + (existing, replacement) -> existing // 解决重复ID冲突(取已有值,实际不会出现) | ||
| 90 | + )); | ||
| 91 | + } | ||
| 92 | + | ||
| 61 | @Override | 93 | @Override |
| 62 | @Transactional(rollbackFor = Exception.class) | 94 | @Transactional(rollbackFor = Exception.class) |
| 63 | @LogRecord(type = SYSTEM_ROLE_TYPE, subType = SYSTEM_ROLE_CREATE_SUB_TYPE, bizNo = "{{#role.id}}", | 95 | @LogRecord(type = SYSTEM_ROLE_TYPE, subType = SYSTEM_ROLE_CREATE_SUB_TYPE, bizNo = "{{#role.id}}", |