feat: align frontend document and rule management flows

This commit is contained in:
wren
2026-05-06 09:40:37 +08:00
parent 8a5044b024
commit c54f84382b
41 changed files with 4239 additions and 2903 deletions
+96 -45
View File
@@ -110,51 +110,44 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
},
{
id: 'rule-management',
title: '评查规则库',
title: '规则管理',
path: '/rules',
icon: 'ri-book-3-line',
order: 4,
children: [
{
id: 'rule-groups',
title: '评查点分组',
path: '/rule-groups',
icon: 'ri-folder-open-line',
order: 1
},
{
id: 'rules-list',
title: '评查点列表',
path: '/rules/list',
icon: 'ri-list-check-3',
order: 2
order: 1
},
{
id: 'rules-file',
title: '评查文件列表',
path: '/rules-files',
icon: 'ri-list-check-2',
order: 3
order: 2
}
]
},
{
id: 'contract-template',
title: '合同模板',
title: '合同管理',
path: '/contract-template',
icon: 'ri-file-search-line',
order: 5,
children: [
{
id: 'contract-search-ai',
title: '智能搜索',
title: '模板搜索',
path: '/contract-template/search',
icon: 'ri-search-line',
order: 1
},
{
id: 'contract-list',
title: '合同列表',
title: '模板列表',
path: '/contract-template/list',
icon: 'ri-folder-line',
order: 2
@@ -167,31 +160,34 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
path: '/settings',
icon: 'ri-settings-4-line',
order: 6,
requiredRole: 'developer',
children: [
{
id: 'rule-groups',
title: '规则组导航',
path: '/rule-groups',
icon: 'ri-folder-open-line',
order: 1
},
{
id: 'config-lists',
title: '配置列表',
path: '/config-lists',
icon: 'ri-list-check-3',
order: 1,
requiredRole: 'developer'
order: 2
},
{
id: 'document-types',
title: '文档类型',
path: '/document-types',
icon: 'ri-file-list-line',
order: 2,
requiredRole: 'developer'
order: 3
},
{
id: 'prompt-management',
title: '提示词管理',
path: '/prompts',
icon: 'ri-chat-1-line',
order: 3,
requiredRole: 'developer'
order: 4
}
]
},
@@ -252,51 +248,44 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
},
{
id: 'rule-management',
title: '评查规则库',
title: '规则管理',
path: '/rules',
icon: 'ri-book-3-line',
order: 4,
children: [
{
id: 'rule-groups',
title: '评查点分组',
path: '/rule-groups',
icon: 'ri-folder-open-line',
order: 1
},
{
id: 'rules-list',
title: '评查点列表',
path: '/rules/list',
icon: 'ri-list-check-3',
order: 2
order: 1
},
{
id: 'rules-file',
title: '评查文件列表',
path: '/rules-files',
icon: 'ri-list-check-2',
order: 3
order: 2
}
]
},
{
id: 'contract-template',
title: '合同模板',
title: '合同管理',
path: '/contract-template',
icon: 'ri-file-search-line',
order: 5,
children: [
{
id: 'contract-search-ai',
title: '智能搜索',
title: '模板搜索',
path: '/contract-template/search',
icon: 'ri-search-line',
order: 1
},
{
id: 'contract-list',
title: '合同列表',
title: '模板列表',
path: '/contract-template/list',
icon: 'ri-folder-line',
order: 2
@@ -367,14 +356,14 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
},
{
id: 'rule-management',
title: '评查规则库',
title: '规则管理',
path: '/rules',
icon: 'ri-book-3-line',
order: 4,
children: [
{
id: 'rule-groups',
title: '评查点分组',
title: '规则组导航',
path: '/rule-groups',
icon: 'ri-folder-open-line',
order: 1
@@ -397,21 +386,21 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
},
{
id: 'contract-template',
title: '合同模板',
title: '合同管理',
path: '/contract-template',
icon: 'ri-file-search-line',
order: 5,
children: [
{
id: 'contract-search-ai',
title: '智能搜索',
title: '模板搜索',
path: '/contract-template/search',
icon: 'ri-search-line',
order: 1
},
{
id: 'contract-list',
title: '合同列表',
title: '模板列表',
path: '/contract-template/list',
icon: 'ri-folder-line',
order: 2
@@ -475,14 +464,14 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
},
{
id: 'rule-management',
title: '评查规则库',
title: '规则管理',
path: '/rules',
icon: 'ri-book-3-line',
order: 4,
children: [
{
id: 'rule-groups',
title: '评查点分组',
title: '规则组导航',
path: '/rule-groups',
icon: 'ri-folder-open-line',
order: 1
@@ -505,21 +494,21 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
},
{
id: 'contract-template',
title: '合同模板',
title: '合同管理',
path: '/contract-template',
icon: 'ri-file-search-line',
order: 5,
children: [
{
id: 'contract-search-ai',
title: '智能搜索',
title: '模板搜索',
path: '/contract-template/search',
icon: 'ri-search-line',
order: 1
},
{
id: 'contract-list',
title: '合同列表',
title: '模板列表',
path: '/contract-template/list',
icon: 'ri-folder-line',
order: 2
@@ -997,7 +986,7 @@ function convertBackendRoutesToMenuItems(backendRoutes: BackendRouteInfo[], incl
// console.log('🔄 [convertBackendRoutesToMenuItems] 转换完成,返回的菜单项数量:', result.length);
// console.log('🔄 [convertBackendRoutesToMenuItems] 返回的菜单数据:', JSON.stringify(result, null, 2));
return result;
return normalizeMenuStructure(result);
}
@@ -1038,7 +1027,69 @@ function buildFallbackRoutes(roleKey: string): {
return {
success: true,
data: fallbackMenus.filter(item => isMinimalMenuPath(item.path)),
data: normalizeMenuStructure(fallbackMenus.filter(item => isMinimalMenuPath(item.path))),
permissionMap,
};
}
function normalizeMenuStructure(menuItems: MenuItem[]): MenuItem[] {
const clonedMenuItems = menuItems.map(item => ({
...item,
children: item.children ? normalizeMenuStructure(item.children) : undefined,
}));
const collectDescendantPaths = (items: MenuItem[] | undefined): string[] => {
if (!items || items.length === 0) {
return [];
}
return items.flatMap((item) => [
item.path,
...collectDescendantPaths(item.children),
]);
};
const nestedPathSet = new Set(
clonedMenuItems.flatMap(item => collectDescendantPaths(item.children)),
);
const dedupedTopLevelItems = clonedMenuItems.filter(item => !nestedPathSet.has(item.path));
const ruleManagement = dedupedTopLevelItems.find(item => item.path === '/rules');
const systemSettings = dedupedTopLevelItems.find(item => item.path === '/settings');
const syntheticRuleGroupsMenu: MenuItem = {
id: 'rule-groups',
title: '规则组导航',
path: '/rule-groups',
icon: 'ri-folder-open-line',
order: 1,
};
let ruleGroupsMenu: MenuItem = syntheticRuleGroupsMenu;
if (ruleManagement?.children?.length) {
const ruleGroupIndex = ruleManagement.children.findIndex(child => child.path === '/rule-groups');
if (ruleGroupIndex !== -1) {
const [existingRuleGroupsMenu] = ruleManagement.children.splice(ruleGroupIndex, 1);
ruleGroupsMenu = existingRuleGroupsMenu;
ruleManagement.children = ruleManagement.children
.map((child, index) => ({ ...child, order: index + 1 }))
.sort((a, b) => a.order - b.order);
}
}
if (!systemSettings) {
return dedupedTopLevelItems;
}
const settingsChildren = systemSettings.children ? [...systemSettings.children] : [];
if (!settingsChildren.some(child => child.path === '/rule-groups')) {
settingsChildren.unshift({ ...ruleGroupsMenu, order: 1 });
}
systemSettings.children = settingsChildren
.map((child, index) => ({ ...child, order: index + 1 }))
.sort((a, b) => a.order - b.order);
return dedupedTopLevelItems;
}