From d01f99eafc417c56c20d2cf34564d2dd3b12cb91 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期六, 07 三月 2026 21:01:45 +0800
Subject: [PATCH] 同步最新代码

---
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/SysMenuServiceImpl.java |  144 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 142 insertions(+), 2 deletions(-)

diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/SysMenuServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/SysMenuServiceImpl.java
index 38b26a9..8cc9b6b 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/SysMenuServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/SysMenuServiceImpl.java
@@ -4,8 +4,10 @@
 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.feignClient.account.XpOperationsRoleClient;
 import com.xiaopeng.api.model.account.SysRole;
 import com.xiaopeng.api.model.account.SysUserRole;
+import com.xiaopeng.api.model.account.XpOperationsRole;
 import com.xiaopeng.api.model.operation.SysMenu;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.security.service.TokenService;
@@ -42,6 +44,9 @@
     @Autowired
     private SysGroupMenuClient sysGroupMenuClient;
 
+    @Autowired
+    private XpOperationsRoleClient xpOperationsRoleClient;
+
     /**
      * 根据菜单ID列表查询菜单列表
      *
@@ -59,8 +64,8 @@
     }
 
     @Override
-    public List<SysMenu> getMenuTree() {
-        List<SysMenu> all = list();
+    public List<SysMenu> getMenuTree(Integer type) {
+        List<SysMenu> all = lambdaQuery().eq(SysMenu::getGroupType, type).list();
         if (all == null || all.isEmpty()) {
             return Collections.emptyList();
         }
@@ -184,4 +189,139 @@
             return Collections.emptyList();
         }
     }
+
+    @Override
+    public List<SysMenu> getAppPermission() {
+        // 1. 获取当前登录用户ID
+        Long operationUserId = tokenService.getLoginOperationUser().getId();
+        if (operationUserId == null) {
+            log.warn("获取当前登录用户ID失败");
+            return Collections.emptyList();
+        }
+
+        // 2. 查询运维APP菜单(group_type=2)
+        List<SysMenu> appMenus = this.lambdaQuery()
+                .eq(SysMenu::getGroupType, 2)
+                .list();
+        if (appMenus == null || appMenus.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        // 3. 查询运维人员关联的角色(一个用户可多个角色)
+        Set<Long> roleIds = new HashSet<>();
+        try {
+            R<List<XpOperationsRole>> rolesResult = xpOperationsRoleClient.listByOperationUserId(operationUserId);
+            if (rolesResult != null && rolesResult.getData() != null) {
+                for (XpOperationsRole r : rolesResult.getData()) {
+                    if (r != null && r.getRoleId() != null) {
+                        roleIds.add(r.getRoleId());
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("查询运维人员角色关联异常, operationUserId={}", operationUserId, e);
+        }
+
+        // 4. 通过 role -> groupId -> group_menu 获取允许的菜单ID集合
+        Set<Long> allowedMenuIds = new HashSet<>();
+        if (!roleIds.isEmpty()) {
+            Set<Long> groupIds = new HashSet<>();
+            for (Long roleId : roleIds) {
+                try {
+                    R<SysRole> roleResult = sysRoleClient.getRoleById(roleId);
+                    if (roleResult != null && roleResult.getData() != null && roleResult.getData().getGroupId() != null) {
+                        groupIds.add(roleResult.getData().getGroupId());
+                    }
+                } catch (Exception e) {
+                    log.error("查询角色信息异常, roleId={}", roleId, e);
+                }
+            }
+
+            for (Long groupId : groupIds) {
+                try {
+                    R<List<Long>> menuIdsResult = sysGroupMenuClient.selectMenuIdsByGroupId(groupId);
+                    if (menuIdsResult != null && menuIdsResult.getData() != null) {
+                        allowedMenuIds.addAll(menuIdsResult.getData());
+                    }
+                } catch (Exception e) {
+                    log.error("查询权限组菜单ID异常, groupId={}", groupId, e);
+                }
+            }
+        }
+
+        // 5. 仅保留运维APP的菜单ID,避免无关ID影响 visible
+        Set<Long> appMenuIds = appMenus.stream()
+                .filter(Objects::nonNull)
+                .map(SysMenu::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+        allowedMenuIds.retainAll(appMenuIds);
+
+        // 6. 组装树形结构,并用 visible 体现权限可见性(0可见 1不可见)
+        return buildAppMenuTreeWithVisible(appMenus, allowedMenuIds);
+    }
+
+    private List<SysMenu> buildAppMenuTreeWithVisible(List<SysMenu> menus, Set<Long> allowedMenuIds) {
+        Map<Long, SysMenu> idMap = new HashMap<>();
+        for (SysMenu m : menus) {
+            if (m != null && m.getId() != null) {
+                idMap.put(m.getId(), m);
+            }
+        }
+
+        Map<Long, List<SysMenu>> childrenMap = menus.stream()
+                .filter(Objects::nonNull)
+                .filter(m -> m.getId() != null)
+                .collect(Collectors.groupingBy(m -> {
+                    Long pid = m.getParentId();
+                    return pid == null ? 0L : pid;
+                }));
+
+        // 根节点:parentId 为 0/null,或父节点不在当前 group_type=2 集合内
+        List<SysMenu> roots = menus.stream()
+                .filter(Objects::nonNull)
+                .filter(m -> m.getId() != null)
+                .filter(m -> {
+                    Long pid = m.getParentId();
+                    if (pid == null || pid == 0L) {
+                        return true;
+                    }
+                    return !idMap.containsKey(pid);
+                })
+                .sorted(Comparator.comparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo)))
+                .collect(Collectors.toList());
+
+        for (SysMenu root : roots) {
+            fillChildrenAndVisible(root, childrenMap, allowedMenuIds, new HashSet<>());
+        }
+        return roots;
+    }
+
+    private boolean fillChildrenAndVisible(SysMenu node, Map<Long, List<SysMenu>> childrenMap, Set<Long> allowedMenuIds, Set<Long> path) {
+        Long id = node.getId();
+        if (id != null && !path.add(id)) {
+            boolean visible = allowedMenuIds.contains(id);
+            node.setChildren(Collections.emptyList());
+            node.setVisible(visible ? "0" : "1");
+            return visible;
+        }
+        List<SysMenu> children = childrenMap.getOrDefault(id == null ? 0L : id, Collections.emptyList()).stream()
+                .filter(Objects::nonNull)
+                .sorted(Comparator.comparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo)))
+                .collect(Collectors.toList());
+
+        boolean anyChildVisible = false;
+        for (SysMenu child : children) {
+            anyChildVisible |= fillChildrenAndVisible(child, childrenMap, allowedMenuIds, path);
+        }
+        node.setChildren(children);
+
+        boolean selfVisible = id != null && allowedMenuIds.contains(id);
+        boolean visible = selfVisible || anyChildVisible;
+        node.setVisible(visible ? "0" : "1");
+        if (id != null) {
+            path.remove(id);
+        }
+        return visible;
+    }
 }

--
Gitblit v1.7.1