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:
@@ -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;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -17,6 +17,7 @@ export namespace SystemMenuApi {
|
||||
visible: boolean;
|
||||
keepAlive: boolean;
|
||||
alwaysShow?: boolean;
|
||||
platform?: string;
|
||||
createTime: Date;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,16 @@ import { getMenuList } from '#/api/system/menu';
|
||||
import { $t } from '#/locales';
|
||||
import { componentKeys } from '#/router/routes';
|
||||
|
||||
/**
|
||||
* 前端平台选项(对应 system_menu.platform 和 system_oauth2_client.platform)
|
||||
* null = 共享菜单;biz = 仅业务平台;iot = 仅物联运维平台
|
||||
* 新增前端时在此扩展。
|
||||
*/
|
||||
const PLATFORM_OPTIONS = [
|
||||
{ label: '业务平台 (biz)', value: 'biz' },
|
||||
{ label: '物联运维平台 (iot)', value: 'iot' },
|
||||
] as const;
|
||||
|
||||
/** 新增/修改的表单 */
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
@@ -239,6 +249,17 @@ export function useFormSchema(): VbenFormSchema[] {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'platform',
|
||||
label: '所属平台',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
placeholder: '请选择所属平台(不选则两个平台都展示)',
|
||||
options: PLATFORM_OPTIONS,
|
||||
},
|
||||
help: '不选 = 共享菜单,两个前端都能看到;选择后只在对应前端显示',
|
||||
},
|
||||
{
|
||||
fieldName: 'keepAlive',
|
||||
label: '缓存状态',
|
||||
|
||||
Reference in New Issue
Block a user