增加权限点

This commit is contained in:
dengqichen 2025-11-01 12:57:31 +08:00
parent 33282d9229
commit 95e66480a2
8 changed files with 150 additions and 65 deletions

View File

@ -6,7 +6,6 @@ import com.qqchen.deploy.backend.framework.controller.BaseController;
import com.qqchen.deploy.backend.framework.security.annotation.PermissionPrefix;
import com.qqchen.deploy.backend.system.model.MenuDTO;
import com.qqchen.deploy.backend.system.model.query.MenuQuery;
import com.qqchen.deploy.backend.system.model.response.MenuPermissionTreeResponse;
import com.qqchen.deploy.backend.system.model.response.MenuResponse;
import com.qqchen.deploy.backend.system.service.IMenuService;
import io.swagger.v3.oas.annotations.Operation;
@ -45,12 +44,6 @@ public class MenuApiController extends BaseController<Menu, MenuDTO, Long, MenuQ
return Response.success(menuService.getMenuTree());
}
@Operation(summary = "获取菜单树")
@GetMapping("/permission-tree")
public Response<List<MenuPermissionTreeResponse>> getPermissionTree() {
return Response.success(menuService.getPermissionTree());
}
@Override
protected void exportData(HttpServletResponse response, List<MenuDTO> data) {

View File

@ -7,6 +7,8 @@ import com.qqchen.deploy.backend.framework.security.annotation.PermissionPrefix;
import com.qqchen.deploy.backend.system.model.PermissionDTO;
import com.qqchen.deploy.backend.system.model.RoleDTO;
import com.qqchen.deploy.backend.system.model.query.RoleQuery;
import com.qqchen.deploy.backend.system.model.response.MenuPermissionTreeResponse;
import com.qqchen.deploy.backend.system.service.IMenuService;
import com.qqchen.deploy.backend.system.service.IRoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@ -25,6 +27,15 @@ public class RoleApiController extends BaseController<Role, RoleDTO, Long, RoleQ
@Resource
private IRoleService roleService;
@Resource
private IMenuService menuService;
@Operation(summary = "获取菜单权限树")
@GetMapping("/permission-tree")
public Response<List<MenuPermissionTreeResponse>> getPermissionTree() {
return Response.success(menuService.getPermissionTree());
}
@Operation(summary = "分配标签")
@PostMapping("/{id}/tags")
public Response<Void> assignTags(@PathVariable Long id, @RequestBody List<Long> tagIds) {

View File

@ -6,9 +6,6 @@ import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.HashSet;
import java.util.Set;
@Data
@EqualsAndHashCode(callSuper = true)
@jakarta.persistence.Entity
@ -37,15 +34,6 @@ public class Permission extends Entity<Long> {
@Column(length = 200)
private String description;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "sys_template_menu",
joinColumns = @JoinColumn(name = "template_id"),
inverseJoinColumns = @JoinColumn(name = "menu_id")
)
private Set<Menu> menus = new HashSet<>();
// 不使用 JPA 关系映射,改用原生 SQL 查询
// @ManyToMany(mappedBy = "permissions", fetch = FetchType.LAZY)
// private Set<Role> roles = new HashSet<>();
// 通过 PermissionService 中的原生SQL查询 sys_role_permission 表获取关联的角色列表
}

View File

@ -2,16 +2,9 @@ package com.qqchen.deploy.backend.system.entity;
import com.qqchen.deploy.backend.framework.domain.Entity;
import jakarta.persistence.Column;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table;
import lombok.Data;
import java.util.HashSet;
import java.util.Set;
/**
* 权限模板实体
*/
@ -48,14 +41,6 @@ public class PermissionTemplate extends Entity<Long> {
*/
private Boolean enabled;
/**
* 模板包含的菜单列表
*/
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "sys_template_menu",
joinColumns = @JoinColumn(name = "template_id"),
inverseJoinColumns = @JoinColumn(name = "menu_id")
)
private Set<Menu> menus = new HashSet<>();
// 不使用 JPA 关系映射改用原生 SQL 查询
// 通过 PermissionTemplateService 中的原生SQL查询 sys_template_menu 表获取关联的菜单列表
}

View File

@ -16,5 +16,8 @@ public class PermissionDTO extends BaseDTO {
private Integer sort;
private String menuName; // 关联的菜单名称
/**
* 关联的菜单信息
*/
private MenuDTO menu;
}

View File

@ -1,10 +1,12 @@
package com.qqchen.deploy.backend.system.service.impl;
import com.qqchen.deploy.backend.system.converter.MenuConverter;
import com.qqchen.deploy.backend.system.converter.PermissionConverter;
import com.qqchen.deploy.backend.system.entity.Menu;
import com.qqchen.deploy.backend.system.entity.Permission;
import com.qqchen.deploy.backend.framework.annotation.ServiceType;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.system.model.MenuDTO;
import com.qqchen.deploy.backend.system.model.PermissionDTO;
import com.qqchen.deploy.backend.system.model.query.PermissionQuery;
import com.qqchen.deploy.backend.system.repository.IMenuRepository;
@ -12,6 +14,8 @@ import com.qqchen.deploy.backend.system.repository.IPermissionRepository;
import com.qqchen.deploy.backend.system.service.IPermissionService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import java.util.List;
@ -34,38 +38,98 @@ public class PermissionServiceImpl extends BaseServiceImpl<Permission, Permissio
@Resource
private PermissionConverter permissionConverter;
@Resource
private MenuConverter menuConverter;
/**
* 覆盖单体查询方法添加菜单信息
*/
@Override
public PermissionDTO findById(Long id) {
PermissionDTO dto = super.findById(id);
if (dto != null && dto.getMenuId() != null) {
menuRepository.findById(dto.getMenuId()).ifPresent(menu ->
dto.setMenu(menuConverter.toDto(menu))
);
}
return dto;
}
/**
* 覆盖分页查询方法添加菜单信息
*/
@Override
public Page<PermissionDTO> page(PermissionQuery query) {
// 调用父类方法获取分页数据
Page<PermissionDTO> page = super.page(query);
// 填充菜单信息
enrichWithMenuInfo(page.getContent());
return page;
}
/**
* 覆盖列表查询方法添加菜单信息
*/
@Override
public List<PermissionDTO> findAll(PermissionQuery query) {
List<PermissionDTO> list = super.findAll(query);
enrichWithMenuInfo(list);
return list;
}
@Override
public List<PermissionDTO> listAllEnabled() {
List<Permission> permissions = permissionRepository.findAllEnabledOrderByMenuAndSort();
List<Long> menuIds = permissions.stream().map(Permission::getMenuId).distinct().collect(Collectors.toList());
Map<Long, String> menuNameMap = menuRepository.findAllById(menuIds).stream()
.collect(Collectors.toMap(Menu::getId, Menu::getName));
return permissions.stream().map(p -> convertToDTO(p, menuNameMap.get(p.getMenuId())))
.collect(Collectors.toList());
List<PermissionDTO> dtoList = permissionConverter.toDtoList(permissions);
enrichWithMenuInfo(dtoList);
return dtoList;
}
@Override
public List<PermissionDTO> listByMenuId(Long menuId) {
List<Permission> permissions = permissionRepository.findByMenuIdAndEnabledTrue(menuId);
String menuName = menuRepository.findById(menuId).map(Menu::getName).orElse(null);
return permissions.stream().map(p -> convertToDTO(p, menuName)).collect(Collectors.toList());
List<PermissionDTO> dtoList = permissionConverter.toDtoList(permissions);
enrichWithMenuInfo(dtoList);
return dtoList;
}
@Override
public List<PermissionDTO> listByIds(List<Long> ids) {
List<Permission> permissions = permissionRepository.findByIdIn(ids);
List<Long> menuIds = permissions.stream().map(Permission::getMenuId).distinct().collect(Collectors.toList());
Map<Long, String> menuNameMap = menuRepository.findAllById(menuIds).stream()
.collect(Collectors.toMap(Menu::getId, Menu::getName));
List<PermissionDTO> dtoList = permissionConverter.toDtoList(permissions);
enrichWithMenuInfo(dtoList);
return dtoList;
}
return permissions.stream().map(p -> convertToDTO(p, menuNameMap.get(p.getMenuId())))
/**
* 为权限DTO列表填充菜单信息
*/
private void enrichWithMenuInfo(List<PermissionDTO> permissionDTOs) {
if (permissionDTOs == null || permissionDTOs.isEmpty()) {
return;
}
// 收集所有菜单ID
List<Long> menuIds = permissionDTOs.stream()
.map(PermissionDTO::getMenuId)
.filter(id -> id != null)
.distinct()
.collect(Collectors.toList());
if (menuIds.isEmpty()) {
return;
}
private PermissionDTO convertToDTO(Permission permission, String menuName) {
PermissionDTO dto = permissionConverter.toDto(permission);
dto.setMenuName(menuName);
return dto;
// 批量查询菜单并转换为DTO
Map<Long, MenuDTO> menuMap = menuRepository.findAllById(menuIds).stream()
.map(menuConverter::toDto)
.collect(Collectors.toMap(MenuDTO::getId, menu -> menu));
// 填充菜单信息
permissionDTOs.forEach(dto -> {
if (dto.getMenuId() != null) {
dto.setMenu(menuMap.get(dto.getMenuId()));
}
});
}
}

View File

@ -1,5 +1,6 @@
package com.qqchen.deploy.backend.system.service.impl;
import com.qqchen.deploy.backend.system.converter.MenuConverter;
import com.qqchen.deploy.backend.system.converter.PermissionConverter;
import com.qqchen.deploy.backend.system.entity.Menu;
import com.qqchen.deploy.backend.system.entity.Permission;
@ -10,6 +11,7 @@ import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.exception.UniqueConstraintException;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.system.model.MenuDTO;
import com.qqchen.deploy.backend.system.model.PermissionDTO;
import com.qqchen.deploy.backend.system.model.RoleDTO;
import com.qqchen.deploy.backend.system.model.query.RoleQuery;
@ -28,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@ -56,6 +59,9 @@ public class RoleServiceImpl extends BaseServiceImpl<Role, RoleDTO, RoleQuery, L
@Resource
private PermissionConverter permissionConverter;
@Resource
private MenuConverter menuConverter;
@Resource
private IPermissionRepository permissionRepository;
@ -137,16 +143,46 @@ public class RoleServiceImpl extends BaseServiceImpl<Role, RoleDTO, RoleQuery, L
Role role = roleRepository.findById(roleId)
.orElseThrow(() -> new BusinessException(ResponseCode.ROLE_NOT_FOUND));
return role.getPermissions().stream()
.map(permission -> {
PermissionDTO dto = permissionConverter.toDto(permission);
String menuName = menuRepository.findById(permission.getMenuId())
.map(Menu::getName)
.orElse(null);
dto.setMenuName(menuName);
return dto;
})
List<PermissionDTO> permissionDTOs = role.getPermissions().stream()
.map(permissionConverter::toDto)
.collect(Collectors.toList());
// 批量填充菜单信息
enrichWithMenuInfo(permissionDTOs);
return permissionDTOs;
}
/**
* 为权限DTO列表批量填充菜单信息
*/
private void enrichWithMenuInfo(List<PermissionDTO> permissionDTOs) {
if (permissionDTOs == null || permissionDTOs.isEmpty()) {
return;
}
// 收集所有菜单ID
List<Long> menuIds = permissionDTOs.stream()
.map(PermissionDTO::getMenuId)
.filter(id -> id != null)
.distinct()
.collect(Collectors.toList());
if (menuIds.isEmpty()) {
return;
}
// 批量查询菜单并转换为DTO
Map<Long, MenuDTO> menuMap = menuRepository.findAllById(menuIds).stream()
.map(menuConverter::toDto)
.collect(Collectors.toMap(MenuDTO::getId, menu -> menu));
// 填充菜单信息
permissionDTOs.forEach(dto -> {
if (dto.getMenuId() != null) {
dto.setMenu(menuMap.get(dto.getMenuId()));
}
});
}
@Override

View File

@ -159,6 +159,11 @@ INSERT INTO sys_permission (id, create_time, menu_id, code, name, type, sort) VA
(13, NOW(), 3, 'system:role:create', '角色创建', 'FUNCTION', 3),
(14, NOW(), 3, 'system:role:update', '角色修改', 'FUNCTION', 4),
(15, NOW(), 3, 'system:role:delete', '角色删除', 'FUNCTION', 5),
(16, NOW(), 3, 'system:role:permission-tree', '获取权限树', 'FUNCTION', 6),
(17, NOW(), 3, 'system:role:assign-tags', '分配标签', 'FUNCTION', 7),
(18, NOW(), 3, 'system:role:assign-roles', '分配角色', 'FUNCTION', 8),
(19, NOW(), 3, 'system:role:get-permissions', '获取角色权限', 'FUNCTION', 9),
(20, NOW(), 3, 'system:role:assign-permissions', '分配权限', 'FUNCTION', 10),
-- 菜单管理 (menu_id=4)
(21, NOW(), 4, 'system:menu:list', '菜单查询', 'FUNCTION', 1),