feat(@vben/web-antd): 支持按 platform 过滤多前端菜单

业务平台 (biz) 与物联运维平台 (iot) 共享同一后端,需按前端来源过滤菜单,
避免同一角色在两端看到相同菜单。

- 新增 CLIENT_ID 常量,请求拦截器 / 基础 client 统一注入 X-Client-Id 头,
  后端密码登录 & refresh-token 据此绑定 token 的 client/platform
- SystemMenuApi.Menu 增加 platform 字段
- 菜单表单新增"所属平台"选择项(PLATFORM_OPTIONS),为 null 则两端共享

配合后端迁移 sql/mysql/migrations/2026-04-20_oauth2_client_platform.sql。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
lzh
2026-04-22 23:40:19 +08:00
parent 93bfef06a4
commit 72ed0eb5aa
3 changed files with 33 additions and 0 deletions

View File

@@ -24,6 +24,13 @@ const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
const tenantEnable = isTenantEnable();
const apiEncrypt = createApiEncrypt(import.meta.env);
/**
* 当前前端对应的 OAuth2 客户端编号。
* 业务平台 = 'biz',物联运维平台 = 'iot'。后端按此过滤菜单platform 列)。
* 改动需同步menu 表 platform 选项、sso-callback 页面 ssoCallback(clientId) 入参。
*/
export const CLIENT_ID = 'biz' as const;
function createRequestClient(baseURL: string, options?: RequestClientOptions) {
const client = new RequestClient({
...options,
@@ -88,6 +95,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
: undefined;
// 添加项目编号
config.headers['project-id'] = accessStore.projectId;
// 声明前端身份:密码登录 / refresh-token 路径后端用此值绑定 token供按 platform 过滤菜单
config.headers['X-Client-Id'] = CLIENT_ID;
// 是否 API 加密
if ((config.headers || {}).isEncrypt) {
@@ -186,6 +195,8 @@ baseRequestClient.addRequestInterceptor({
: undefined;
// 添加项目编号
config.headers['project-id'] = accessStore.projectId;
// 声明前端身份(同上)
config.headers['X-Client-Id'] = CLIENT_ID;
return config;
},
});

View File

@@ -17,6 +17,7 @@ export namespace SystemMenuApi {
visible: boolean;
keepAlive: boolean;
alwaysShow?: boolean;
platform?: string;
createTime: Date;
}
}