package com.xiaopeng.operation.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.feignClient.account.SysGroupMenuClient; import com.xiaopeng.api.feignClient.account.SysRoleClient; import com.xiaopeng.api.feignClient.account.SysUserRoleClient; import com.xiaopeng.api.model.account.SysRole; import com.xiaopeng.api.model.account.SysUserRole; import com.xiaopeng.api.model.operation.SysMenu; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.security.service.TokenService; import com.xiaopeng.operation.mapper.SysMenuMapper; import com.xiaopeng.operation.service.ISysMenuService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; /** *

* 菜单权限表 服务实现类 *

* * @author mitao * @since 2026-02-03 */ @Slf4j @Service public class SysMenuServiceImpl extends ServiceImpl implements ISysMenuService { @Autowired private TokenService tokenService; @Autowired private SysUserRoleClient sysUserRoleClient; @Autowired private SysRoleClient sysRoleClient; @Autowired private SysGroupMenuClient sysGroupMenuClient; /** * 根据菜单ID列表查询菜单列表 * * @param menuIds 菜单ID列表 * @return 菜单列表 */ @Override public List selectMenusByMenuIds(List menuIds) { if (menuIds == null || menuIds.isEmpty()) { return new ArrayList<>(); } // 使用 MyBatis-Plus 的 listByIds 方法批量查询 return this.listByIds(menuIds); } @Override public List getMenuTree() { List all = list(); if (all == null || all.isEmpty()) { return Collections.emptyList(); } // 1) 按 parentId 分组(M/C/F 都先放进去,后面再按类型筛) Map> childrenMap = all.stream() .filter(Objects::nonNull) .collect(Collectors.groupingBy(m -> m.getParentId() == null ? 0L : m.getParentId())); // 2) 找到根目录:通常 parentId = 0 或 null 的目录(M) List roots = childrenMap.getOrDefault(0L, Collections.emptyList()).stream() .filter(m -> "M".equals(m.getMenuType())) .sorted(Comparator.comparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo))) .collect(Collectors.toList()); // 3) 递归挂载:M 下挂 C;C 下挂 F(也允许 C 下还有 C,或 M 下还有 M,按你的数据结构来) for (SysMenu root : roots) { fillChildren(root, childrenMap); } return roots; } private void fillChildren(SysMenu node, Map> childrenMap) { Long id = node.getId(); if (id == null) { node.setChildren(Collections.emptyList()); return; } List rawChildren = childrenMap.getOrDefault(id, Collections.emptyList()); if (rawChildren.isEmpty()) { node.setChildren(Collections.emptyList()); return; } // 根据你的层级规则过滤子节点: // - M 只能挂 M/C(看你业务,很多系统 M 下是 C) // - C 只能挂 F(按钮)或(有些系统 C 下还能挂 C) // - F 一般不挂任何子节点 String type = node.getMenuType(); List children = rawChildren.stream() .filter(Objects::nonNull) .filter(child -> { if ("M".equals(type)) { return "M".equals(child.getMenuType()) || "C".equals(child.getMenuType()); } if ("C".equals(type)) { return "F".equals(child.getMenuType()); // 若允许 C 下还有 C,可改为:return "C".equals(...) || "F".equals(...) } return false; // F 不再往下挂 }) .sorted(Comparator.comparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo))) .collect(Collectors.toList()); node.setChildren(children); // 继续递归 for (SysMenu child : children) { fillChildren(child, childrenMap); } } @Override public List getPermission() { try { // 1. 获取当前登录用户ID Long userId = tokenService.getLoginUser().getUserid(); if (userId == null) { log.warn("获取当前登录用户ID失败"); return Collections.emptyList(); } // 2. 查询用户角色关联 R userRoleResult = sysUserRoleClient.selectSysUserRoleByUserId(userId); if (userRoleResult == null || userRoleResult.getCode() != 200 || userRoleResult.getData() == null) { log.warn("查询用户角色关联失败, userId={}", userId); return Collections.emptyList(); } Long roleId = userRoleResult.getData().getRoleId(); if (roleId == null) { log.warn("用户未关联角色, userId={}", userId); return Collections.emptyList(); } // 3. 查询角色信息 R roleResult = sysRoleClient.getRoleById(roleId); if (roleResult == null || roleResult.getCode() != 200 || roleResult.getData() == null) { log.warn("查询角色信息失败, roleId={}", roleId); return Collections.emptyList(); } Long groupId = roleResult.getData().getGroupId(); if (groupId == null) { log.warn("角色未关联权限组, roleId={}", roleId); return Collections.emptyList(); } // 4. 查询权限组关联的菜单ID列表 R> menuIdsResult = sysGroupMenuClient.selectMenuIdsByGroupId(groupId); if (menuIdsResult == null || menuIdsResult.getCode() != 200 || menuIdsResult.getData() == null) { log.warn("查询权限组菜单ID列表失败, groupId={}", groupId); return Collections.emptyList(); } List menuIds = menuIdsResult.getData(); if (menuIds.isEmpty()) { log.info("权限组未关联菜单, groupId={}", groupId); return Collections.emptyList(); } // 5. 查询菜单详情 List menus = this.listByIds(menuIds); log.info("查询用户权限菜单成功, userId={}, menuCount={}", userId, menus.size()); return menus; } catch (Exception e) { log.error("查询用户权限菜单异常", e); return Collections.emptyList(); } } }