feat: reorganize platform navigation menus

This commit is contained in:
hailin
2026-07-16 17:15:51 +08:00
parent cc0572111d
commit fcb8121f0a
3 changed files with 311 additions and 20 deletions

View File

@@ -15,9 +15,18 @@ class MenuSpec:
DEFAULT_MENUS: tuple[MenuSpec, ...] = (
MenuSpec("workbench", "工作台", icon="home", sort_order=10),
MenuSpec("workbench.overview", "运营总览", "#/", "home", "workbench", 10),
MenuSpec("business", "业务处理", icon="ticket", sort_order=20),
MenuSpec("workbench", "工作台", "#/", "home", sort_order=10),
MenuSpec(
"workbench.overview",
"运营总览",
"#/",
"home",
"workbench",
10,
is_visible=False,
is_enabled=False,
),
MenuSpec("business", "工单", icon="ticket", sort_order=20),
MenuSpec("business.tickets", "工单中心", "#/tickets", "ticket", "business", 10, "ticket.view"),
MenuSpec(
"business.ticket_create",
@@ -28,33 +37,42 @@ DEFAULT_MENUS: tuple[MenuSpec, ...] = (
20,
"ticket.create",
),
MenuSpec(
"business.solutions",
"解决方案库",
"#/solutions",
"library",
"business",
30,
"solution.view",
),
MenuSpec("platform", "平台能力", icon="bot", sort_order=30),
MenuSpec("knowledge", "知识与方案", icon="book_open", sort_order=30),
MenuSpec(
"platform.knowledge",
"知识库",
"#/knowledge",
"database",
"platform",
"knowledge",
10,
"knowledge.view",
is_enabled=False,
),
MenuSpec(
"knowledge.search",
"知识检索",
"#/knowledge/search",
"search",
"knowledge",
20,
"knowledge.view",
),
MenuSpec(
"business.solutions",
"解决方案库",
"#/solutions",
"library",
"knowledge",
30,
"solution.view",
),
MenuSpec("platform", "AI 平台", icon="bot", sort_order=40),
MenuSpec(
"platform.agents",
"Agent 配置",
"#/agents",
"bot",
"platform",
20,
10,
"agent.manage",
),
MenuSpec(
@@ -63,7 +81,7 @@ DEFAULT_MENUS: tuple[MenuSpec, ...] = (
"#/modelhub/providers",
"settings",
"platform",
30,
20,
"model.manage",
),
MenuSpec(
@@ -72,7 +90,7 @@ DEFAULT_MENUS: tuple[MenuSpec, ...] = (
"#/skills",
"settings",
"platform",
40,
30,
"skill.manage",
),
MenuSpec(
@@ -81,10 +99,10 @@ DEFAULT_MENUS: tuple[MenuSpec, ...] = (
"#/agent-runs",
"audit",
"platform",
50,
40,
"agent.run.view",
),
MenuSpec("system", "系统治理", icon="shield", sort_order=40),
MenuSpec("system", "系统治理", icon="shield", sort_order=50),
MenuSpec(
"system.users", "用户管理", "#/system/users", "users", "system", 10, "system.user.view"
),

View File

@@ -0,0 +1,258 @@
from django.db import migrations
NEW_MENUS = (
("workbench", "工作台", "#/", "home", "", 10, "", True, True),
("workbench.overview", "运营总览", "#/", "home", "workbench", 10, "", False, False),
("business", "工单", "", "ticket", "", 20, "", True, True),
(
"business.tickets",
"工单中心",
"#/tickets",
"ticket",
"business",
10,
"ticket.view",
True,
True,
),
(
"business.ticket_create",
"创建工单",
"#/tickets/new",
"briefcase",
"business",
20,
"ticket.create",
True,
True,
),
("knowledge", "知识与方案", "", "book_open", "", 30, "", True, True),
(
"platform.knowledge",
"知识库",
"#/knowledge",
"database",
"knowledge",
10,
"knowledge.view",
True,
True,
),
(
"knowledge.search",
"知识检索",
"#/knowledge/search",
"search",
"knowledge",
20,
"knowledge.view",
True,
True,
),
(
"business.solutions",
"解决方案库",
"#/solutions",
"library",
"knowledge",
30,
"solution.view",
True,
True,
),
("platform", "AI 平台", "", "bot", "", 40, "", True, True),
(
"platform.agents",
"Agent 配置",
"#/agents",
"bot",
"platform",
10,
"agent.manage",
True,
True,
),
(
"platform.models",
"模型渠道",
"#/modelhub/providers",
"settings",
"platform",
20,
"model.manage",
True,
True,
),
(
"platform.skills",
"Skill 配置",
"#/skills",
"settings",
"platform",
30,
"skill.manage",
True,
True,
),
(
"platform.agent_runs",
"运行记录",
"#/agent-runs",
"audit",
"platform",
40,
"agent.run.view",
True,
True,
),
("system", "系统治理", "", "shield", "", 50, "", True, True),
)
OLD_MENUS = (
("workbench", "工作台", "", "home", "", 10, "", True, True),
("workbench.overview", "运营总览", "#/", "home", "workbench", 10, "", True, True),
("business", "业务处理", "", "ticket", "", 20, "", True, True),
(
"business.tickets",
"工单中心",
"#/tickets",
"ticket",
"business",
10,
"ticket.view",
True,
True,
),
(
"business.ticket_create",
"创建工单",
"#/tickets/new",
"briefcase",
"business",
20,
"ticket.create",
True,
True,
),
(
"business.solutions",
"解决方案库",
"#/solutions",
"library",
"business",
30,
"solution.view",
True,
True,
),
("platform", "平台能力", "", "bot", "", 30, "", True, True),
(
"platform.knowledge",
"知识库",
"#/knowledge",
"database",
"platform",
10,
"knowledge.view",
True,
False,
),
(
"platform.agents",
"Agent 配置",
"#/agents",
"bot",
"platform",
20,
"agent.manage",
True,
True,
),
(
"platform.models",
"模型渠道",
"#/modelhub/providers",
"settings",
"platform",
30,
"model.manage",
True,
True,
),
(
"platform.skills",
"Skill 配置",
"#/skills",
"settings",
"platform",
40,
"skill.manage",
True,
True,
),
(
"platform.agent_runs",
"运行记录",
"#/agent-runs",
"audit",
"platform",
50,
"agent.run.view",
True,
True,
),
("system", "系统治理", "", "shield", "", 40, "", True, True),
)
def apply_menu_specs(apps, specs):
menu_item = apps.get_model("accounts", "MenuItem")
menus_by_code = {}
for (
code,
title,
path,
icon,
parent_code,
sort_order,
permission_code,
is_visible,
is_enabled,
) in specs:
parent = menus_by_code.get(parent_code)
if parent is None and parent_code:
parent = menu_item.objects.filter(code=parent_code).first()
menu, _ = menu_item.objects.update_or_create(
code=code,
defaults={
"title": title,
"path": path,
"icon": icon,
"parent": parent,
"sort_order": sort_order,
"permission_code": permission_code,
"is_visible": is_visible,
"is_enabled": is_enabled,
},
)
menus_by_code[code] = menu
def forwards(apps, schema_editor):
apply_menu_specs(apps, NEW_MENUS)
def backwards(apps, schema_editor):
apply_menu_specs(apps, OLD_MENUS)
menu_item = apps.get_model("accounts", "MenuItem")
menu_item.objects.filter(code="knowledge.search").delete()
knowledge = menu_item.objects.filter(code="knowledge").first()
if knowledge is not None:
knowledge.children.update(parent=None)
knowledge.delete()
class Migration(migrations.Migration):
dependencies = [("accounts", "0001_initial")]
operations = [migrations.RunPython(forwards, backwards)]

View File

@@ -21,6 +21,21 @@ def test_bootstrap_governance_seeds_admin_roles_groups_permissions_and_menus(db,
assert UserGroup.objects.filter(code="default").exists()
assert MenuItem.objects.filter(code="system.users", title="用户管理").exists()
assert MenuItem.objects.filter(code="system.roles", permission_code="system.role.view").exists()
assert MenuItem.objects.filter(code="workbench", path="#/", parent=None).exists()
assert MenuItem.objects.filter(
code="workbench.overview", is_visible=False, is_enabled=False
).exists()
assert MenuItem.objects.filter(code="business", title="工单", sort_order=20).exists()
knowledge = MenuItem.objects.get(code="knowledge")
assert knowledge.title == "知识与方案"
assert list(knowledge.children.order_by("sort_order").values_list("code", flat=True)) == [
"platform.knowledge",
"knowledge.search",
"business.solutions",
]
assert MenuItem.objects.filter(code="platform.knowledge", is_enabled=True).exists()
assert MenuItem.objects.filter(code="platform", title="AI 平台", sort_order=40).exists()
assert MenuItem.objects.filter(code="system", sort_order=50).exists()
def test_bootstrap_governance_migrates_legacy_english_roles(db, settings):