# System Permission Org View Authorization Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Add `脑图模式 / 组织树模式` to system permission organization management, move personnel authorization/account creation onto org personnel nodes, and simplify the maintenance tab into role-only maintenance. **Architecture:** Keep the existing backend permission APIs and refactor the frontend around two organization views that share one data source. `SystemPermissionView.vue` owns data loading, drawers, authorization submission, and role maintenance; a new focused `OrgPermissionTree.vue` renders the Ruoyi-like left-tree/right-personnel-list organization tree mode. **Tech Stack:** Vue 3 ` ``` - [ ] **Step 3: Add scoped styles** Add this style block: ```vue ``` - [ ] **Step 4: Run static test and verify current next failure** Run: ```bash node frontend/scripts/test-system-permission-management-ui.mjs ``` Expected result: ```text AssertionError ``` The component-specific assertions should pass; failures should now point to `SystemPermissionView.vue` still using the old page structure. --- ### Task 3: Refactor SystemPermissionView Page Structure **Files:** - Modify: `frontend/src/views/SystemPermissionView.vue` - [ ] **Step 1: Import the new component** Add the import beside `OrgMindMap`: ```js import OrgPermissionTree from "../components/OrgPermissionTree.vue"; ``` - [ ] **Step 2: Replace top copy and tabs** Change the hero copy to: ```vue

组织架构负责公司层级、人员授权和系统账号;角色维护负责菜单权限和业务身份。

``` Change the top tab labels to: ```vue 组织架构 角色维护 ``` Keep `permissionMainTab` values as `"org"` and `"maintenance"` to minimize routing/state churn. - [ ] **Step 3: Add organization mode switch** Add this state near `permissionMainTab`: ```js const orgViewMode = ref("mindmap"); ``` Inside the organization section header, add this switch before the status pill: ```vue
``` - [ ] **Step 4: Render mind map or tree mode** Wrap the existing `OrgMindMap` with: ```vue ``` Add this computed near `orgNodeCount`: ```js const selectedOrgNodeId = computed(() => selectedNode.value?.node_id || orgNodes.value[0]?.node_id || ""); ``` - [ ] **Step 5: Hide mind-map-only toolbar in tree mode** Change the toolbar container to: ```vue
``` Keep `放大`、`缩小`、`一屏展示`、`刷新` unchanged. - [ ] **Step 6: Replace maintenance page with role-only page** Remove the nested `system-permission-sub-tabs` block and remove the `maintenanceSubTab === 'users'` table panel. The maintenance section header should become: ```vue

角色权限

角色维护

角色用于配置菜单权限和业务身份;人员授权请回到组织架构中对人员节点操作。

``` Remove: ```js const maintenanceSubTab = ref("users"); const userRowsForTable = computed(() => users.value); const { page: userPage, pageSize: userPageSize, rows: paginatedUsers } = usePagination(userRowsForTable); ``` Keep: ```js const users = ref([]); ``` because authorization needs it to detect existing system accounts. - [ ] **Step 7: Run static test and verify authorization assertions still fail** Run: ```bash node frontend/scripts/test-system-permission-management-ui.mjs ``` Expected result: ```text AssertionError ``` The remaining failure should be around missing authorization drawer functions/state. --- ### Task 4: Add Personnel Authorization Drawer and Logic **Files:** - Modify: `frontend/src/views/SystemPermissionView.vue` - [ ] **Step 1: Add authorization state** Add these declarations near existing drawer state: ```js const showAuthorizeDrawer = ref(false); const authorizingEmployee = ref(null); const authorizeForm = reactive({ role_ids: [], password: "", status: "ACTIVE" }); ``` Add these computed values near `selectedEmployee`: ```js const authorizingSystemUser = computed(() => { const employeeId = authorizingEmployee.value?.employee_id; if (!employeeId) { return null; } return users.value.find((user) => String(user.employee_id) === String(employeeId)) || null; }); const authorizingEmployeePhone = computed(() => authorizingEmployee.value?.mobile || authorizingSystemUser.value?.mobile || authorizingSystemUser.value?.username || "" ); ``` - [ ] **Step 2: Add authorization drawer template** Insert this drawer before the role drawer: ```vue
``` - [ ] **Step 3: Add open and submit functions** Add these functions near `removeOrgEmployee`: ```js function openAuthorizeDrawer(employee) { const existingUser = users.value.find((user) => String(user.employee_id) === String(employee?.employee_id)); authorizingEmployee.value = employee; authorizeForm.role_ids = existingUser?.role_ids?.length ? existingUser.role_ids.map(String) : (employee?.role_ids || []).map(String); authorizeForm.password = ""; authorizeForm.status = existingUser?.status || "ACTIVE"; showAuthorizeDrawer.value = true; } async function submitAuthorizeUser() { if (!authorizingEmployee.value?.employee_id) { notifyError("请选择有效人员"); return; } if (!authorizingEmployeePhone.value) { notifyError("该人员没有电话号码,不能作为账号"); return; } if (!authorizeForm.role_ids.length) { notifyError("请选择角色"); return; } if (!authorizingSystemUser.value && (!authorizeForm.password || authorizeForm.password.length < 6)) { notifyError("密码最少6位"); return; } try { if (authorizingSystemUser.value) { await putResource(`/system-permissions/users/${authorizingSystemUser.value.user_id}/roles`, { role_ids: authorizeForm.role_ids.map(Number) }); if (authorizingSystemUser.value.status !== authorizeForm.status) { await putResource(`/system-permissions/users/${authorizingSystemUser.value.user_id}/status`, { status: authorizeForm.status }); } notifySuccess("人员角色授权已更新"); } else { await postResource("/system-permissions/users", { employee_id: Number(authorizingEmployee.value.employee_id), role_ids: authorizeForm.role_ids.map(Number), password: authorizeForm.password, status: authorizeForm.status }); notifySuccess("系统账号已创建并授权"); } showAuthorizeDrawer.value = false; authorizingEmployee.value = null; await loadAll(); } catch (error) { notifyError(error.message || "人员授权失败"); } } ``` - [ ] **Step 4: Update employee context menu actions** Change `nodeActions(node)` employee branch to: ```js if (node.employee_id) { return [ { key: "authorizeEmployee", label: "授权" }, { key: "removeEmployee", label: "移除" } ]; } ``` Add this branch to `runNodeAction`: ```js } else if (actionKey === "authorizeEmployee") { openAuthorizeDrawer(node); ``` - [ ] **Step 5: Remove standalone user drawer code** Delete the old drawer controlled by: ```js showUserDrawer createUserForm openUserDrawer submitCreateUser syncSelectedEmployeePhone resetPassword toggleUserStatus formatRoleNames(user) ``` Do not delete `users`, `loadAll()` user loading, or `employeeOptions`. - [ ] **Step 6: Run static test** Run: ```bash node frontend/scripts/test-system-permission-management-ui.mjs ``` Expected result: ```text all assertions pass ``` If the script prints no output and exits `0`, treat it as pass. --- ### Task 5: Add Styling for Switch, Tree Layout, and Authorization Summary **Files:** - Modify: `frontend/src/views/SystemPermissionView.vue` - [ ] **Step 1: Add view switch styles** Add this CSS near `.mindmap-toolbar`: ```css .org-view-switch { display: inline-flex; gap: 6px; padding: 6px; border: 1px solid rgba(37, 99, 235, 0.12); border-radius: 999px; background: rgba(239, 246, 255, 0.92); } .org-view-switch button { border: 0; border-radius: 999px; padding: 8px 12px; background: transparent; color: #475569; font-size: 13px; font-weight: 800; cursor: pointer; } .org-view-switch button.active { background: #ffffff; color: #1d4ed8; box-shadow: 0 10px 20px rgba(37, 99, 235, 0.14); } ``` - [ ] **Step 2: Add authorization summary styles** Add this CSS near drawer styles: ```css .authorize-summary { display: grid; gap: 8px; border: 1px solid rgba(37, 99, 235, 0.12); border-radius: 16px; padding: 12px; background: #f8fbff; color: #475569; font-size: 13px; font-weight: 700; } ``` - [ ] **Step 3: Remove obsolete sub-tab styles** Delete CSS blocks for: ```css .system-permission-sub-tabs .system-permission-sub-tabs button .system-permission-sub-tabs button.active ``` Also remove the mobile media override for `.system-permission-sub-tabs`. - [ ] **Step 4: Run frontend build** Run: ```bash cd frontend && npm run build ``` Expected result: ```text ✓ built ``` Chunk-size warnings are acceptable if the build exits `0`. --- ### Task 6: Backend Regression Verification **Files:** - Test only: `backend/tests/test_system_permission_management.py` - [ ] **Step 1: Run backend permission tests** Run: ```bash cd backend && python -m pytest tests/test_system_permission_management.py -q ``` Expected result: ```text passed ``` - [ ] **Step 2: If tests fail due to local environment only, capture the exact blocker** Acceptable environment blockers include missing Python packages or unavailable virtual environment. Record the exact error text in the execution summary. Do not change backend code unless a real regression is identified. --- ### Task 7: Browser Verification **Files:** - No file changes. - [ ] **Step 1: Start or reuse frontend dev server** Run: ```bash cd frontend && npm run dev -- --host 127.0.0.1 --port 5173 ``` Expected result: ```text Local: http://127.0.0.1:5173/ ``` - [ ] **Step 2: Verify page structure in browser** Open: ```text http://127.0.0.1:5173/system-permissions ``` Verify: - Top tabs are `组织架构` and `角色维护`. - `组织架构` has `脑图模式 / 组织树模式`. - `脑图模式` still shows mind-map toolbar. - `组织树模式` shows left organization tree and right personnel table. - `角色维护` does not show standalone system personnel table. - [ ] **Step 3: Verify personnel authorization interaction** In browser: - In mind-map mode, expand a node with personnel, right-click a personnel leaf, verify menu shows `授权` and `移除`. - Click `授权`, verify drawer displays phone/account, organization, account status, role selector, and password only when no account exists. - In tree mode, select an org node with personnel, verify row actions show `授权` and `移除`. Expected result: ```text Both modes can reach the same authorization drawer. ``` --- ## Self-Review - Spec coverage: - Organization view switch: Task 3. - Tree mode UI: Task 2 and Task 7. - Mind-map employee right-click `授权/移除`: Task 4. - Role-only maintenance tab: Task 3. - Account creation and role update from personnel node: Task 4. - Tests and verification: Tasks 1, 5, 6, 7. - Placeholder scan: - No `TBD`, `TODO`, or vague implementation-only placeholders remain. - Type consistency: - `orgViewMode`, `showAuthorizeDrawer`, `authorizingEmployee`, `authorizeForm`, and `selectedOrgNodeId` are introduced before use. - `OrgPermissionTree` emits `select-node`, `node-contextmenu`, `add-employee`, `authorize-employee`, `remove-employee`; `SystemPermissionView.vue` listens to the same names. - Existing backend endpoint names match `backend/app/api/routes/system_permissions.py`.