浏览代码

feat: move enterprise identity to system management

马小龙 2 天之前
父节点
当前提交
67d426030c

+ 20 - 20
frontend/src/router/routes.js

@@ -179,23 +179,6 @@ export default {
       path: '/data-governance',
       urls: '',
       children: [
-        {
-          hidden: 0,
-          type: 1,
-          title: '企业身份',
-          path: '/systemManage/enterprise-identity',
-          children: [],
-          label: '企业身份',
-          sort: 1,
-          component: 'systemManage/enterpriseIdentity',
-          meta: {
-            title: '企业身份',
-            icon: 'mdi-account-key-outline',
-            permissions: ['identity:manage']
-          },
-          name: 'systemEnterpriseIdentity',
-          alwaysShow: 0
-        },
         {
           hidden: 0,
           icon: 'mdi-database-cog-outline',
@@ -1968,6 +1951,23 @@ export default {
           name: 'systemUserManage',
           alwaysShow: 0
         },
+        {
+          hidden: 0,
+          type: 1,
+          title: '企业身份与 SSO',
+          path: '/systemManage/enterprise-identity',
+          children: [],
+          label: '企业身份与 SSO',
+          sort: 2,
+          component: 'systemManage/enterpriseIdentity',
+          meta: {
+            title: '企业身份与 SSO',
+            icon: 'mdi-account-key-outline',
+            permissions: ['identity:manage']
+          },
+          name: 'systemEnterpriseIdentity',
+          alwaysShow: 0
+        },
         {
           hidden: 0,
           type: 1,
@@ -1975,7 +1975,7 @@ export default {
           path: '/systemManage/responsibilities',
           children: [],
           label: '设备责任矩阵',
-          sort: 2,
+          sort: 3,
           component: 'systemManage/responsibility',
           meta: {
             title: '设备责任矩阵',
@@ -1992,7 +1992,7 @@ export default {
           path: '/systemManage/governance-audit',
           children: [],
           label: '审计与运行证据',
-          sort: 3,
+          sort: 4,
           component: 'systemManage/governanceAudit',
           meta: {
             title: '审计与运行证据',
@@ -2009,7 +2009,7 @@ export default {
           path: '/systemManage/agent-governance',
           children: [],
           label: 'Agent 治理',
-          sort: 4,
+          sort: 5,
           component: 'systemManage/agentGovernance',
           meta: {
             title: 'Agent 治理',

+ 1 - 11
frontend/src/store/modules/menu.js

@@ -1,15 +1,5 @@
 import Routes from '@/router/routes'
-
-function filterRoutes (routes, permissions) {
-  return routes.reduce((result, route) => {
-    const required = (route.meta && route.meta.permissions) || []
-    if (required.some(permission => !permissions.includes(permission))) return result
-    const copy = { ...route }
-    if (route.children) copy.children = filterRoutes(route.children, permissions)
-    result.push(copy)
-    return result
-  }, [])
-}
+import { filterRoutes } from './menuFilter'
 const state = {
   refresh: true, // 更新路由
   roles: Routes.routes,

+ 19 - 0
frontend/src/store/modules/menuFilter.js

@@ -0,0 +1,19 @@
+export function filterRoutes (routes, permissions) {
+  const granted = Array.isArray(permissions) ? permissions : []
+
+  return routes.reduce((result, route) => {
+    const copy = { ...route }
+    const hasChildren = Array.isArray(route.children) && route.children.length > 0
+
+    if (hasChildren) {
+      copy.children = filterRoutes(route.children, granted)
+      if (copy.children.length === 0) return result
+    } else {
+      const required = (route.meta && route.meta.permissions) || []
+      if (required.some(permission => !granted.includes(permission))) return result
+    }
+
+    result.push(copy)
+    return result
+  }, [])
+}

+ 78 - 0
tests/test_enterprise_identity_menu_filter_contract.py

@@ -0,0 +1,78 @@
+import base64
+import json
+import subprocess
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parents[1]
+FILTER = ROOT / "frontend/src/store/modules/menuFilter.js"
+ROUTES = ROOT / "frontend/src/router/routes.js"
+
+
+def _data_url(source: str) -> str:
+    encoded = base64.b64encode(source.encode("utf-8")).decode("ascii")
+    return f"data:text/javascript;base64,{encoded}"
+
+
+def _system_children(permissions: list[str]) -> list[str] | None:
+    script = f"""
+      const {{ filterRoutes }} = await import({_data_url(FILTER.read_text(encoding='utf-8'))!r})
+      const {{ default: routes }} = await import({_data_url(ROUTES.read_text(encoding='utf-8'))!r})
+      const system = filterRoutes(routes.routes, {json.dumps(permissions)}).find(
+        route => route.name === 'systemManage'
+      )
+      console.log(JSON.stringify(system ? system.children.map(route => route.name) : null))
+    """
+    completed = subprocess.run(
+        ["node", "--input-type=module", "--eval", script],
+        cwd=ROOT,
+        check=True,
+        capture_output=True,
+        text=True,
+    )
+    return json.loads(completed.stdout)
+
+
+def _strict_leaf_is_visible(permissions: list[str]) -> bool:
+    routes = [
+        {
+            "name": "parent",
+            "children": [
+                {
+                    "name": "strictLeaf",
+                    "children": [],
+                    "meta": {"permissions": ["first:read", "second:seal"]},
+                }
+            ],
+        }
+    ]
+    script = f"""
+      const {{ filterRoutes }} = await import({_data_url(FILTER.read_text(encoding='utf-8'))!r})
+      const visible = filterRoutes({json.dumps(routes)}, {json.dumps(permissions)})
+      console.log(JSON.stringify(Boolean(visible[0]?.children?.length)))
+    """
+    completed = subprocess.run(
+        ["node", "--input-type=module", "--eval", script],
+        cwd=ROOT,
+        check=True,
+        capture_output=True,
+        text=True,
+    )
+    return json.loads(completed.stdout)
+
+
+def test_identity_manager_keeps_system_manage_with_only_identity_child():
+    assert _system_children(["identity:manage"]) == ["systemEnterpriseIdentity"]
+
+
+def test_system_manage_is_hidden_without_any_system_child_permission():
+    assert _system_children([]) is None
+
+
+def test_user_manager_keeps_only_user_management_child():
+    assert _system_children(["users:manage"]) == ["systemUserManage"]
+
+
+def test_leaf_requires_all_of_its_permissions():
+    assert _strict_leaf_is_visible(["first:read"]) is False
+    assert _strict_leaf_is_visible(["first:read", "second:seal"]) is True