添加权限接口.

This commit is contained in:
lijiahang
2023-07-19 15:03:49 +08:00
parent 8a5888e81e
commit 6643597c16
17 changed files with 302 additions and 121 deletions

View File

@@ -31,4 +31,6 @@ public class Const implements com.orion.lang.constant.Const {
public static final Long ROOT_MENU_ID = 0L;
public static final Integer DEFAULT_SORT = 0;
}

View File

@@ -29,9 +29,9 @@ public interface ErrorMessage {
String ROLE_ABSENT = "角色不存在";
String PARENT_MENU_ABSENT = "父菜单不存在";
String INVALID_PARENT_MENU = "所选父菜单不合法";
String PARENT_MENU_MUST_PARENT = "上级菜单必须为父菜单";
String PARENT_MENU_ABSENT = "父菜单不存在";
String DATA_ABSENT = "数据不存在";

View File

@@ -1,5 +1,15 @@
### 初始化缓存
### 初始化角色权限缓存
GET {{baseUrl}}/infra/permission/init-cache
Authorization: {{token}}
### 获取用户菜单
GET {{baseUrl}}/infra/permission/menu
Authorization: {{token}}
### 获取用户权限
GET {{baseUrl}}/infra/permission/permission
Authorization: {{token}}

View File

@@ -1,7 +1,10 @@
package com.orion.ops.module.infra.controller;
import com.orion.lang.define.wrapper.HttpWrapper;
import com.orion.ops.framework.common.annotation.IgnoreLog;
import com.orion.ops.framework.common.annotation.RestWrapper;
import com.orion.ops.module.infra.entity.vo.SystemMenuVO;
import com.orion.ops.module.infra.entity.vo.UserPermissionVO;
import com.orion.ops.module.infra.service.PermissionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -13,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* 权限服务
@@ -34,11 +38,25 @@ public class PermissionController {
private PermissionService permissionService;
@GetMapping("/init-cache")
@Operation(summary = "初始化缓存")
@PreAuthorize("@ss.hasRole('admin')")
@Operation(summary = "初始化角色权限缓存")
@PreAuthorize("@ss.hasPermission('infra:system:init-permission-cache')")
public HttpWrapper<?> initCache() {
permissionService.initPermissionCache();
return HttpWrapper.ok();
}
@IgnoreLog
@GetMapping("/menu")
@Operation(summary = "获取用户菜单")
public List<SystemMenuVO> getUserMenuList() {
return permissionService.getUserMenuList();
}
@IgnoreLog
@GetMapping("/permission")
@Operation(summary = "获取用户权限")
public UserPermissionVO getUserPermission() {
return permissionService.getUserPermission();
}
}

View File

@@ -21,11 +21,9 @@ public interface SystemMenuConvert {
SystemMenuConvert MAPPER = Mappers.getMapper(SystemMenuConvert.class);
SystemMenuCreateValidMenuRequest toMenuValidate(SystemMenuCreateRequest request);
SystemMenuValidMenuRequest toMenuValidate(SystemMenuDO domain);
SystemMenuCreateValidFunctionRequest toFunctionValidate(SystemMenuCreateRequest request);
SystemMenuCreateRequest toCreateValidate(SystemMenuUpdateRequest request);
SystemMenuValidFunctionRequest toFunctionValidate(SystemMenuDO domain);
SystemMenuDO to(SystemMenuCreateRequest request);

View File

@@ -7,6 +7,7 @@ import com.orion.ops.module.infra.entity.request.user.SystemUserQueryRequest;
import com.orion.ops.module.infra.entity.request.user.SystemUserUpdateRequest;
import com.orion.ops.module.infra.entity.request.user.SystemUserUpdateStatusRequest;
import com.orion.ops.module.infra.entity.vo.SystemUserVO;
import com.orion.ops.module.infra.entity.vo.UserBaseInfoVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@@ -38,5 +39,6 @@ public interface SystemUserConvert {
LoginUser toLoginUser(SystemUserDO domain);
UserBaseInfoVO toBaseInfo(LoginUser user);
}

View File

@@ -1,5 +1,7 @@
package com.orion.ops.module.infra.define;
import java.util.Collection;
/**
* 权限定义
*
@@ -15,7 +17,7 @@ public interface RoleDefine {
String ADMIN_CODE = "admin";
/**
* 是否为管理员权限
* 是否为管理员角色
*
* @param role role
* @return 是否为管理员
@@ -24,4 +26,14 @@ public interface RoleDefine {
return ADMIN_CODE.equals(role);
}
/**
* 是否包含管理员角色
*
* @param roles roles
* @return 是否包含管理员
*/
static boolean containsAdmin(Collection<String> roles) {
return roles.contains(ADMIN_CODE);
}
}

View File

@@ -22,8 +22,8 @@ import java.io.Serializable;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "SystemMenuCreateFunctionRequest", description = "菜单 创建功能请求对象")
public class SystemMenuCreateValidFunctionRequest implements Serializable {
@Schema(name = "SystemMenuValidFunctionRequest", description = "菜单 创建功能请求对象")
public class SystemMenuValidFunctionRequest implements Serializable {
@NotNull
@Schema(description = "父id")
@@ -35,16 +35,7 @@ public class SystemMenuCreateValidFunctionRequest implements Serializable {
private String name;
@Size(max = 64)
@NotBlank
@Schema(description = "菜单权限")
private String permission;
@NotNull
@Schema(description = "菜单类型 1父菜单 2子菜单 3功能")
private Integer type;
@NotNull
@Schema(description = "菜单状态 0停用 1启用")
private Integer status;
}

View File

@@ -22,8 +22,8 @@ import java.io.Serializable;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "SystemMenuCreateMenuRequest", description = "菜单 创建菜单请求对象")
public class SystemMenuCreateValidMenuRequest implements Serializable {
@Schema(name = "SystemMenuValidMenuRequest", description = "菜单 创建菜单请求对象")
public class SystemMenuValidMenuRequest implements Serializable {
@NotNull
@Schema(description = "父id")
@@ -35,14 +35,9 @@ public class SystemMenuCreateValidMenuRequest implements Serializable {
private String name;
@Size(max = 64)
@NotBlank
@Schema(description = "菜单权限")
private String permission;
@NotNull
@Schema(description = "菜单类型 1父菜单 2子菜单 3功能")
private Integer type;
@NotNull
@Schema(description = "排序")
private Integer sort;
@@ -51,10 +46,6 @@ public class SystemMenuCreateValidMenuRequest implements Serializable {
@Schema(description = "是否可见 0不可见 1可见")
private Integer visible;
@NotNull
@Schema(description = "菜单状态 0停用 1启用")
private Integer status;
@NotNull
@Schema(description = "菜单缓存 0不缓存 1缓存")
private Integer cache;

View File

@@ -0,0 +1,35 @@
package com.orion.ops.module.infra.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 用户基本信息 视图响应对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/7/19 12:30
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "UserBaseInfoVO", description = "用户基本信息 视图响应对象")
public class UserBaseInfoVO {
@Schema(description = "id")
private Long id;
@Schema(description = "用户名")
private String username;
@Schema(description = "花名")
private String nickname;
@Schema(description = "头像地址")
private String avatar;
}

View File

@@ -0,0 +1,34 @@
package com.orion.ops.module.infra.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 用户权限 视图响应对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/7/19 12:26
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "UserPermissionVO", description = "用户权限 视图响应对象")
public class UserPermissionVO {
@Schema(description = "用户基本信息")
private UserBaseInfoVO user;
@Schema(description = "该用户已启用的角色")
private List<String> roles;
@Schema(description = "该用户已启用的权限")
private List<String> permissions;
}

View File

@@ -4,7 +4,6 @@ import com.orion.lang.utils.time.Dates;
import com.orion.ops.framework.common.constant.ErrorCode;
import com.orion.ops.framework.common.security.LoginUser;
import com.orion.ops.framework.security.core.service.SecurityFrameworkService;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.module.infra.entity.dto.LoginTokenDTO;
import com.orion.ops.module.infra.enums.LoginTokenStatusEnum;
import com.orion.ops.module.infra.enums.UserStatusEnum;
@@ -14,11 +13,9 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
* 安全包配置
* 安全包 实现类
*
* @author Jiahang Li
* @version 1.0.0
@@ -35,26 +32,14 @@ public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
@Override
public boolean hasPermission(String permission) {
List<String> roles = Optional.ofNullable(SecurityUtils.getLoginUser())
.map(LoginUser::getRoles)
.orElse(null);
if (roles == null) {
return false;
}
// 检查是否有权限
return permissionService.rolesHasPermission(roles, permission);
return permissionService.hasPermission(permission);
}
@Override
public boolean hasRole(String role) {
List<String> roles = Optional.ofNullable(SecurityUtils.getLoginUser())
.map(LoginUser::getRoles)
.orElse(null);
if (roles == null) {
return false;
}
// 检查是否有角色
return permissionService.rolesHasRole(roles, role);
return permissionService.hasRole(role);
}
@Override

View File

@@ -2,6 +2,8 @@ package com.orion.ops.module.infra.service;
import com.orion.ops.module.infra.entity.domain.SystemRoleDO;
import com.orion.ops.module.infra.entity.dto.SystemMenuCacheDTO;
import com.orion.ops.module.infra.entity.vo.SystemMenuVO;
import com.orion.ops.module.infra.entity.vo.UserPermissionVO;
import java.util.List;
import java.util.Map;
@@ -42,21 +44,33 @@ public interface PermissionService {
void initPermissionCache();
/**
* 检查角色是否含有此角色 (有效性判断)
* 检查当前用户是否含有此角色 (有效性判断)
*
* @param roles roles
* @param role role
* @param role role
* @return 是否包含
*/
boolean rolesHasRole(List<String> roles, String role);
boolean hasRole(String role);
/**
* 检查角色是否含有此权限 (有效性判断)
* 检查当前用户是否含有此权限 (有效性判断)
*
* @param roles roles
* @param permission permission
* @return 是否包含
*/
boolean rolesHasPermission(List<String> roles, String permission);
boolean hasPermission(String permission);
/**
* 获取用户菜单
*
* @return 菜单
*/
List<SystemMenuVO> getUserMenuList();
/**
* 获取用户权限
*
* @return 权限信息
*/
UserPermissionVO getUserPermission();
}

View File

@@ -49,6 +49,14 @@ public interface SystemMenuService {
*/
List<SystemMenuVO> getSystemMenuList(SystemMenuQueryRequest request);
/**
* 构建菜单树
*
* @param menus menus
* @return tree
*/
List<SystemMenuVO> buildSystemMenuTree(List<SystemMenuVO> menus);
/**
* 通过 id 级联更新菜单状态
*

View File

@@ -1,7 +1,9 @@
package com.orion.ops.module.infra.service.impl;
import com.orion.lang.utils.collect.Lists;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.module.infra.convert.SystemMenuConvert;
import com.orion.ops.module.infra.convert.SystemUserConvert;
import com.orion.ops.module.infra.dao.SystemMenuDAO;
import com.orion.ops.module.infra.dao.SystemRoleDAO;
import com.orion.ops.module.infra.dao.SystemRoleMenuDAO;
@@ -10,9 +12,13 @@ import com.orion.ops.module.infra.entity.domain.SystemMenuDO;
import com.orion.ops.module.infra.entity.domain.SystemRoleDO;
import com.orion.ops.module.infra.entity.domain.SystemRoleMenuDO;
import com.orion.ops.module.infra.entity.dto.SystemMenuCacheDTO;
import com.orion.ops.module.infra.entity.vo.SystemMenuVO;
import com.orion.ops.module.infra.entity.vo.UserBaseInfoVO;
import com.orion.ops.module.infra.entity.vo.UserPermissionVO;
import com.orion.ops.module.infra.enums.MenuStatusEnum;
import com.orion.ops.module.infra.enums.RoleStatusEnum;
import com.orion.ops.module.infra.service.PermissionService;
import com.orion.ops.module.infra.service.SystemMenuService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -34,23 +40,12 @@ import java.util.stream.Collectors;
@Service
public class PermissionServiceImpl implements PermissionService {
/**
* 角色缓存
*/
@Getter
private final Map<String, SystemRoleDO> roleCache = new HashMap<>();
/**
* 菜单缓存 以作角色权限直接引用
*
* @see #roleMenuCache
*/
@Getter
private final List<SystemMenuCacheDTO> menuCache = new ArrayList<>();
/**
* 角色菜单关联
*/
@Getter
private final Map<String, List<SystemMenuCacheDTO>> roleMenuCache = new HashMap<>();
@@ -63,6 +58,9 @@ public class PermissionServiceImpl implements PermissionService {
@Resource
private SystemRoleMenuDAO systemRoleMenuDAO;
@Resource
private SystemMenuService systemMenuService;
@PostConstruct
@Override
public void initPermissionCache() {
@@ -105,37 +103,29 @@ public class PermissionServiceImpl implements PermissionService {
}
@Override
public boolean rolesHasRole(List<String> roles, String role) {
// 检查是否为超级管理员
for (String r : roles) {
// 是否为超级管理员
if (RoleDefine.isAdmin(r) && this.checkRoleEnabled(r)) {
return true;
}
}
// 检查是否包含
if (!roles.contains(role)) {
public boolean hasRole(String role) {
// 获取用户角色
List<String> roles = this.getUserEnabledRoles();
if (roles.isEmpty()) {
return false;
}
// 检查是否启用
return this.checkRoleEnabled(role);
// 检查是否为超级管理员或包含此角色
return RoleDefine.containsAdmin(roles) || roles.contains(role);
}
@Override
public boolean rolesHasPermission(List<String> roles, String permission) {
public boolean hasPermission(String permission) {
// 获取用户角色
List<String> roles = this.getUserEnabledRoles();
if (roles.isEmpty()) {
return false;
}
// 检查是否为超级管理员
for (String r : roles) {
// 是否为超级管理员
if (RoleDefine.isAdmin(r) && this.checkRoleEnabled(r)) {
return true;
}
if (RoleDefine.containsAdmin(roles)) {
return true;
}
// 检查普通角色是否有此权限
for (String role : roles) {
// 角色是否启用
if (!this.checkRoleEnabled(role)) {
continue;
}
// 获取角色权限列表
List<SystemMenuCacheDTO> menus = roleMenuCache.get(role);
if (Lists.isEmpty(menus)) {
@@ -153,6 +143,71 @@ public class PermissionServiceImpl implements PermissionService {
return false;
}
@Override
public List<SystemMenuVO> getUserMenuList() {
// 获取用户角色
List<String> roles = this.getUserEnabledRoles();
if (roles.isEmpty()) {
return Lists.empty();
}
// 查询角色菜单
List<SystemMenuVO> menus = roles.stream()
.map(roleMenuCache::get)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.distinct()
.map(SystemMenuConvert.MAPPER::to)
.collect(Collectors.toList());
// 构建菜单树
return systemMenuService.buildSystemMenuTree(menus);
}
@Override
public UserPermissionVO getUserPermission() {
// 获取用户信息
UserBaseInfoVO user = SystemUserConvert.MAPPER.toBaseInfo(SecurityUtils.getLoginUser());
// 获取用户角色
List<String> roles = this.getUserEnabledRoles();
// 获取用户权限
List<String> permissions;
if (roles.isEmpty()) {
permissions = Lists.empty();
} else {
permissions = roles.stream()
.map(roleMenuCache::get)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.map(SystemMenuCacheDTO::getPermission)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
}
// 组装数据
UserPermissionVO vo = new UserPermissionVO().builder()
.user(user)
.roles(roles)
.permissions(permissions)
.build();
return vo;
}
/**
* 获取用户启用的角色
*
* @return roles
*/
private List<String> getUserEnabledRoles() {
// 获取当前用户角色
List<String> roles = SecurityUtils.getLoginUser().getRoles();
if (Lists.isEmpty(roles)) {
return Lists.empty();
}
// 过滤未启用的角色
return roles.stream()
.filter(this::checkRoleEnabled)
.collect(Collectors.toList());
}
/**
* 检查角色是否启用
*

View File

@@ -25,9 +25,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -50,10 +48,15 @@ public class SystemMenuServiceImpl implements SystemMenuService {
@Override
public Long createSystemMenu(SystemMenuCreateRequest request) {
// 验证参数
this.validateCreateRequest(request);
// 转换
SystemMenuDO record = SystemMenuConvert.MAPPER.to(request);
record.setStatus(MenuStatusEnum.ENABLED.getStatus());
// 验证参数
this.validateRequest(record, request.getType());
// 方法
if (record.getSort() == null) {
record.setSort(Const.DEFAULT_SORT);
}
// 保存数据
int effect = systemMenuDAO.insert(record);
log.info("SystemMenuService-createSystemMenu effect: {}, record: {}", effect, JSON.toJSONString(record));
@@ -69,10 +72,10 @@ public class SystemMenuServiceImpl implements SystemMenuService {
Long id = Valid.notNull(request.getId(), ErrorMessage.ID_MISSING);
SystemMenuDO record = systemMenuDAO.selectById(id);
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
// 验证参数
this.validateCreateRequest(SystemMenuConvert.MAPPER.toCreateValidate(request));
// 转换
SystemMenuDO updateRecord = SystemMenuConvert.MAPPER.to(request);
// 验证参数
this.validateRequest(updateRecord, record.getType());
// 更新
int effect = systemMenuDAO.updateById(updateRecord);
log.info("SystemMenuService-updateSystemMenu effect: {}, updateRecord: {}", effect, JSON.toJSONString(updateRecord));
@@ -115,38 +118,54 @@ public class SystemMenuServiceImpl implements SystemMenuService {
if (menus.isEmpty()) {
return Lists.empty();
}
// 构建菜单树
return this.buildSystemMenuTree(menus);
}
@Override
public List<SystemMenuVO> buildSystemMenuTree(List<SystemMenuVO> menus) {
// id 映射数据
Map<Long, SystemMenuVO> idMapping = menus.stream()
.collect(Collectors.toMap(SystemMenuVO::getId, Function.identity()));
// 子级节点数据
Map<Long, List<SystemMenuVO>> childrenNodesGroup = menus.stream()
.collect(Collectors.groupingBy(SystemMenuVO::getParentId));
// 寻找根节点
List<SystemMenuVO> rootNodes = menus.stream()
.filter(s -> idMapping.get(s.getParentId()) == null)
.collect(Collectors.toList());
// 子级节点数据
Map<Long, List<SystemMenuVO>> childrenNodesGroup = menus.stream()
.collect(Collectors.groupingBy(SystemMenuVO::getParentId));
// 设置子节点
this.setChildrenNodes(rootNodes, childrenNodesGroup);
return rootNodes;
}
/**
* 设置子节点
*
* @param parentNodes 父节点
* @param childrenNodesGroup 子节点组
*/
private void setChildrenNodes(List<SystemMenuVO> parentNodes, Map<Long, List<SystemMenuVO>> childrenNodesGroup) {
// 为空则跳出
if (Lists.isEmpty(parentNodes)) {
return;
}
// 排序
parentNodes.sort(Comparator.comparing(SystemMenuVO::getType)
.thenComparing(SystemMenuVO::getSort)
.thenComparing(SystemMenuVO::getId));
// 设置子节点
for (SystemMenuVO parentNode : parentNodes) {
List<SystemMenuVO> childrenNodes = childrenNodesGroup.get(parentNode.getId());
parentNode.setChildren(childrenNodes);
if (Lists.isEmpty(childrenNodes)) {
continue;
// 非叶子节点继续设置
if (Lists.isNotEmpty(childrenNodes)) {
// 级联设置
this.setChildrenNodes(childrenNodes, childrenNodesGroup);
}
// 级联设置
this.setChildrenNodes(childrenNodes, childrenNodesGroup);
}
}
@@ -232,28 +251,35 @@ public class SystemMenuServiceImpl implements SystemMenuService {
/**
* 验证创建菜单参数 不进行重复性校验
*
* @param request request
* @param domain domain
* @param record record
*/
private void validateCreateRequest(SystemMenuCreateRequest request) {
Long parentId = request.getParentId();
MenuTypeEnum type = Valid.valid(MenuTypeEnum::of, request.getType());
// 检查必填参数
private void validateRequest(SystemMenuDO domain, Integer menuType) {
// 父id不能为当前id
Valid.isFalse(Objects.equals(domain.getParentId(), domain.getId()), ErrorMessage.INVALID_PARENT_MENU);
// 检查菜单类型
MenuTypeEnum type = Valid.valid(MenuTypeEnum::of, menuType);
// 验证父菜单参数
if (MenuTypeEnum.PARENT_MENU.equals(type)) {
// 父菜单创建的 parentId 为 0
request.setParentId(Const.ROOT_MENU_ID);
domain.setParentId(Const.ROOT_MENU_ID);
// 验证必填参数
Valid.valid(SystemMenuConvert.MAPPER.toMenuValidate(request));
} else if (MenuTypeEnum.SUB_MENU.equals(type)) {
Valid.valid(SystemMenuConvert.MAPPER.toMenuValidate(domain));
return;
}
// 验证 parentId 是否存在
SystemMenuDO parent = Valid.notNull(systemMenuDAO.selectById(domain.getParentId()), ErrorMessage.PARENT_MENU_ABSENT);
// 验证子菜单/功能参数
if (MenuTypeEnum.SUB_MENU.equals(type)) {
// 验证必填参数
Valid.valid(SystemMenuConvert.MAPPER.toMenuValidate(request));
// 检查 parentId 是否为为父菜单
SystemMenuDO parent = Valid.notNull(systemMenuDAO.selectById(parentId), ErrorMessage.PARENT_MENU_ABSENT);
Valid.eq(parent.getType(), MenuTypeEnum.PARENT_MENU.getType());
Valid.valid(SystemMenuConvert.MAPPER.toMenuValidate(domain));
// 父级必须为父菜单
Valid.eq(parent.getType(), MenuTypeEnum.PARENT_MENU.getType(), ErrorMessage.INVALID_PARENT_MENU);
} else if (MenuTypeEnum.FUNCTION.equals(type)) {
// 验证必填参数
Valid.valid(SystemMenuConvert.MAPPER.toFunctionValidate(request));
// 检查 parentId 是否存在
Valid.notNull(systemMenuDAO.selectById(parentId), ErrorMessage.PARENT_MENU_ABSENT);
Valid.valid(SystemMenuConvert.MAPPER.toFunctionValidate(domain));
// 父级必须不能为自己
Valid.neq(parent.getType(), MenuTypeEnum.FUNCTION.getType(), ErrorMessage.INVALID_PARENT_MENU);
}
}

View File

@@ -53,7 +53,7 @@ public class SystemUserRoleServiceImpl implements SystemUserRoleService {
Integer effect = systemUserRoleDAO.deleteByUserId(userId);
// 更新缓存中的角色
RedisUtils.<LoginUser>processSetJson(UserCacheKeyDefine.USER_INFO, s -> {
s.setRoles(null);
s.setRoles(Lists.empty());
}, userId);
return effect;
}