feat(system): 按 OAuth2 客户端 platform 过滤菜单,支持业务/物联双前端
问题:业务平台(biz)和物联运维平台(iot)共用一套用户体系和菜单表,但每个前端 只该看到自己域的菜单。原来没有按客户端过滤的机制。 方案:在 OAuth2 客户端维度打 platform 标签(biz/iot/NULL),菜单也打同样标签, 登录时下发菜单按二者匹配过滤。 链路: - OAuth2AccessTokenCheckRespDTO / LoginUser(framework + gateway)新增 clientId 字段 - TokenAuthenticationFilter(framework + gateway)把 accessToken.clientId 带进 LoginUser - WebFrameworkUtils.HEADER_CLIENT_ID="X-Client-Id":登录/refresh 等"无 token 入口" 允许前端声明 client,避免硬编码 default - AdminAuthServiceImpl.resolveClientId:未传 Header 时回退 OAuth2ClientConstants.CLIENT_ID_DEFAULT - MenuDO / OAuth2ClientDO 各加 platform 列 - MenuService.filterMenusByPlatform:platform 为空(全平台共用)或匹配即保留 SQL 迁移按字母序编号: - _01_oauth2_client_platform.sql:加列 + 给 default/iot-client 客户端打标 + 递归标 IoT 菜单子树(root id=4000)为 iot - _02_bulk_mark_biz_menus.sql:其余 platform=NULL 的菜单兜底标 biz - 顺序依赖:_01 标完 iot 后 _02 才动剩余 NULL,避免 _02 把 IoT 菜单错标 biz Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
-- ============================================================
|
||||
-- 多前端按 client → platform 过滤菜单
|
||||
-- 配合后端代码:AuthController.getPermissionInfo / MenuService.filterMenusByPlatform
|
||||
-- 日期:2026-04-20
|
||||
--
|
||||
-- platform 取值约定:
|
||||
-- biz = 业务平台(对应 OAuth2 客户端 default)
|
||||
-- iot = 物联运维平台(对应 OAuth2 客户端 iot-client)
|
||||
-- NULL = 两个平台都展示(通用菜单,如系统管理、用户、部门等)
|
||||
-- ============================================================
|
||||
|
||||
-- 1. system_oauth2_client 加 platform 列
|
||||
ALTER TABLE `system_oauth2_client`
|
||||
ADD COLUMN `platform` VARCHAR(10) NULL DEFAULT NULL
|
||||
COMMENT '平台标识:biz-业务平台,iot-物联运维平台,NULL-不按客户端过滤菜单'
|
||||
AFTER `additional_information`;
|
||||
|
||||
-- 2. 矫正 system_menu.platform 列的注释(旧注释写的是 ops/sys,与代码约定不一致,更新为 biz/iot)
|
||||
ALTER TABLE `system_menu`
|
||||
MODIFY COLUMN `platform` VARCHAR(10) NULL DEFAULT NULL
|
||||
COMMENT '平台标识:biz-业务平台,iot-物联运维平台,NULL-两个平台都展示';
|
||||
|
||||
-- 3. 给两个内部 SSO 客户端打 platform 标
|
||||
-- 业务平台复用 yudao 默认 default 客户端 → biz
|
||||
-- 物联运维平台用独立 iot-client → iot
|
||||
UPDATE `system_oauth2_client` SET `platform` = 'biz' WHERE `client_id` = 'default';
|
||||
UPDATE `system_oauth2_client` SET `platform` = 'iot' WHERE `client_id` = 'iot-client';
|
||||
|
||||
-- 4. 给 IoT 模块的菜单打 iot 标记。从 sql/mysql/system_menu.sql 看,
|
||||
-- IoT 设备接入 root id=4000,整个子树都属于 iot 平台。
|
||||
UPDATE `system_menu` SET `platform` = 'iot'
|
||||
WHERE `id` IN (
|
||||
SELECT t.id FROM (
|
||||
-- 递归取 4000 子树。MySQL 8 用 CTE,旧版自行替换为多次 UPDATE
|
||||
WITH RECURSIVE iot_tree(id) AS (
|
||||
SELECT id FROM system_menu WHERE id = 4000
|
||||
UNION ALL
|
||||
SELECT m.id FROM system_menu m JOIN iot_tree it ON m.parent_id = it.id
|
||||
)
|
||||
SELECT id FROM iot_tree
|
||||
) t
|
||||
);
|
||||
|
||||
-- 5. 业务平台独有菜单标 biz(可选;不标的话默认 NULL = 两边都显示)
|
||||
-- 例如 OA 示例(id=5):
|
||||
-- UPDATE `system_menu` SET `platform` = 'biz' WHERE `id` IN (5);
|
||||
|
||||
-- 6. 系统管理 / 基础设施 / 用户 / 部门 / 字典 等通用菜单保持 NULL,两边共用。
|
||||
|
||||
-- 7. 改完客户端后,记得在后台 OAuth2 客户端管理页面"保存"一次刷新缓存;
|
||||
-- 或重启后端清缓存(Redis key: oauth2_client)。
|
||||
18
sql/mysql/migrations/2026-04-20_02_bulk_mark_biz_menus.sql
Normal file
18
sql/mysql/migrations/2026-04-20_02_bulk_mark_biz_menus.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
-- ============================================================
|
||||
-- 批量给「非 IoT 菜单」打上 platform='biz'
|
||||
-- 策略:iot 平台只看设备接入子树(4000),其余(含系统管理、基础设施、OA、各 demo)一律归业务平台
|
||||
-- 日期:2026-04-20
|
||||
-- ============================================================
|
||||
|
||||
-- 所有 platform 还是 NULL 的,一律改为 biz
|
||||
-- (platform='iot' 的行已经在上一次迁移里设过,不会被动)
|
||||
UPDATE system_menu
|
||||
SET platform = 'biz'
|
||||
WHERE deleted = 0 AND platform IS NULL;
|
||||
|
||||
-- 验证
|
||||
SELECT platform, COUNT(*) AS cnt FROM system_menu WHERE deleted = 0 GROUP BY platform;
|
||||
-- 预期:
|
||||
-- biz = 大部分(系统管理/基础设施/OA/demos 等)
|
||||
-- iot = 设备接入子树(~50)
|
||||
-- NULL = 0
|
||||
Reference in New Issue
Block a user