fix: enforce platform role menu access

This commit is contained in:
2026-07-27 12:48:35 +08:00
parent cd58e1f6b6
commit 160172bf10
33 changed files with 481 additions and 107 deletions

View File

@@ -3,7 +3,7 @@ import { request } from './http';
/** 平台登录和当前账号资料的接口模型。 */
export type LoginData = { username: string; password: string };
export type LoginReply = { access_token: string; token_type: string; identity: string; display_name: string; role_code: string };
export type Profile = { identity: string; username: string; display_name: string; avatar: string; role_code: string };
export type Profile = { identity: string; username: string; display_name: string; avatar: string; role_code: string; menu_codes: string[] };
export const authApi = {
login: (data: LoginData) => request<LoginReply>('/auth/login', { method: 'POST', body: JSON.stringify(data) }),

View File

@@ -11,4 +11,16 @@ export const platformApi = {
listRole: () => resourceApi.list<PlatformRole>('/platform/platform_role'),
createRole: (data: Record<string, unknown>) => resourceApi.create<PlatformRole>('/platform/platform_role', data),
listMenu: () => request<{ total: number; list: PlatformMenu[] }>('/platform/platform_menu'),
listRoleMenuIdentities: (identity: string) =>
request<{ menu_identities: string[] }>(
`/platform/platform_role/${identity}/menu`,
),
replaceRoleMenus: (identity: string, menuIdentities: string[]) =>
request<{ updated: boolean }>(
`/platform/platform_role/${identity}/menu`,
{
method: 'PUT',
body: JSON.stringify({ menu_identities: menuIdentities }),
},
),
};

View File

@@ -1,10 +1,10 @@
import type { ResourceField } from './resources';
export type ResourceFormValue = string | number | boolean | undefined;
export type ResourceFormValue = string | number | boolean | string[] | undefined;
export type ResourceFormMode = 'create' | 'edit';
export function isMissingField(value: ResourceFormValue | null): boolean {
return value === '' || value === null || value === undefined;
return value === '' || value === null || value === undefined || (Array.isArray(value) && value.length === 0);
}
export function isResourceFieldRequired(

View File

@@ -4,6 +4,8 @@ export type ResourceFieldType =
| 'text'
| 'password'
| 'identity'
| 'role-code'
| 'menu-identities'
| 'number'
| 'boolean'
| 'date'
@@ -105,6 +107,7 @@ const labels: Record<string, string> = {
category: '分类',
priority: '优先级',
platform_role_code: '平台角色',
menu_identities: '菜单权限',
data_scope: '数据范围',
menu_code: '菜单编码',
icon: '图标',
@@ -181,6 +184,8 @@ const jsonFields = new Set([
]);
const textareaFields = new Set(['body', 'content', 'reason', 'opinion']);
const fieldType = (key: string): ResourceFieldType => {
if (key === 'platform_role_code') return 'role-code';
if (key === 'menu_identities') return 'menu-identities';
if (key.endsWith('_identity')) return 'identity';
if (key === 'password') return 'password';
if (numberFields.has(key)) return 'number';
@@ -541,14 +546,23 @@ export const resources: ResourceUiDefinition[] = [
'password!',
'display_name',
'avatar',
'platform_role_code',
'platform_role_code!',
'phone',
]),
define('platform_role', '/platform/platform_role', 'writable', 'list', [
'role_code!',
'name!',
'data_scope!',
]),
define(
'platform_role',
'/platform/platform_role',
'writable',
'list',
['role_code!', 'name!', 'data_scope!'],
[
action(
'分配菜单',
'/platform/platform_role/:identity/menu',
['menu_identities!'],
),
],
),
define('platform_menu', '/platform/platform_menu', 'writable', 'tree', [
'parent_identity',
'menu_code!',