diff --git a/backend/src/main/java/com/qqchen/deploy/backend/system/api/MenuApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/system/api/MenuApiController.java index 6f84e905..13e64702 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/system/api/MenuApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/system/api/MenuApiController.java @@ -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> getPermissionTree() { - return Response.success(menuService.getPermissionTree()); - } - @Override protected void exportData(HttpServletResponse response, List data) { diff --git a/backend/src/main/java/com/qqchen/deploy/backend/system/api/RoleApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/system/api/RoleApiController.java index 51a98b9b..af1119f4 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/system/api/RoleApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/system/api/RoleApiController.java @@ -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> getPermissionTree() { + return Response.success(menuService.getPermissionTree()); + } + @Operation(summary = "分配标签") @PostMapping("/{id}/tags") public Response assignTags(@PathVariable Long id, @RequestBody List tagIds) { diff --git a/backend/src/main/java/com/qqchen/deploy/backend/system/entity/Permission.java b/backend/src/main/java/com/qqchen/deploy/backend/system/entity/Permission.java index 0a525788..1ca0d231 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/system/entity/Permission.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/system/entity/Permission.java @@ -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 { @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 menus = new HashSet<>(); - // 不使用 JPA 关系映射,改用原生 SQL 查询 - // @ManyToMany(mappedBy = "permissions", fetch = FetchType.LAZY) - // private Set roles = new HashSet<>(); + // 通过 PermissionService 中的原生SQL查询 sys_role_permission 表获取关联的角色列表 } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/system/entity/PermissionTemplate.java b/backend/src/main/java/com/qqchen/deploy/backend/system/entity/PermissionTemplate.java index abc8db58..9d747b69 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/system/entity/PermissionTemplate.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/system/entity/PermissionTemplate.java @@ -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 { */ private Boolean enabled; - /** - * 模板包含的菜单列表 - */ - @ManyToMany(fetch = FetchType.LAZY) - @JoinTable( - name = "sys_template_menu", - joinColumns = @JoinColumn(name = "template_id"), - inverseJoinColumns = @JoinColumn(name = "menu_id") - ) - private Set menus = new HashSet<>(); + // 不使用 JPA 关系映射,改用原生 SQL 查询 + // 通过 PermissionTemplateService 中的原生SQL查询 sys_template_menu 表获取关联的菜单列表 } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/system/model/PermissionDTO.java b/backend/src/main/java/com/qqchen/deploy/backend/system/model/PermissionDTO.java index 1b488c0a..8b915c97 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/system/model/PermissionDTO.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/system/model/PermissionDTO.java @@ -16,5 +16,8 @@ public class PermissionDTO extends BaseDTO { private Integer sort; - private String menuName; // 关联的菜单名称 + /** + * 关联的菜单信息 + */ + private MenuDTO menu; } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/system/service/impl/PermissionServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/system/service/impl/PermissionServiceImpl.java index 4c93b373..60496aee 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/system/service/impl/PermissionServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/system/service/impl/PermissionServiceImpl.java @@ -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 + dto.setMenu(menuConverter.toDto(menu)) + ); + } + return dto; + } + + /** + * 覆盖分页查询方法,添加菜单信息 + */ + @Override + public Page page(PermissionQuery query) { + // 调用父类方法获取分页数据 + Page page = super.page(query); + // 填充菜单信息 + enrichWithMenuInfo(page.getContent()); + return page; + } + + /** + * 覆盖列表查询方法,添加菜单信息 + */ + @Override + public List findAll(PermissionQuery query) { + List list = super.findAll(query); + enrichWithMenuInfo(list); + return list; + } + @Override public List listAllEnabled() { List permissions = permissionRepository.findAllEnabledOrderByMenuAndSort(); - List menuIds = permissions.stream().map(Permission::getMenuId).distinct().collect(Collectors.toList()); - Map 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 dtoList = permissionConverter.toDtoList(permissions); + enrichWithMenuInfo(dtoList); + return dtoList; } @Override public List listByMenuId(Long menuId) { List 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 dtoList = permissionConverter.toDtoList(permissions); + enrichWithMenuInfo(dtoList); + return dtoList; } @Override public List listByIds(List ids) { List permissions = permissionRepository.findByIdIn(ids); - List menuIds = permissions.stream().map(Permission::getMenuId).distinct().collect(Collectors.toList()); - Map 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 dtoList = permissionConverter.toDtoList(permissions); + enrichWithMenuInfo(dtoList); + return dtoList; } - private PermissionDTO convertToDTO(Permission permission, String menuName) { - PermissionDTO dto = permissionConverter.toDto(permission); - dto.setMenuName(menuName); - return dto; + /** + * 为权限DTO列表填充菜单信息 + */ + private void enrichWithMenuInfo(List permissionDTOs) { + if (permissionDTOs == null || permissionDTOs.isEmpty()) { + return; + } + + // 收集所有菜单ID + List menuIds = permissionDTOs.stream() + .map(PermissionDTO::getMenuId) + .filter(id -> id != null) + .distinct() + .collect(Collectors.toList()); + + if (menuIds.isEmpty()) { + return; + } + + // 批量查询菜单并转换为DTO + Map 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())); + } + }); } } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/system/service/impl/RoleServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/system/service/impl/RoleServiceImpl.java index affffeb2..54b2dafc 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/system/service/impl/RoleServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/system/service/impl/RoleServiceImpl.java @@ -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 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 permissionDTOs = role.getPermissions().stream() + .map(permissionConverter::toDto) .collect(Collectors.toList()); + + // 批量填充菜单信息 + enrichWithMenuInfo(permissionDTOs); + + return permissionDTOs; + } + + /** + * 为权限DTO列表批量填充菜单信息 + */ + private void enrichWithMenuInfo(List permissionDTOs) { + if (permissionDTOs == null || permissionDTOs.isEmpty()) { + return; + } + + // 收集所有菜单ID + List menuIds = permissionDTOs.stream() + .map(PermissionDTO::getMenuId) + .filter(id -> id != null) + .distinct() + .collect(Collectors.toList()); + + if (menuIds.isEmpty()) { + return; + } + + // 批量查询菜单并转换为DTO + Map 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 diff --git a/backend/src/main/resources/db/changelog/changes/v1.0.0-data.sql b/backend/src/main/resources/db/changelog/changes/v1.0.0-data.sql index 92da7c45..caa2de95 100644 --- a/backend/src/main/resources/db/changelog/changes/v1.0.0-data.sql +++ b/backend/src/main/resources/db/changelog/changes/v1.0.0-data.sql @@ -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),