refactor(system/role): 重构角色管理

This commit is contained in:
2025-02-06 20:36:18 +08:00
parent 4caada8c64
commit f6535ef7a3
20 changed files with 455 additions and 77 deletions

View File

@@ -16,7 +16,12 @@
package top.continew.admin.system.mapper; package top.continew.admin.system.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import top.continew.admin.system.model.entity.UserRoleDO; import top.continew.admin.system.model.entity.UserRoleDO;
import top.continew.admin.system.model.resp.role.RoleUserResp;
import top.continew.starter.data.mp.base.BaseMapper; import top.continew.starter.data.mp.base.BaseMapper;
/** /**
@@ -26,4 +31,15 @@ import top.continew.starter.data.mp.base.BaseMapper;
* @since 2023/2/13 23:13 * @since 2023/2/13 23:13
*/ */
public interface UserRoleMapper extends BaseMapper<UserRoleDO> { public interface UserRoleMapper extends BaseMapper<UserRoleDO> {
/**
* 分页查询列表
*
* @param page 分页条件
* @param queryWrapper 查询条件
* @return 分页列表信息
*/
IPage<RoleUserResp> selectUserPage(@Param("page") IPage<UserRoleDO> page,
@Param(Constants.WRAPPER) QueryWrapper<UserRoleDO> queryWrapper);
} }

View File

@@ -16,6 +16,7 @@
package top.continew.admin.system.model.entity; package top.continew.admin.system.model.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@@ -37,6 +38,12 @@ public class UserRoleDO implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId
private Long id;
/** /**
* 用户 ID * 用户 ID
*/ */

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.system.model.query;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 角色关联用户查询条件
*
* @author Charles7c
* @since 2025/2/5 22:01
*/
@Data
@Schema(description = "角色关联用户查询条件")
public class RoleUserQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色 ID
*/
@Schema(description = "角色 ID", example = "1")
private Long roleId;
/**
* 关键词
*/
@Schema(description = "关键词", example = "zhangsan")
private String description;
}

View File

@@ -72,4 +72,10 @@ public class UserQuery implements Serializable {
*/ */
@Schema(description = "用户 ID 列表", example = "[1,2,3]") @Schema(description = "用户 ID 列表", example = "[1,2,3]")
private List<Long> userIds; private List<Long> userIds;
/**
* 不包含的用户 ID 列表
*/
@Schema(description = "不包含的用户 ID 列表", example = "[1,2]")
private List<Long> excludeUserIds;
} }

View File

@@ -73,12 +73,6 @@ public class RoleReq implements Serializable {
@Length(max = 200, message = "描述长度不能超过 {max} 个字符") @Length(max = 200, message = "描述长度不能超过 {max} 个字符")
private String description; private String description;
/**
* 功能权限:菜单 ID 列表
*/
@Schema(description = "功能权限:菜单 ID 列表", example = "1000,1010,1011,1012,1013,1014")
private List<Long> menuIds = new ArrayList<>();
/** /**
* 数据权限 * 数据权限
*/ */
@@ -91,12 +85,6 @@ public class RoleReq implements Serializable {
@Schema(description = "权限范围:部门 ID 列表", example = "5") @Schema(description = "权限范围:部门 ID 列表", example = "5")
private List<Long> deptIds = new ArrayList<>(); private List<Long> deptIds = new ArrayList<>();
/**
* 菜单选择是否父子节点关联
*/
@Schema(description = "菜单选择是否父子节点关联", example = "false")
private Boolean menuCheckStrictly;
/** /**
* 部门选择是否父子节点关联 * 部门选择是否父子节点关联
*/ */

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.system.model.req;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 修改角色功能权限参数
*
* @author Charles7c
* @since 2025/2/5 21:00
*/
@Data
@Schema(description = "修改角色功能权限参数")
public class RoleUpdatePermissionReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色 ID
*/
@Schema(description = "角色 ID", example = "1")
private Long roleId;
/**
* 功能权限:菜单 ID 列表
*/
@Schema(description = "功能权限:菜单 ID 列表", example = "1000,1010,1011,1012,1013,1014")
private List<Long> menuIds = new ArrayList<>();
/**
* 菜单选择是否父子节点关联
*/
@Schema(description = "菜单选择是否父子节点关联", example = "false")
private Boolean menuCheckStrictly;
}

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.admin.system.model.resp; package top.continew.admin.system.model.resp.role;
import cn.crane4j.annotation.AssembleMethod; import cn.crane4j.annotation.AssembleMethod;
import cn.crane4j.annotation.ContainerMethod; import cn.crane4j.annotation.ContainerMethod;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.admin.system.model.resp; package top.continew.admin.system.model.resp.role;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@@ -0,0 +1,129 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.system.model.resp.role;
import cn.crane4j.annotation.Assemble;
import cn.crane4j.core.executor.handler.ManyToManyAssembleOperationHandler;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.continew.admin.common.constant.ContainerConstants;
import top.continew.admin.common.constant.SysConstants;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.common.enums.GenderEnum;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
/**
* 角色关联用户信息
*
* @author Charles7c
* @since 2025/2/5 22:01
*/
@Data
@Schema(description = "角色关联用户信息")
public class RoleUserResp implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@Schema(description = "ID", example = "1")
private Long id;
/**
* 角色 ID
*/
@Schema(description = "角色 ID", example = "1")
private Long roleId;
/**
* 用户 ID
*/
@Schema(description = "用户 ID", example = "1")
@Assemble(prop = ":roleIds", sort = 0, container = ContainerConstants.USER_ROLE_ID_LIST)
private Long userId;
/**
* 用户名
*/
@Schema(description = "用户名", example = "zhangsan")
private String username;
/**
* 昵称
*/
@Schema(description = "昵称", example = "张三")
private String nickname;
/**
* 性别
*/
@Schema(description = "性别", example = "1")
private GenderEnum gender;
/**
* 状态
*/
@Schema(description = "状态", example = "1")
private DisEnableStatusEnum status;
/**
* 是否为系统内置数据
*/
@Schema(description = "是否为系统内置数据", example = "false")
private Boolean isSystem;
/**
* 描述
*/
@Schema(description = "描述", example = "测试人员描述信息")
private String description;
/**
* 部门 ID
*/
@Schema(description = "部门 ID", example = "5")
private Long deptId;
/**
* 所属部门
*/
@Schema(description = "所属部门", example = "测试部")
private String deptName;
/**
* 角色 ID 列表
*/
@Schema(description = "角色 ID 列表", example = "2")
@Assemble(prop = ":roleNames", container = ContainerConstants.USER_ROLE_NAME_LIST, handlerType = ManyToManyAssembleOperationHandler.class)
private List<Long> roleIds;
/**
* 角色名称列表
*/
@Schema(description = "角色名称列表", example = "测试人员")
private List<String> roleNames;
public Boolean getDisabled() {
return this.getIsSystem() && Objects.equals(roleId, SysConstants.SUPER_ROLE_ID);
}
}

View File

@@ -20,8 +20,9 @@ import top.continew.admin.common.context.RoleContext;
import top.continew.admin.system.model.entity.RoleDO; import top.continew.admin.system.model.entity.RoleDO;
import top.continew.admin.system.model.query.RoleQuery; import top.continew.admin.system.model.query.RoleQuery;
import top.continew.admin.system.model.req.RoleReq; import top.continew.admin.system.model.req.RoleReq;
import top.continew.admin.system.model.resp.RoleDetailResp; import top.continew.admin.system.model.req.RoleUpdatePermissionReq;
import top.continew.admin.system.model.resp.RoleResp; import top.continew.admin.system.model.resp.role.RoleDetailResp;
import top.continew.admin.system.model.resp.role.RoleResp;
import top.continew.starter.data.mp.service.IService; import top.continew.starter.data.mp.service.IService;
import top.continew.starter.extension.crud.service.BaseService; import top.continew.starter.extension.crud.service.BaseService;
@@ -36,6 +37,14 @@ import java.util.Set;
*/ */
public interface RoleService extends BaseService<RoleResp, RoleDetailResp, RoleQuery, RoleReq>, IService<RoleDO> { public interface RoleService extends BaseService<RoleResp, RoleDetailResp, RoleQuery, RoleReq>, IService<RoleDO> {
/**
* 修改角色权限
*
* @param id 角色 ID
* @param req 参数
*/
void updatePermission(Long id, RoleUpdatePermissionReq req);
/** /**
* 分配角色给用户 * 分配角色给用户
* *

View File

@@ -17,6 +17,10 @@
package top.continew.admin.system.service; package top.continew.admin.system.service;
import top.continew.admin.system.model.entity.UserRoleDO; import top.continew.admin.system.model.entity.UserRoleDO;
import top.continew.admin.system.model.query.RoleUserQuery;
import top.continew.admin.system.model.resp.role.RoleUserResp;
import top.continew.starter.extension.crud.model.query.PageQuery;
import top.continew.starter.extension.crud.model.resp.PageResp;
import java.util.List; import java.util.List;
@@ -28,6 +32,15 @@ import java.util.List;
*/ */
public interface UserRoleService { public interface UserRoleService {
/**
* 分页查询角色关联用户列表
*
* @param query 查询条件
* @param pageQuery 分页查询条件
* @return 分页信息
*/
PageResp<RoleUserResp> pageUser(RoleUserQuery query, PageQuery pageQuery);
/** /**
* 批量分配角色给指定用户 * 批量分配角色给指定用户
* *
@@ -46,6 +59,13 @@ public interface UserRoleService {
*/ */
boolean assignRoleToUsers(Long roleId, List<Long> userIds); boolean assignRoleToUsers(Long roleId, List<Long> userIds);
/**
* 根据 ID 删除
*
* @param ids ID 列表
*/
void deleteByIds(List<Long> ids);
/** /**
* 根据用户 ID 删除 * 根据用户 ID 删除
* *

View File

@@ -37,9 +37,10 @@ import top.continew.admin.system.mapper.RoleMapper;
import top.continew.admin.system.model.entity.RoleDO; import top.continew.admin.system.model.entity.RoleDO;
import top.continew.admin.system.model.query.RoleQuery; import top.continew.admin.system.model.query.RoleQuery;
import top.continew.admin.system.model.req.RoleReq; import top.continew.admin.system.model.req.RoleReq;
import top.continew.admin.system.model.req.RoleUpdatePermissionReq;
import top.continew.admin.system.model.resp.MenuResp; import top.continew.admin.system.model.resp.MenuResp;
import top.continew.admin.system.model.resp.RoleDetailResp; import top.continew.admin.system.model.resp.role.RoleDetailResp;
import top.continew.admin.system.model.resp.RoleResp; import top.continew.admin.system.model.resp.role.RoleResp;
import top.continew.admin.system.service.*; import top.continew.admin.system.service.*;
import top.continew.starter.core.validation.CheckUtils; import top.continew.starter.core.validation.CheckUtils;
import top.continew.starter.extension.crud.service.BaseServiceImpl; import top.continew.starter.extension.crud.service.BaseServiceImpl;
@@ -71,8 +72,6 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
CheckUtils.throwIf(this.isCodeExists(code, null), "新增失败,[{}] 已存在", code); CheckUtils.throwIf(this.isCodeExists(code, null), "新增失败,[{}] 已存在", code);
// 新增信息 // 新增信息
Long roleId = super.add(req); Long roleId = super.add(req);
// 保存角色和菜单关联
roleMenuService.add(req.getMenuIds(), roleId);
// 保存角色和部门关联 // 保存角色和部门关联
roleDeptService.add(req.getDeptIds(), roleId); roleDeptService.add(req.getDeptIds(), roleId);
return roleId; return roleId;
@@ -95,12 +94,10 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
if (SysConstants.SUPER_ROLE_CODE.equals(req.getCode())) { if (SysConstants.SUPER_ROLE_CODE.equals(req.getCode())) {
return; return;
} }
// 保存角色和菜单关联
boolean isSaveMenuSuccess = roleMenuService.add(req.getMenuIds(), id);
// 保存角色和部门关联 // 保存角色和部门关联
boolean isSaveDeptSuccess = roleDeptService.add(req.getDeptIds(), id); boolean isSaveDeptSuccess = roleDeptService.add(req.getDeptIds(), id);
// 如果功能权限或数据权限有变更,则更新在线用户权限信息 // 如果数据权限有变更,则更新在线用户权限信息
if (isSaveMenuSuccess || isSaveDeptSuccess || ObjectUtil.notEqual(req.getDataScope(), oldDataScope)) { if (isSaveDeptSuccess || ObjectUtil.notEqual(req.getDataScope(), oldDataScope)) {
this.updateUserContext(id); this.updateUserContext(id);
} }
} }
@@ -121,6 +118,22 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
roleDeptService.deleteByRoleIds(ids); roleDeptService.deleteByRoleIds(ids);
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePermission(Long id, RoleUpdatePermissionReq req) {
super.getById(id);
// 保存角色和菜单关联
boolean isSaveMenuSuccess = roleMenuService.add(req.getMenuIds(), id);
// 如果功能权限有变更,则更新在线用户权限信息
if (isSaveMenuSuccess) {
this.updateUserContext(id);
}
baseMapper.lambdaUpdate()
.set(RoleDO::getMenuCheckStrictly, req.getMenuCheckStrictly())
.eq(RoleDO::getId, id)
.update();
}
@Override @Override
public void assignToUsers(Long id, List<Long> userIds) { public void assignToUsers(Long id, List<Long> userIds) {
super.getById(id); super.getById(id);

View File

@@ -16,18 +16,29 @@
package top.continew.admin.system.service.impl; package top.continew.admin.system.service.impl;
import cn.crane4j.annotation.AutoOperate;
import cn.crane4j.annotation.ContainerMethod; import cn.crane4j.annotation.ContainerMethod;
import cn.crane4j.annotation.MappingType; import cn.crane4j.annotation.MappingType;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import top.continew.admin.common.constant.ContainerConstants; import top.continew.admin.common.constant.ContainerConstants;
import top.continew.admin.common.constant.SysConstants; import top.continew.admin.common.constant.SysConstants;
import top.continew.admin.system.mapper.UserRoleMapper; import top.continew.admin.system.mapper.UserRoleMapper;
import top.continew.admin.system.model.entity.UserRoleDO; import top.continew.admin.system.model.entity.UserRoleDO;
import top.continew.admin.system.model.query.RoleUserQuery;
import top.continew.admin.system.model.resp.role.RoleUserResp;
import top.continew.admin.system.service.UserRoleService; import top.continew.admin.system.service.UserRoleService;
import top.continew.starter.core.validation.CheckUtils; import top.continew.starter.core.validation.CheckUtils;
import top.continew.starter.extension.crud.model.query.PageQuery;
import top.continew.starter.extension.crud.model.resp.PageResp;
import java.util.List; import java.util.List;
@@ -43,6 +54,28 @@ public class UserRoleServiceImpl implements UserRoleService {
private final UserRoleMapper baseMapper; private final UserRoleMapper baseMapper;
@Override
@AutoOperate(type = RoleUserResp.class, on = "list")
public PageResp<RoleUserResp> pageUser(RoleUserQuery query, PageQuery pageQuery) {
String description = query.getDescription();
QueryWrapper<UserRoleDO> queryWrapper = new QueryWrapper<UserRoleDO>().eq("t1.role_id", query.getRoleId())
.and(StrUtil.isNotBlank(description), q -> q.like("t2.username", description)
.or()
.like("t2.nickname", description)
.or()
.like("t2.description", description));
// 排序
if (!pageQuery.getSort().isUnsorted()) {
for (Sort.Order order : pageQuery.getSort()) {
String property = order.getProperty();
queryWrapper.orderBy(true, order.isAscending(), CharSequenceUtil.toUnderlineCase(property));
}
}
IPage<RoleUserResp> page = baseMapper.selectUserPage(new Page<>(pageQuery.getPage(), pageQuery
.getSize()), queryWrapper);
return PageResp.build(page);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean assignRolesToUser(List<Long> roleIds, Long userId) { public boolean assignRolesToUser(List<Long> roleIds, Long userId) {
@@ -67,28 +100,16 @@ public class UserRoleServiceImpl implements UserRoleService {
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean assignRoleToUsers(Long roleId, List<Long> userIds) { public boolean assignRoleToUsers(Long roleId, List<Long> userIds) {
// 检查是否有变更
List<Long> oldUserIdList = baseMapper.lambdaQuery()
.select(UserRoleDO::getUserId)
.eq(UserRoleDO::getRoleId, roleId)
.list()
.stream()
.map(UserRoleDO::getUserId)
.toList();
if (CollUtil.isEmpty(CollUtil.disjunction(userIds, oldUserIdList))) {
return false;
}
CheckUtils.throwIf(SysConstants.SUPER_ROLE_ID.equals(roleId) && !userIds
.contains(SysConstants.SUPER_USER_ID), "不允许变更超管用户角色");
// 删除原有关联
baseMapper.lambdaUpdate().eq(UserRoleDO::getRoleId, roleId).remove();
// 保存最新关联
List<UserRoleDO> userRoleList = userIds.stream().map(userId -> new UserRoleDO(userId, roleId)).toList(); List<UserRoleDO> userRoleList = userIds.stream().map(userId -> new UserRoleDO(userId, roleId)).toList();
return baseMapper.insertBatch(userRoleList); return baseMapper.insertBatch(userRoleList);
} }
@Override
public void deleteByIds(List<Long> ids) {
baseMapper.deleteByIds(ids);
}
@Override @Override
public void deleteByUserIds(List<Long> userIds) { public void deleteByUserIds(List<Long> userIds) {
if (CollUtil.isEmpty(userIds)) { if (CollUtil.isEmpty(userIds)) {

View File

@@ -488,6 +488,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
List<Date> createTimeList = query.getCreateTime(); List<Date> createTimeList = query.getCreateTime();
Long deptId = query.getDeptId(); Long deptId = query.getDeptId();
List<Long> userIdList = query.getUserIds(); List<Long> userIdList = query.getUserIds();
List<Long> excludeUserIdList = query.getExcludeUserIds();
return new QueryWrapper<UserDO>().and(StrUtil.isNotBlank(description), q -> q.like("t1.username", description) return new QueryWrapper<UserDO>().and(StrUtil.isNotBlank(description), q -> q.like("t1.username", description)
.or() .or()
.like("t1.nickname", description) .like("t1.nickname", description)
@@ -504,7 +505,8 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
deptIdList.add(deptId); deptIdList.add(deptId);
q.in("t1.dept_id", deptIdList); q.in("t1.dept_id", deptIdList);
}) })
.in(CollUtil.isNotEmpty(userIdList), "t1.id", userIdList); .in(CollUtil.isNotEmpty(userIdList), "t1.id", userIdList)
.notIn(CollUtil.isNotEmpty(excludeUserIdList), "t1.id", excludeUserIdList);
} }
/** /**

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.continew.admin.system.mapper.UserRoleMapper">
<select id="selectUserPage" resultType="top.continew.admin.system.model.resp.role.RoleUserResp">
SELECT
t1.*,
t2.nickname,
t2.username,
t2.status,
t2.gender,
t2.dept_id,
t2.description,
t2.is_system,
t3.name AS deptName
FROM sys_user_role AS t1
LEFT JOIN sys_user AS t2 ON t2.id = t1.user_id
LEFT JOIN sys_dept AS t3 ON t3.id = t2.dept_id
${ew.customSqlSegment}
</select>
</mapper>

View File

@@ -27,13 +27,18 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import top.continew.admin.common.controller.BaseController; import top.continew.admin.common.controller.BaseController;
import top.continew.admin.system.model.query.RoleQuery; import top.continew.admin.system.model.query.RoleQuery;
import top.continew.admin.system.model.query.RoleUserQuery;
import top.continew.admin.system.model.req.RoleReq; import top.continew.admin.system.model.req.RoleReq;
import top.continew.admin.system.model.resp.RoleDetailResp; import top.continew.admin.system.model.req.RoleUpdatePermissionReq;
import top.continew.admin.system.model.resp.RoleResp; import top.continew.admin.system.model.resp.role.RoleDetailResp;
import top.continew.admin.system.model.resp.role.RoleResp;
import top.continew.admin.system.model.resp.role.RoleUserResp;
import top.continew.admin.system.service.RoleService; import top.continew.admin.system.service.RoleService;
import top.continew.admin.system.service.UserRoleService; import top.continew.admin.system.service.UserRoleService;
import top.continew.starter.extension.crud.annotation.CrudRequestMapping; import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import top.continew.starter.extension.crud.enums.Api; import top.continew.starter.extension.crud.enums.Api;
import top.continew.starter.extension.crud.model.query.PageQuery;
import top.continew.starter.extension.crud.model.resp.PageResp;
import java.util.List; import java.util.List;
@@ -47,12 +52,30 @@ import java.util.List;
@Validated @Validated
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@CrudRequestMapping(value = "/system/role", api = {Api.PAGE, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE}) @CrudRequestMapping(value = "/system/role", api = {Api.LIST, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE})
public class RoleController extends BaseController<RoleService, RoleResp, RoleDetailResp, RoleQuery, RoleReq> { public class RoleController extends BaseController<RoleService, RoleResp, RoleDetailResp, RoleQuery, RoleReq> {
private final UserRoleService userRoleService; private final UserRoleService userRoleService;
@Operation(summary = "分配角色给用户", description = "批量分配角色给用户") @Operation(summary = "修改权限", description = "修改角色的功能权限")
@SaCheckPermission("system:role:updatePermission")
@PutMapping("/{id}/permission")
public void updatePermission(@PathVariable("id") Long id, @Validated @RequestBody RoleUpdatePermissionReq req) {
baseService.updatePermission(id, req);
}
@Operation(summary = "分页查询关联用户", description = "分页查询角色关联的用户列表")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@SaCheckPermission("system:role:list")
@GetMapping("/{id}/user")
public PageResp<RoleUserResp> pageUser(@PathVariable("id") Long id,
@Validated RoleUserQuery query,
@Validated PageQuery pageQuery) {
query.setRoleId(id);
return userRoleService.pageUser(query, pageQuery);
}
@Operation(summary = "分配用户", description = "批量分配角色给用户")
@SaCheckPermission("system:role:assign") @SaCheckPermission("system:role:assign")
@PostMapping("/{id}/user") @PostMapping("/{id}/user")
public void assignToUsers(@PathVariable("id") Long id, public void assignToUsers(@PathVariable("id") Long id,
@@ -60,10 +83,18 @@ public class RoleController extends BaseController<RoleService, RoleResp, RoleDe
baseService.assignToUsers(id, userIds); baseService.assignToUsers(id, userIds);
} }
@Operation(summary = "查询角色关联用户", description = "查询角色关联的用户ID列表") @Operation(summary = "取消分配用户", description = "批量取消分配角色给用户")
@SaCheckPermission("system:role:unassign")
@DeleteMapping("/user")
public void unassignFromUsers(@Validated @NotEmpty(message = "用户列表不能为空") @RequestBody List<Long> userRoleIds) {
userRoleService.deleteByIds(userRoleIds);
}
@Operation(summary = "查询关联用户ID", description = "查询角色关联的用户ID列表")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH) @Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@GetMapping("/{id}/user") @SaCheckPermission("system:role:list")
public List<Long> listUser(@PathVariable("id") Long id) { @GetMapping("/{id}/user/id")
public List<Long> listUserId(@PathVariable("id") Long id) {
return userRoleService.listUserIdByRoleId(id); return userRoleService.listUserIdByRoleId(id);
} }
} }

View File

@@ -24,7 +24,9 @@ VALUES
(1033, '新增', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:add', 3, 1, 1, NOW()), (1033, '新增', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:add', 3, 1, 1, NOW()),
(1034, '修改', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:update', 4, 1, 1, NOW()), (1034, '修改', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:update', 4, 1, 1, NOW()),
(1035, '删除', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:delete', 5, 1, 1, NOW()), (1035, '删除', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:delete', 5, 1, 1, NOW()),
(1036, '分配', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:assign', 6, 1, 1, NOW()), (1036, '修改权限', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:updatePermission', 6, 1, 1, NOW()),
(1037, '分配', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:assign', 7, 1, 1, NOW()),
(1038, '取消分配', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:unassign', 8, 1, 1, NOW()),
(1050, '菜单管理', 1000, 2, '/system/menu', 'SystemMenu', 'system/menu/index', NULL, 'menu', b'0', b'0', b'0', NULL, 3, 1, 1, NOW()), (1050, '菜单管理', 1000, 2, '/system/menu', 'SystemMenu', 'system/menu/index', NULL, 'menu', b'0', b'0', b'0', NULL, 3, 1, 1, NOW()),
(1051, '列表', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:list', 1, 1, 1, NOW()), (1051, '列表', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:list', 1, 1, 1, NOW()),
@@ -203,19 +205,19 @@ VALUES
-- 初始化默认用户和角色关联数据 -- 初始化默认用户和角色关联数据
INSERT INTO `sys_user_role` INSERT INTO `sys_user_role`
(`user_id`, `role_id`) (`id`, `user_id`, `role_id`)
VALUES VALUES
(1, 1), (1, 1, 1),
(547889293968801822, 547888897925840927), (2, 547889293968801822, 547888897925840927),
(547889293968801823, 547888897925840928), (3, 547889293968801823, 547888897925840928),
(547889293968801824, 547888897925840928), (4, 547889293968801824, 547888897925840928),
(547889293968801825, 547888897925840928), (5, 547889293968801825, 547888897925840928),
(547889293968801826, 547888897925840928), (6, 547889293968801826, 547888897925840928),
(547889293968801827, 547888897925840928), (7, 547889293968801827, 547888897925840928),
(547889293968801828, 547888897925840928), (8, 547889293968801828, 547888897925840928),
(547889293968801829, 547888897925840928), (9, 547889293968801829, 547888897925840928),
(547889293968801830, 547888897925840928), (10, 547889293968801830, 547888897925840928),
(547889293968801831, 547888897925840928); (11, 547889293968801831, 547888897925840928);
-- 初始化默认角色和菜单关联数据 -- 初始化默认角色和菜单关联数据
INSERT INTO `sys_role_menu` INSERT INTO `sys_role_menu`

View File

@@ -119,9 +119,11 @@ CREATE TABLE IF NOT EXISTS `sys_user_social` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户社会化关联表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户社会化关联表';
CREATE TABLE IF NOT EXISTS `sys_user_role` ( CREATE TABLE IF NOT EXISTS `sys_user_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_id` bigint(20) NOT NULL COMMENT '用户ID', `user_id` bigint(20) NOT NULL COMMENT '用户ID',
`role_id` bigint(20) NOT NULL COMMENT '角色ID', `role_id` bigint(20) NOT NULL COMMENT '角色ID',
PRIMARY KEY (`user_id`, `role_id`) PRIMARY KEY (`id`),
UNIQUE INDEX `uk_user_id_role_id`(`user_id`, `role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户和角色关联表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户和角色关联表';
CREATE TABLE IF NOT EXISTS `sys_role_menu` ( CREATE TABLE IF NOT EXISTS `sys_role_menu` (

View File

@@ -24,7 +24,9 @@ VALUES
(1033, '新增', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:add', 3, 1, 1, NOW()), (1033, '新增', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:add', 3, 1, 1, NOW()),
(1034, '修改', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:update', 4, 1, 1, NOW()), (1034, '修改', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:update', 4, 1, 1, NOW()),
(1035, '删除', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:delete', 5, 1, 1, NOW()), (1035, '删除', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:delete', 5, 1, 1, NOW()),
(1036, '分配', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:assign', 6, 1, 1, NOW()), (1036, '修改权限', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:updatePermission', 6, 1, 1, NOW()),
(1037, '分配', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:assign', 7, 1, 1, NOW()),
(1038, '取消分配', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:unassign', 8, 1, 1, NOW()),
(1050, '菜单管理', 1000, 2, '/system/menu', 'SystemMenu', 'system/menu/index', NULL, 'menu', false, false, false, NULL, 3, 1, 1, NOW()), (1050, '菜单管理', 1000, 2, '/system/menu', 'SystemMenu', 'system/menu/index', NULL, 'menu', false, false, false, NULL, 3, 1, 1, NOW()),
(1051, '列表', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:list', 1, 1, 1, NOW()), (1051, '列表', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:list', 1, 1, 1, NOW()),
@@ -203,19 +205,19 @@ VALUES
-- 初始化默认用户和角色关联数据 -- 初始化默认用户和角色关联数据
INSERT INTO "sys_user_role" INSERT INTO "sys_user_role"
("user_id", "role_id") ("id", "user_id", "role_id")
VALUES VALUES
(1, 1), (1, 1, 1),
(547889293968801822, 547888897925840927), (2, 547889293968801822, 547888897925840927),
(547889293968801823, 547888897925840928), (3, 547889293968801823, 547888897925840928),
(547889293968801824, 547888897925840928), (4, 547889293968801824, 547888897925840928),
(547889293968801825, 547888897925840928), (5, 547889293968801825, 547888897925840928),
(547889293968801826, 547888897925840928), (6, 547889293968801826, 547888897925840928),
(547889293968801827, 547888897925840928), (7, 547889293968801827, 547888897925840928),
(547889293968801828, 547888897925840928), (8, 547889293968801828, 547888897925840928),
(547889293968801829, 547888897925840928), (9, 547889293968801829, 547888897925840928),
(547889293968801830, 547888897925840928), (10, 547889293968801830, 547888897925840928),
(547889293968801831, 547888897925840928); (11, 547889293968801831, 547888897925840928);
-- 初始化默认角色和菜单关联数据 -- 初始化默认角色和菜单关联数据
INSERT INTO "sys_role_menu" INSERT INTO "sys_role_menu"

View File

@@ -197,10 +197,13 @@ COMMENT ON COLUMN "sys_user_social"."create_time" IS '创建时间';
COMMENT ON TABLE "sys_user_social" IS '用户社会化关联表'; COMMENT ON TABLE "sys_user_social" IS '用户社会化关联表';
CREATE TABLE IF NOT EXISTS "sys_user_role" ( CREATE TABLE IF NOT EXISTS "sys_user_role" (
"id" int8 NOT NULL,
"user_id" int8 NOT NULL, "user_id" int8 NOT NULL,
"role_id" int8 NOT NULL, "role_id" int8 NOT NULL,
PRIMARY KEY ("user_id", "role_id") PRIMARY KEY ("id")
); );
CREATE UNIQUE INDEX "uk_user_id_role_id" ON "sys_user_role" ("user_id", "role_id");
COMMENT ON COLUMN "sys_user_role"."id" IS 'ID';
COMMENT ON COLUMN "sys_user_role"."user_id" IS '用户ID'; COMMENT ON COLUMN "sys_user_role"."user_id" IS '用户ID';
COMMENT ON COLUMN "sys_user_role"."role_id" IS '角色ID'; COMMENT ON COLUMN "sys_user_role"."role_id" IS '角色ID';
COMMENT ON TABLE "sys_user_role" IS '用户和角色关联表'; COMMENT ON TABLE "sys_user_role" IS '用户和角色关联表';