位置: SysMenuController.java:84-89
@SaCheckPermission("system:menu:query") // ← 步骤1: 权限校验
@GetMapping("/treeselect")
public R<List<Tree<Long>>> treeselect(SysMenuBo menu) {
// 步骤2: 查询菜单列表
List<SysMenuVo> menus = menuService.selectMenuList(menu, LoginHelper.getUserId());
// 步骤3: 构建树形结构
return R.ok(menuService.buildMenuTreeSelect(menus));
}
执行步骤:
@SaCheckPermission("system:menu:query") - 检查用户是否有 system:menu:query 权限LoginHelper.getUserId() - 从当前登录上下文获取用户IDmenuService.selectMenuList(menu, userId)menuService.buildMenuTreeSelect(menus)R<List<Tree<Long>>> 返回位置: SysMenuServiceImpl.java:73-93
public List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId) {
List<SysMenuVo> menuList;
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
// ========== 步骤A: 权限过滤 ==========
if (!LoginHelper.isSuperAdmin(userId)) {
// 非超管用户,需要通过角色过滤菜单
wrapper.inSql(SysMenu::getMenuId, baseMapper.buildMenuByUserSql(userId));
}
// ========== 步骤B: 平台过滤 ==========
int platformId = menu.getPlatformId()==null? PlatformUtils.getId() : menu.getPlatformId();
// ========== 步骤C: 构建查询条件并执行 ==========
menuList = baseMapper.selectVoList(
wrapper.like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
.eq(SysMenu::getPlatformId, platformId) // ← 关键:平台过滤
.eq(StringUtils.isNotBlank(menu.getMenuType()), SysMenu::getMenuType, menu.getMenuType())
.eq(ObjectUtil.isNotNull(menu.getParentId()), SysMenu::getParentId, menu.getParentId())
.orderByAsc(SysMenu::getParentId)
.orderByAsc(SysMenu::getOrderNum)
);
return menuList;
}
详细执行流程:
if (!LoginHelper.isSuperAdmin(userId)) {
wrapper.inSql(SysMenu::getMenuId, baseMapper.buildMenuByUserSql(userId));
}
生成的SQL子查询 (buildMenuByUserSql):
SELECT menu_id
FROM sys_role_menu
WHERE role_id IN (
SELECT sur.role_id
FROM sys_user_role sur
LEFT JOIN sys_role sr ON sr.role_id = sur.role_id
WHERE sur.user_id = ?
AND sr.status = '0'
)
作用: 获取该用户所有角色分配的菜单ID列表
int platformId = PlatformUtils.getId();
执行流程:
PlatformUtils.getId() 调用PLATFORM_CODEPLATFORM_CODE 转换为平台ID:
"PINGTAIDUAN" → 0 (平台端)"SHANGHUDUAN" → 1 (商户端)商户端用户的完整SQL:
SELECT *
FROM sys_menu
WHERE menu_id IN (
-- 用户角色分配的菜单ID列表
SELECT menu_id FROM sys_role_menu WHERE role_id IN (...)
)
AND platform_id = 1 -- 商户端
ORDER BY parent_id, order_num
关键点: 这是一个 AND 条件,必须同时满足:
位置: SysMenuMapper.java
使用 MyBatis-Plus 的 LambdaQueryWrapper 自动生成SQL并执行。
位置: SysMenuServiceImpl.java:250-265
public List<Tree<Long>> buildMenuTreeSelect(List<SysMenuVo> menus) {
if (CollUtil.isEmpty(menus)) {
return CollUtil.newArrayList(); // ← 如果查询结果为空,返回空列表
}
return TreeBuildUtils.build(menus, (menu, tree) -> {
tree.setId(menu.getMenuId())
.setParentId(menu.getParentId())
.setName(menu.getMenuName())
.setWeight(menu.getOrderNum());
// ... 设置其他属性
});
}
根据执行流程,商户端查询的SQL实际上是:
SELECT *
FROM sys_menu
WHERE menu_id IN (
-- 步骤1: 获取用户角色分配的菜单
SELECT menu_id FROM sys_role_menu
WHERE role_id IN (
SELECT role_id FROM sys_user_role WHERE user_id = 2038434195944886273
)
)
AND platform_id = 1 -- 步骤2: 过滤商户端菜单
两个条件的交集为空:
步骤1结果: 用户角色分配的菜单(假设有 100 条)
platform_id 可能是 0、NULL 或其他值步骤2过滤: platform_id = 1
交集: 如果步骤1的100条菜单中,没有一条的 platform_id = 1
执行以下SQL验证:
-- 查看用户角色分配的菜单的平台分布
SELECT sm.platform_id, COUNT(*) as count
FROM sys_user_role sur
LEFT JOIN sys_role_menu srm ON sur.role_id = srm.role_id
LEFT JOIN sys_menu sm ON srm.menu_id = sm.menu_id
WHERE sur.user_id = 2038434195944886273
GROUP BY sm.platform_id;
如果结果显示:
platform_id = 0: 100 条platform_id = 1: 0 条说明: 用户角色分配的菜单都是平台端的,没有商户端的,所以查询结果为空。
将用户角色需要的菜单改为 platform_id = 1:
UPDATE sys_menu SET platform_id = 1
WHERE menu_id IN (
SELECT menu_id FROM sys_role_menu
WHERE role_id IN (
SELECT role_id FROM sys_user_role
WHERE user_id = 2038434195944886273
)
);
删除旧的菜单权限,分配新的 platform_id = 1 的菜单:
-- 1. 获取角色ID
SELECT role_id FROM sys_user_role WHERE user_id = 2038434195944886273;
-- 2. 删除旧权限
DELETE FROM sys_role_menu WHERE role_id = ?;
-- 3. 分配新权限
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT ?, menu_id FROM sys_menu WHERE platform_id = 1;
在以下位置添加日志:
platformId 的值menuList.size()PlatformUtils.java:8 - 查看请求头中的 PLATFORM_CODE
log.info("查询菜单 - userId={}, platformId={}, isSuperAdmin={}",
userId, platformId, LoginHelper.isSuperAdmin(userId));
log.info("查询结果 - menuList.size()={}", menuList.size());