feat(system): 重构角色权限模块

- 移除 Authority 相关代码,改为使用 Menu 进行权限管理
- 重构 Role 和 RoleMenu 实体,以及相关 repository 和 service
- 更新菜单相关 API,增加菜单权限校验- 优化角色创建和编辑逻辑,支持菜单权限分配
- 更新 RoleVo 类,使用 Menu 替代 Authority
This commit is contained in:
zhuangtianxiang 2025-01-10 16:51:12 +08:00
parent 6bb8e7cefa
commit cde42f955d
13 changed files with 102 additions and 125 deletions

View File

@ -37,6 +37,7 @@ public class FirstTimeInitializer implements CommandLineRunner {
private final DeptRepository deptRepo;
private final PasswordEncoder passwordEncoder;
//TODO 初始化赋权给admin
@Override
public void run(String... args) {
// if (authorityService.count() == 0L) {

View File

@ -26,7 +26,7 @@ public class MenuController {
/**
* 获取菜单树
*/
@GetMapping("/menu")
@GetMapping
public List<MenuVo> menu(@AuthenticationPrincipal UserDetailsImpl userDetails) {
List<MenuVo> list = service.selectByUserId(userDetails.getId(), Menu.Type.PAGE).stream().map(MenuVo::new).toList();
return TreeUtil.makeTree(
@ -40,16 +40,16 @@ public class MenuController {
/**
* 新建菜单
*/
@PostMapping("")
public Menu create(MenuDto dto) {
@PostMapping
public Menu create(@RequestBody MenuDto dto) {
return service.create(dto);
}
/**
* 更新菜单
*/
@PatchMapping("")
public Menu update(MenuDto dto, Long id) {
@PatchMapping("/{id}")
public Menu update(@RequestBody MenuDto dto, @PathVariable("id") Long id) {
return service.update(dto, id);
}
@ -57,7 +57,7 @@ public class MenuController {
* 删除菜单
*/
@DeleteMapping("/{id}")
public Boolean delete(@PathVariable Long id) {
public Boolean delete(@PathVariable("id") Long id) {
return service.delete(id);
}
}

View File

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.gateway.modules.system.dto.AuthorityCreateDto;
//import com.zsc.edu.gateway.modules.system.dto.RoleAuthCreateDto;
import com.zsc.edu.gateway.modules.system.dto.RoleDto;
import com.zsc.edu.gateway.modules.system.entity.Authority;
import com.zsc.edu.gateway.modules.system.entity.Role;
import com.zsc.edu.gateway.modules.system.query.RoleQuery;
import com.zsc.edu.gateway.modules.system.service.RoleAuthService;
@ -28,7 +27,6 @@ public class RoleController {
private final RoleService service;
private final RoleAuthService roleAuthService;
/**
* 返回所有角色列表 hasAuthority('SYSTEM:ROLE:QUERY')
@ -49,9 +47,8 @@ public class RoleController {
*/
@PostMapping
@PreAuthorize("hasAuthority('system:role:create')")
public Boolean create(@RequestBody RoleDto dto) {
Role role= service.create(dto);
return role != null;
public Role create(@RequestBody RoleDto dto) {
return service.create(dto);
}
/**
@ -63,9 +60,7 @@ public class RoleController {
*/
@PatchMapping("{id}")
@PreAuthorize("hasAuthority('system:role:update')")
public Boolean update(@RequestBody RoleDto dto, @PathVariable("id") Long id) {
// Role role = roleMapper.toEntity(dto);
// role.setId(id);
public Role update(@RequestBody RoleDto dto, @PathVariable("id") Long id) {
return service.edit(dto, id);
}
@ -105,15 +100,5 @@ public class RoleController {
return service.delete(id);
}
/**
* 为角色添加权限 hasAuthority('SYSTEM:ROLE:AUTHED')
*
* @return RoleAuthority 新的角色权限
*/
@PostMapping("/saveAuth/{id}")
@PreAuthorize("hasAuthority('system:role:create')")
public Boolean addAuthed(@PathVariable Long id, @RequestBody Set<AuthorityCreateDto> authorities) {
return service.saveRoleAuths(id,authorities);
}
}

View File

@ -1,6 +1,7 @@
package com.zsc.edu.gateway.modules.system.dto;
import com.zsc.edu.gateway.modules.system.entity.Menu;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -13,7 +14,7 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class MenuDto {
/**
* 子部门ID
* 父菜单ID
*/
private Long pid;
/**
@ -23,6 +24,7 @@ public class MenuDto {
/**
* 名称
*/
@NotBlank(message = "名字不能为空")
private String name;
/**
* 路径
@ -52,8 +54,4 @@ public class MenuDto {
* 权限
*/
private String permissions;
/**
* 权限标识
*/
private String authority = "";
}

View File

@ -35,7 +35,7 @@ public class RoleDto {
/**
* 权限列表
*/
public Set<AuthorityCreateDto> authorities;
public Set<Long> menuIds;
}

View File

@ -27,6 +27,4 @@ public class RoleMenu implements Serializable {
*/
private Long menuId;
// @TableField(exist = false)
// private Set<Authority> authorities;
}

View File

@ -16,7 +16,6 @@ public interface MenuRepository extends BaseMapper<Menu> {
List<Menu> selectByRoleId(Long roleId);
List<Menu> selectByUserId(Long userId, Menu.Type type);
}

View File

@ -7,5 +7,4 @@ import com.zsc.edu.gateway.modules.system.entity.RoleMenu;
* @author Yao
*/
public interface RoleMenuRepository extends BaseMapper<RoleMenu> {
}

View File

@ -1,14 +1,10 @@
package com.zsc.edu.gateway.modules.system.service;
import com.zsc.edu.gateway.modules.system.dto.AuthorityCreateDto;
import com.zsc.edu.gateway.modules.system.dto.RoleDto;
import com.zsc.edu.gateway.modules.system.entity.Authority;
import com.zsc.edu.gateway.modules.system.entity.Role;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.gateway.modules.system.vo.RoleVo;
import java.util.Set;
/**
* <p>
* 角色表 服务类
@ -21,7 +17,7 @@ public interface RoleService extends IService<Role> {
Role create(RoleDto roleDto);
Boolean edit(RoleDto roleDto, Long id);
Role edit(RoleDto roleDto, Long id);
RoleVo detail(Long id);
@ -29,5 +25,4 @@ public interface RoleService extends IService<Role> {
Boolean delete(Long id);
Boolean saveRoleAuths(Long roleId, Set<AuthorityCreateDto> authorities);
}

View File

@ -35,6 +35,12 @@ public class MenuServiceImpl extends ServiceImpl<MenuRepository, Menu> implement
@Override
public Menu create(MenuDto dto) {
if (baseMapper.selectList(new LambdaQueryWrapper<Menu>().eq(Menu::getName, dto.getName())) != null) {
throw new ConstraintException("该菜单名已存在!请检查输入表单是否出错!");
}
if (baseMapper.selectList(new LambdaQueryWrapper<Menu>().eq(Menu::getPermissions, dto.getPermissions())) != null) {
throw new ConstraintException("该权限已存在!请检查输入表单是否出错!");
}
Menu menu = mapper.toEntity(dto);
baseMapper.insert(menu);
return menu;

View File

@ -1,17 +1,12 @@
package com.zsc.edu.gateway.modules.system.service.impl;
import com.zsc.edu.gateway.exception.ConstraintException;
import com.zsc.edu.gateway.modules.system.dto.AuthorityCreateDto;
import com.zsc.edu.gateway.modules.system.dto.RoleDto;
import com.zsc.edu.gateway.modules.system.entity.Authority;
import com.zsc.edu.gateway.modules.system.entity.Role;
import com.zsc.edu.gateway.modules.system.entity.RoleAuthority;
import com.zsc.edu.gateway.modules.system.entity.UserRole;
import com.zsc.edu.gateway.modules.system.entity.*;
import com.zsc.edu.gateway.modules.system.mapper.RoleMapper;
import com.zsc.edu.gateway.modules.system.repo.AuthorityRepository;
import com.zsc.edu.gateway.modules.system.repo.RoleMenuRepository;
import com.zsc.edu.gateway.modules.system.repo.RoleRepository;
import com.zsc.edu.gateway.modules.system.repo.UserRolesRepository;
import com.zsc.edu.gateway.modules.system.service.RoleAuthService;
import com.zsc.edu.gateway.modules.system.service.RoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -19,10 +14,7 @@ import com.zsc.edu.gateway.modules.system.vo.RoleVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
@ -40,8 +32,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleRepository, Role> implement
private final RoleMapper mapper;
private final UserRolesRepository urRepo;
private final RoleAuthService roleAuthService;
private final AuthorityRepository authorityRepository;
private final RoleMenuRepository roleMenuRepository;
private final RoleRepository roleRepository;
@Override
@ -50,9 +41,15 @@ public class RoleServiceImpl extends ServiceImpl<RoleRepository, Role> implement
if (existsByName) {
throw new ConstraintException("name", dto.name, "角色已存在");
}
Role role = mapper.toEntity(dto);
Role role = new Role();
role.setName(dto.getName());
role.setRemark(dto.getRemark());
save(role);
// saveRoleAuths(role.getId(), role.getAuthorities());
if (dto.getMenuIds() != null) {
roleMenuRepository.insert(
dto.getMenuIds().stream()
.map(menuId -> new RoleMenu(role.getId(), menuId)).collect(Collectors.toList()));
}
return role;
}
@ -69,46 +66,37 @@ public class RoleServiceImpl extends ServiceImpl<RoleRepository, Role> implement
if (hasUser) {
throw new ConstraintException("存在与本角色绑定的用户,请先删除用户");
}
// 删除角色权限关联关系
roleAuthService.removeByRoleId(id);
roleMenuRepository.delete(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId, id));
return removeById(id);
}
@Override
public Boolean edit(RoleDto dto, Long id) {
Role existingRole = getById(id);
if (existingRole == null) {
public Role edit(RoleDto dto, Long id) {
Role selectyRole = getById(id);
if (selectyRole == null) {
throw new ConstraintException("id", id.toString(), "角色不存在");
}
if (!Objects.equals(existingRole.getName(), dto.getName()) &&
if (!Objects.equals(selectyRole.getName(), dto.getName()) &&
count(new LambdaQueryWrapper<Role>().eq(Role::getName, dto.getName())) > 0) {
throw new ConstraintException("name", dto.getName(), "同名角色已存在");
}
mapper.convert(dto, existingRole);
if (existingRole.getAuthorities() != null) {
roleAuthService.remove(new LambdaQueryWrapper<RoleAuthority>().eq(RoleAuthority::getRoleId, id));
saveRoleAuths(id, dto.getAuthorities());
Role role = new Role();
role.setName(dto.getName());
role.setRemark(dto.getRemark());
updateById(role);
if (dto.getMenuIds() != null) {
roleMenuRepository.delete(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId, id));
roleMenuRepository.insert(
dto.getMenuIds().stream()
.map(menuId -> new RoleMenu(id, menuId)).collect(Collectors.toList()));
}
return updateById(existingRole);
return role;
}
@Override
public RoleVo detail(Long id) {
// Role role = getById(id);
// // List<RoleAuthority> roleAuthorities = roleAuthService.list(new LambdaQueryWrapper<RoleAuthority>().eq(RoleAuthority::getRoleId, role.id));
// role.authorities = authorityRepository.selectAuthoritiesByRoleId(role.id);
return roleRepository.selectRoleById(id);
}
@Override
public Boolean saveRoleAuths(Long roleId, Set<AuthorityCreateDto> authorities) {
// 保存角色关联权限
List<RoleAuthority> roleAuthorities = authorities.stream()
.map(authority ->
new RoleAuthority(roleId, authorityRepository.getAuthorityIdByName(authority.getName())))
.collect(Collectors.toList());
return roleAuthService.saveBatch(roleAuthorities);
}
}

View File

@ -1,60 +1,65 @@
package com.zsc.edu.gateway.modules.system.vo;
import com.zsc.edu.gateway.modules.system.entity.Authority;
import com.zsc.edu.gateway.modules.system.entity.Menu;
import lombok.Data;
import java.util.Date;
import java.util.List;
import java.time.LocalDateTime;
import java.util.Set;
/**
* @author lenovo
* @author zhuang
*/
@Data
public class RoleVo {
/**
* 自增主键
*/
public Long id;
/**
* 角色
* 唯一
*/
private String name;
/**
*级别
*/
private Integer level;
/**
* 描述
*/
private String description;
/**
* 数据权限
*/
private String dataScope;
/**
* 创建人
*/
private String createBy;
/**
* 更新人
*/
private String updateBy;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
public String name;
/**
* 启用状态
*/
private Boolean enabled;
/**
* 备注
*/
private String remark;
private Boolean enabled = true;
private List<Authority> authorities;
/**
* 部门ID(权限)
*/
public Long deptId;
/**
* 备注说明
*/
public String roleRemark;
/**
* 创建时间
*/
public LocalDateTime createTime;
/*
* 创建人
*
*/
public String createBy;
/**
* 更新时间
*/
public LocalDateTime updateTime;
/*
* 更新人
*
* */
public String updateBy;
/**
* 权限集合
*/
public Set<Menu> menus;
}

View File

@ -9,20 +9,23 @@
<result column="create_time" jdbcType="DATE" property="createTime"/>
<result column="update_time" jdbcType="DATE" property="updateTime"/>
<result column="enabled" jdbcType="BIT" property="enabled"/>
<result column="remark" jdbcType="VARCHAR" property="remark"/>
<collection property="authorities" ofType="com.zsc.edu.gateway.modules.system.entity.Authority" autoMapping="true" columnPrefix="authority_">
<result column="remark" jdbcType="VARCHAR" property="roleRemark"/>
<collection property="menus" ofType="com.zsc.edu.gateway.modules.system.entity.Menu" autoMapping="true"
columnPrefix="menu_">
<id column="id" jdbcType="BIT" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="permissions" jdbcType="VARCHAR" property="permissions"/>
<result column="remark" jdbcType="VARCHAR" property="remark"/>
</collection>
</resultMap>
<select id="selectRoleById" resultMap="roleMap">
select sr.*,
sa.id as authority_id, sa.name as authority_name, sa.enabled as authority_enabled,sa.remark as authority_remark,sa.create_by as authority_create_by,sa.create_time as authority_create_time,sa.update_by as authority_update_by,sa.update_time as authority_update_time
sm.id AS menu_id,
sm.permissions AS menu_permissions,
sm.remark AS menu_remark
from sys_role sr
left join sys_role_authorities sra on sr.id=sra.role_id
left join sys_authority sa on sra.authority_id=sa.id
left join sys_role_menu srm on sr.id = srm.role_id
left join sys_menu sm on srm.menu_id = sm.id
where sr.id=#{roleId}
</select>