feat: reorganize platform navigation menus
This commit is contained in:
@@ -15,9 +15,18 @@ class MenuSpec:
|
|||||||
|
|
||||||
|
|
||||||
DEFAULT_MENUS: tuple[MenuSpec, ...] = (
|
DEFAULT_MENUS: tuple[MenuSpec, ...] = (
|
||||||
MenuSpec("workbench", "工作台", icon="home", sort_order=10),
|
MenuSpec("workbench", "工作台", "#/", "home", sort_order=10),
|
||||||
MenuSpec("workbench.overview", "运营总览", "#/", "home", "workbench", 10),
|
MenuSpec(
|
||||||
MenuSpec("business", "业务处理", icon="ticket", sort_order=20),
|
"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.tickets", "工单中心", "#/tickets", "ticket", "business", 10, "ticket.view"),
|
||||||
MenuSpec(
|
MenuSpec(
|
||||||
"business.ticket_create",
|
"business.ticket_create",
|
||||||
@@ -28,33 +37,42 @@ DEFAULT_MENUS: tuple[MenuSpec, ...] = (
|
|||||||
20,
|
20,
|
||||||
"ticket.create",
|
"ticket.create",
|
||||||
),
|
),
|
||||||
MenuSpec(
|
MenuSpec("knowledge", "知识与方案", icon="book_open", sort_order=30),
|
||||||
"business.solutions",
|
|
||||||
"解决方案库",
|
|
||||||
"#/solutions",
|
|
||||||
"library",
|
|
||||||
"business",
|
|
||||||
30,
|
|
||||||
"solution.view",
|
|
||||||
),
|
|
||||||
MenuSpec("platform", "平台能力", icon="bot", sort_order=30),
|
|
||||||
MenuSpec(
|
MenuSpec(
|
||||||
"platform.knowledge",
|
"platform.knowledge",
|
||||||
"知识库",
|
"知识库",
|
||||||
"#/knowledge",
|
"#/knowledge",
|
||||||
"database",
|
"database",
|
||||||
"platform",
|
"knowledge",
|
||||||
10,
|
10,
|
||||||
"knowledge.view",
|
"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(
|
MenuSpec(
|
||||||
"platform.agents",
|
"platform.agents",
|
||||||
"Agent 配置",
|
"Agent 配置",
|
||||||
"#/agents",
|
"#/agents",
|
||||||
"bot",
|
"bot",
|
||||||
"platform",
|
"platform",
|
||||||
20,
|
10,
|
||||||
"agent.manage",
|
"agent.manage",
|
||||||
),
|
),
|
||||||
MenuSpec(
|
MenuSpec(
|
||||||
@@ -63,7 +81,7 @@ DEFAULT_MENUS: tuple[MenuSpec, ...] = (
|
|||||||
"#/modelhub/providers",
|
"#/modelhub/providers",
|
||||||
"settings",
|
"settings",
|
||||||
"platform",
|
"platform",
|
||||||
30,
|
20,
|
||||||
"model.manage",
|
"model.manage",
|
||||||
),
|
),
|
||||||
MenuSpec(
|
MenuSpec(
|
||||||
@@ -72,7 +90,7 @@ DEFAULT_MENUS: tuple[MenuSpec, ...] = (
|
|||||||
"#/skills",
|
"#/skills",
|
||||||
"settings",
|
"settings",
|
||||||
"platform",
|
"platform",
|
||||||
40,
|
30,
|
||||||
"skill.manage",
|
"skill.manage",
|
||||||
),
|
),
|
||||||
MenuSpec(
|
MenuSpec(
|
||||||
@@ -81,10 +99,10 @@ DEFAULT_MENUS: tuple[MenuSpec, ...] = (
|
|||||||
"#/agent-runs",
|
"#/agent-runs",
|
||||||
"audit",
|
"audit",
|
||||||
"platform",
|
"platform",
|
||||||
50,
|
40,
|
||||||
"agent.run.view",
|
"agent.run.view",
|
||||||
),
|
),
|
||||||
MenuSpec("system", "系统治理", icon="shield", sort_order=40),
|
MenuSpec("system", "系统治理", icon="shield", sort_order=50),
|
||||||
MenuSpec(
|
MenuSpec(
|
||||||
"system.users", "用户管理", "#/system/users", "users", "system", 10, "system.user.view"
|
"system.users", "用户管理", "#/system/users", "users", "system", 10, "system.user.view"
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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)]
|
||||||
@@ -21,6 +21,21 @@ def test_bootstrap_governance_seeds_admin_roles_groups_permissions_and_menus(db,
|
|||||||
assert UserGroup.objects.filter(code="default").exists()
|
assert UserGroup.objects.filter(code="default").exists()
|
||||||
assert MenuItem.objects.filter(code="system.users", title="用户管理").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="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):
|
def test_bootstrap_governance_migrates_legacy_english_roles(db, settings):
|
||||||
|
|||||||
Reference in New Issue
Block a user