216 lines
6.6 KiB
JavaScript
216 lines
6.6 KiB
JavaScript
/**
|
|
* 路由权限别名配置
|
|
*
|
|
* 目标:
|
|
* 1. 把“功能子页”统一映射到实际受控的父菜单/父页面
|
|
* 2. 让 root loader、usePermission、服务端鉴权复用同一套规则
|
|
* 3. 给测试脚本一个稳定的数据源,避免后续继续手工补漏
|
|
*
|
|
* 维护约束文档:
|
|
* - docs/route-alias-guidelines.md
|
|
*/
|
|
|
|
/**
|
|
* @typedef {{
|
|
* source: string;
|
|
* target: string;
|
|
* note: string;
|
|
* examples: Array<{ input: string; output: string }>;
|
|
* }} RouteAliasEntry
|
|
*/
|
|
|
|
/**
|
|
* @typedef {{
|
|
* group: string;
|
|
* note: string;
|
|
* entries: RouteAliasEntry[];
|
|
* }} RouteAliasGroup
|
|
*/
|
|
|
|
/** @type {RouteAliasGroup[]} */
|
|
export const permissionRouteAliasGroups = [
|
|
{
|
|
group: 'legacy-compat',
|
|
note: '兼容历史遗留路由,避免新旧页面并存时出现权限断层。',
|
|
entries: [
|
|
{
|
|
source: '^/reviewsTest(?=/|$)',
|
|
target: '/documents',
|
|
note: '文档评查详情页复用文档模块权限,兼容从文档列表与上传页进入详情的场景。',
|
|
examples: [
|
|
{ input: '/reviewsTest', output: '/documents' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/reviews(?=/|$)',
|
|
target: '/documents',
|
|
note: '旧版评查详情页同样归入文档模块权限,避免历史链接访问被拒绝。',
|
|
examples: [
|
|
{ input: '/reviews', output: '/documents' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/rulesTest/list(?=/|$)',
|
|
target: '/rules',
|
|
note: '旧版规则列表页归入规则管理主菜单权限。',
|
|
examples: [
|
|
{ input: '/rulesTest/list', output: '/rules' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/rulesTest/detail(?=/|$)',
|
|
target: '/rules',
|
|
note: '旧版规则详情页归入规则管理主菜单权限。',
|
|
examples: [
|
|
{ input: '/rulesTest/detail', output: '/rules' },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
group: 'editor-pages',
|
|
note: '新建/编辑/复制页统一依赖父列表页权限,避免为固定子路由重复配菜单。',
|
|
entries: [
|
|
{
|
|
source: '^/entry-modules/new(?=/|$)',
|
|
target: '/entry-modules',
|
|
note: '入口模块新建/编辑页复用入口模块列表权限。',
|
|
examples: [
|
|
{ input: '/entry-modules/new', output: '/entry-modules' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/document-types/new(?=/|$)',
|
|
target: '/document-types',
|
|
note: '文档类型新建/编辑页复用文档类型列表权限。',
|
|
examples: [
|
|
{ input: '/document-types/new', output: '/document-types' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/config-lists/new(?=/|$)',
|
|
target: '/config-lists',
|
|
note: '配置列表新建/编辑页复用配置列表权限。',
|
|
examples: [
|
|
{ input: '/config-lists/new', output: '/config-lists' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/prompts/new(?=/|$)',
|
|
target: '/prompts',
|
|
note: '提示词新建/编辑/克隆页复用提示词列表权限。',
|
|
examples: [
|
|
{ input: '/prompts/new', output: '/prompts' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/rule-groups/new(?=/|$)',
|
|
target: '/rule-groups',
|
|
note: '旧分组新建/编辑入口已下线,统一回到规则导航页。',
|
|
examples: [
|
|
{ input: '/rule-groups/new', output: '/rule-groups' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/rules/list(?=/|$)',
|
|
target: '/rules',
|
|
note: '评查点列表页优先复用规则管理主菜单权限,兼容后端尚未细分子路由授权的场景。',
|
|
examples: [
|
|
{ input: '/rules/list', output: '/rules' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/rules/new(?=/|$)',
|
|
target: '/rules',
|
|
note: '评查点新建/编辑/复制页复用规则管理主菜单权限。',
|
|
examples: [
|
|
{ input: '/rules/new', output: '/rules' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/documents/list(?=/|$)',
|
|
target: '/documents',
|
|
note: '文档列表子页复用文档模块主菜单权限,兼容 Remix 嵌套路由地址。',
|
|
examples: [
|
|
{ input: '/documents/list', output: '/documents' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/documents/edit(?=/|$)',
|
|
target: '/documents',
|
|
note: '文档编辑页复用文档列表权限。',
|
|
examples: [
|
|
{ input: '/documents/edit', output: '/documents' },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
group: 'module-subpages',
|
|
note: '模块内部的功能页归属到模块入口或父查询页,以维持导航和权限的一致性。',
|
|
entries: [
|
|
{
|
|
source: '^/contract-template/search/results(?=/|$)',
|
|
target: '/contract-template/search',
|
|
note: '搜索结果页复用合同模板搜索页权限。',
|
|
examples: [
|
|
{ input: '/contract-template/search/results', output: '/contract-template/search' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/contract-template/detail(?=/|$)',
|
|
target: '/contract-template/list',
|
|
note: '合同模板详情页复用合同列表权限,兼容父菜单本身不直接授权的场景。',
|
|
examples: [
|
|
{ input: '/contract-template/detail/123', output: '/contract-template/list/123' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/contract-draft(?=/|$)',
|
|
target: '/contract-template/list',
|
|
note: '合同起草页复用合同列表权限,保持与老入口的访问语义一致。',
|
|
examples: [
|
|
{ input: '/contract-draft/1', output: '/contract-template/list/1' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/chat-with-llm/chat(?=/|$)',
|
|
target: '/chat-with-llm',
|
|
note: 'AI 对话实际工作台复用 AI 对话主菜单权限。',
|
|
examples: [
|
|
{ input: '/chat-with-llm/chat', output: '/chat-with-llm' },
|
|
],
|
|
},
|
|
{
|
|
source: '^/chat-with-llm/dataset-manager(?=/|$)',
|
|
target: '/chat-with-llm',
|
|
note: '知识库管理页归属 AI 对话模块,避免隐藏子页权限断层。',
|
|
examples: [
|
|
{ input: '/chat-with-llm/dataset-manager', output: '/chat-with-llm' },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
export function listPermissionRouteAliases() {
|
|
return permissionRouteAliasGroups.flatMap(group =>
|
|
group.entries.map(entry => ({
|
|
...entry,
|
|
group: group.group,
|
|
groupNote: group.note,
|
|
pattern: new RegExp(entry.source),
|
|
})),
|
|
);
|
|
}
|
|
|
|
export function normalizeRoutePathForPermission(pathname) {
|
|
for (const entry of listPermissionRouteAliases()) {
|
|
if (entry.pattern.test(pathname)) {
|
|
return pathname.replace(entry.pattern, entry.target);
|
|
}
|
|
}
|
|
|
|
return pathname;
|
|
}
|