feat: 完成 issue #165 [A2] 菜单播种 v2——原生菜单(type=1/component/iconify)+PUT 幂等更新+admin 角色
This commit is contained in:
@@ -31,32 +31,40 @@ import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
# ---- iAOP 模块注册表(镜像 web/shared/session.js 的 MODULES,顺序即菜单顺序) ----
|
||||
# ---- iAOP 模块注册表 v2(Epic #163 原生重构:type=1 原生菜单,component→views/iaop/*) ----
|
||||
# path=/iaop/<key>,component=iaop/<key>/index(与 apps/web-antdv-next/src/views/iaop/* 对应);
|
||||
# icon 为 iconify 名;users 不注册(FBA 系统管理承载)、mobile 暂不注册(见 B9)。
|
||||
MODULES = [
|
||||
{"key": "cockpit", "title": "配置化驾驶舱", "icon": "🚀", "path": "/cockpit/"},
|
||||
{"key": "chat", "title": "对话助手", "icon": "💬", "path": "/chat/assistant.html"},
|
||||
{"key": "studio", "title": "模板配置台", "icon": "🧩", "path": "/studio/", "children": [
|
||||
{"key": "import", "title": "点位导入"},
|
||||
{"key": "hyper", "title": "模型超参"},
|
||||
{"key": "layout", "title": "驾驶舱编排"},
|
||||
{"key": "version", "title": "版本发布"},
|
||||
{"key": "cockpit", "title": "配置化驾驶舱", "icon": "mdi:view-dashboard",
|
||||
"path": "/iaop/cockpit", "component": "iaop/cockpit/index"},
|
||||
{"key": "chat", "title": "对话助手", "icon": "mdi:chat-processing-outline",
|
||||
"path": "/iaop/chat", "component": "iaop/chat/index"},
|
||||
{"key": "studio", "title": "模板配置台", "icon": "mdi:widgets-outline",
|
||||
"path": "/iaop/studio", "component": "iaop/studio/index", "children": [
|
||||
{"key": "import", "title": "点位导入", "component": "iaop/studio/import"},
|
||||
{"key": "hyper", "title": "模型超参", "component": "iaop/studio/hyper"},
|
||||
{"key": "layout", "title": "驾驶舱编排", "component": "iaop/studio/layout"},
|
||||
{"key": "version", "title": "版本发布", "component": "iaop/studio/version"},
|
||||
]},
|
||||
{"key": "admin", "title": "管理控制台", "icon": "⚙️", "path": "/admin/", "children": [
|
||||
{"key": "models", "title": "模型管理"},
|
||||
{"key": "kb", "title": "知识库管理"},
|
||||
{"key": "alerts", "title": "告警确认"},
|
||||
{"key": "audit", "title": "审计查询"},
|
||||
{"key": "admin", "title": "管理控制台", "icon": "mdi:cog-outline",
|
||||
"path": "/iaop/admin", "component": "iaop/admin/index", "children": [
|
||||
{"key": "models", "title": "模型管理", "component": "iaop/admin/models"},
|
||||
{"key": "kb", "title": "知识库管理", "component": "iaop/admin/kb"},
|
||||
{"key": "alerts", "title": "告警确认", "component": "iaop/admin/alerts"},
|
||||
{"key": "audit", "title": "审计查询", "component": "iaop/admin/audit"},
|
||||
]},
|
||||
{"key": "users", "title": "用户与角色", "icon": "👤", "path": "/auth/users.html"},
|
||||
{"key": "mobile", "title": "移动端驾驶舱", "icon": "📱", "path": "/mobile/"},
|
||||
]
|
||||
|
||||
# 角色 → 可见模块(PRD 8.2;admin 通常为 is_superuser,无需分配,看到全部)
|
||||
# 角色 → 可见 iAOP 模块(PRD 8.2;admin 角色为新增业务管理员,非超管)
|
||||
ROLE_MENUS = {
|
||||
"viewer": ["cockpit", "chat", "mobile"],
|
||||
"engineer": ["cockpit", "chat", "mobile", "studio"],
|
||||
"viewer": ["cockpit", "chat"],
|
||||
"engineer": ["cockpit", "chat", "studio"],
|
||||
"admin": ["cockpit", "chat", "studio", "admin"],
|
||||
}
|
||||
|
||||
# admin 角色额外分配:FBA 原生管理菜单(存在即分配)
|
||||
FBA_ADMIN_MENUS = ["system", "monitor", "log", "scheduler"]
|
||||
|
||||
|
||||
class FbaClient:
|
||||
def __init__(self, base: str, username: str, password: str):
|
||||
@@ -133,21 +141,26 @@ def main():
|
||||
|
||||
# ---- 1. 播种菜单(幂等:按 name 查重) --------------------------------
|
||||
existing = flatten_menu_names(cli.get("/sys/menus"))
|
||||
created, skipped = 0, 0
|
||||
created, updated = 0, 0
|
||||
|
||||
def ensure_menu(name, title, path, mtype, sort, parent_id=None):
|
||||
nonlocal created, skipped
|
||||
if name in existing:
|
||||
skipped += 1
|
||||
return existing[name]
|
||||
def upsert_menu(name, title, path, mtype, sort, parent_id=None,
|
||||
component=None, icon=None, perms=None):
|
||||
nonlocal created, updated
|
||||
body = {
|
||||
"title": title, "name": name, "path": path,
|
||||
"parent_id": parent_id, "sort": sort, "icon": None,
|
||||
"parent_id": parent_id, "sort": sort, "icon": icon,
|
||||
"type": mtype, # 0目录 1菜单
|
||||
"component": None, "perms": f"iaop:{name}",
|
||||
"component": component, "perms": perms or f"iaop:{name}",
|
||||
"status": 1, "display": 1, "cache": 0,
|
||||
"link": None, "remark": "iAOP 模块(seed_iaop_menus.py)",
|
||||
"link": None, "remark": "iAOP 原生菜单(seed_iaop_menus.py v2)",
|
||||
}
|
||||
if name in existing:
|
||||
# 幂等:已存在(含 #161 旧版 type=0/iframe 菜单)→ PUT 更新关键字段
|
||||
mid = existing[name]
|
||||
cli.put(f"/sys/menus/{mid}", body)
|
||||
updated += 1
|
||||
print(f"[upd] 更新菜单 {name}({title})")
|
||||
return mid
|
||||
cli.post("/sys/menus", body)
|
||||
created += 1
|
||||
# 创建后重新拉取以拿到 id(接口不回传 id)
|
||||
@@ -159,13 +172,17 @@ def main():
|
||||
for i, m in enumerate(MODULES):
|
||||
children = m.get("children")
|
||||
if children:
|
||||
pid = ensure_menu(m["key"], m["title"], m["path"], 0, i)
|
||||
pid = upsert_menu(m["key"], m["title"], m["path"], 0, i,
|
||||
component=m.get("component"), icon=m.get("icon"))
|
||||
for j, c in enumerate(children):
|
||||
ensure_menu(c["key"], c["title"], f"{m['path']}#{c['key']}",
|
||||
1, j, parent_id=pid)
|
||||
upsert_menu(c["key"], c["title"],
|
||||
f"{m['path']}/{c['key']}", 1, j,
|
||||
parent_id=pid, component=c.get("component"),
|
||||
icon=c.get("icon"))
|
||||
else:
|
||||
ensure_menu(m["key"], m["title"], m["path"], 1, i)
|
||||
print(f"[ok] 菜单:新建 {created},已存在跳过 {skipped}")
|
||||
upsert_menu(m["key"], m["title"], m["path"], 1, i,
|
||||
component=m.get("component"), icon=m.get("icon"))
|
||||
print(f"[ok] 菜单:新建 {created},更新 {updated}")
|
||||
|
||||
# ---- 2. 播种角色并分配菜单 -------------------------------------------
|
||||
menu_ids = flatten_menu_names(cli.get("/sys/menus"))
|
||||
@@ -195,6 +212,11 @@ def main():
|
||||
ids = []
|
||||
for k in mod_keys:
|
||||
ids.extend(module_menu_ids(k))
|
||||
# admin 角色额外分配 FBA 原生管理菜单(system/monitor/log/scheduler 等)
|
||||
if role_name == "admin":
|
||||
for fba_name in FBA_ADMIN_MENUS:
|
||||
if fba_name in menu_ids:
|
||||
ids.append(menu_ids[fba_name])
|
||||
cli.put(f"/sys/roles/{rid}/menus", {"menus": ids})
|
||||
print(f"[ok] 角色 {role_name} 菜单:{', '.join(mod_keys)}({len(ids)} 项)")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user