2026-10-06 探脈產出,唯讀盤點,供討論稿引用。路徑相對於
~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/。
views/role-manage/RoleForm.vue:456-516,用 PrimeVue TreeTable。Checkbox 自繪三態(空/勾/減號),CSS 在 :531 起。menuStore(:18)四份:uiRoutes(列,BE 回巢狀樹)、capabilityMenu(欄 action)、tenantMenu、enableStatusMenu。載入 onMounted → menuStore.initStaticMenu(stores/menuStore.js:268-278)。uiRoutes 巢狀樹(toTreeNodes :323-330;cellStateMap :350-365 遞迴算三態;群組列聚合子孫 capability :250-265)。getCapabilityActions(:83-98)把 capabilityMenu 依 action 去重,READ 排第一。isRcLicensed(:236-240)標在 route_capabilities[] 每筆,缺席時 fail-open。currRole.capabilities[]。is_platform 過濾:isTopTenant :41-45、isEditingRootTenantRole :46-54、stripPlatformRoutes :343-345、可指派 id 集合 :171-180、送出前濾 :209-220。config/api/api.js,兩頁直接用 BaseService):GET/POST/PUT API.ROLE(RoleForm :102/:128/:141)、存檔後 GET API.WEB_MENU(:148-149)、列表 POST API.ROLES(RoleManage :77)、PUT ROLE_STATUS(:94)、DELETE ROLE(:104)。常數 ROLES/ROLE/ROLE_STATUS :29-31、UI_ROUTES :32、ROLE_MENU :45、CAPABILITIES_MENU :481。views/user-manage/UserManageTabView.vue,兩 tab:UserManage.vue(列表)、UserManageUpload.vue(匯入)。表單 UserMTRBACForm.vue,個人資料 UserProfileForm.vue。UserMTRBACForm.vue:user_roles DataTable(:548-578,欄位租戶/部門/角色/是否預設);新增編輯 Dialog(:589-650)三個 Dropdown:租戶 :598、部門 :613、角色 :627、is_default InputSwitch :642。換租戶重載部門與角色 :381-386 → composables/useTenantScopedMenus.js:29-30(ORG_UNIT_MENU/ROLE_MENU 帶 tenant_id)。org_unit_id),但是扁平 Dropdown 不是樹。payload 每筆 {role_uid, tenant_id, org_unit_id, is_default}(:216-223)。effective_date/expire_date(Calendar :489/:501,payload :234-242)。每筆角色指派本身沒有起訖日。GET/POST/PUT API.USER(:166/:257/:268)、POST API.USERS(UserManage :74)、USER_CHANGE_STATUS(:176/:196)、匯入四支(Upload :102/:135/:157/:200)。components/user-manage/UserTenantGroupList.vue(91 行)。components/grc/project/ProjectParticipantsPanel.vue(108 行),用在 views/project/ProjectSettingsView.vue:104 與 views/project/ProjectPlanningView.vue:2427(tab index 3,query participants)。components/grc/ParticipantPicker.vue(176 行),新建專案也用它(ProjectCreateView.vue:406)。ParticipantPicker.vue:93-97 roleOptions(manager/reviewer/auditor/viewer,i18n lang.participant.role.*),新增預設 viewer(:55)。:66-73)。PUT API.GRC_PROJECT/{projectId} body {participants:[{user_uid, role}]}(Panel :76-80)。可選人員 menuStore.userMenu(GET API.USER_MENU)。能力點這套
userStore.permissions(stores/userStore.js:7,持久化 key cm_store)= /user/web-menu 回來的選單樹,節點 {label, icon, url, items[], capabilities:[{id, name, resource_type, action, requirement}]}。utils/userUtil.js:userCapabilities :24-37(扁平成 name Set)、hasCap(name) :42、getUserPagePermissions(url) :62-78。hasCap 約 13 支檔在用(例 components/integrations/GoogleDriveIntegrationCard.vue:218-222、views/scan-zone/ScanZoneManage.vue:30);getUserPagePermissions 例 views/project/ProjectListView.vue:36。config/router/index.js 只有 requiresAdmin(:1057-1066,判 userInfo.is_admin)與 requiresPlatformAdmin(:1071-1100)。:464/:873 註解明寫不依 ui_routes 擋直接輸入網址。側邊選單另依 url 濾 platform-only(layout/AppMenu.vue:24-45)。專案成員角色這套:沒有共用 helper,各頁自己拿 participants 比 userInfo.uid。
views/project/ProjectAuditorOverview.vue:isProjectManager :185-190、isAuditor :197、按鈕 :1152/:1160/:1172/:1205/:2095。views/project/ProjectPlanningView.vue:isProjectManager :378-383、myParticipantRole :386-391 → components/grc/ssp/SspTabPanel.vue:76(canEdit :92)。components/grc/FlowPhaseBanner.vue:230:isManager 吃 BE 回的 stageInfo.user_role。RoundAuditReviewView.vue:54-70、MyTasksView.vue:208-228、ProjectSettingsView.vue:53。/user/web-menu(WEB_MENU)回來直接寫入 userStore.permissions,寫入點:views/auth/Login.vue:205-206、OtpVerification.vue:216、layout/AppTopbar.vue:323-324(切租戶)、views/license/LicenseActivation.vue:164、RoleForm.vue:148-149。layout/AppMenu.vue:47-76。/auth/user-manage(:93-98)、/auth/role-manage(:101-106)、/auth/role-form(:109-114)、/auth/user-form-mtrbac(:117-122)。src/components/ 沒有 Tree、日期區間、矩陣、轉移清單的通用封裝。TreeSelect;<Tree> 僅 EditIncludeControlsDialog.vue:302(控制項專用)。部門資料是扁平清單(ORG_UNIT_MENU、menuStore.orgUnitMenu),部門管理頁 views/org-unit/OrgUnitManage.vue 用 DataTable+上層 Dropdown,沒有樹狀元件可直接複用。selectionMode="range" 在 AiUsageSummary.vue:171,其餘成對單日 Calendar。:456-516,CSS :531-605),未抽元件。PickList/OrderList。最接近 ParticipantPicker.vue、DeviceMultiSelect.vue(57 行)。composables/useTenantScopedMenus.js 可沿用。| 檔案 | 行數 |
|---|---|
| views/role-manage/RoleForm.vue | 605 |
| views/role-manage/RoleManage.vue | 265 |
| views/user-manage/UserMTRBACForm.vue | 651 |
| views/user-manage/UserManage.vue | 401 |
| views/user-manage/UserManageUpload.vue | 470 |
| views/user-manage/UserProfileForm.vue | 691 |
| components/grc/project/ProjectParticipantsPanel.vue | 108 |
| components/grc/ParticipantPicker.vue | 176 |
| views/project/ProjectPlanningView.vue | 2613(>800) |
| views/project/ProjectAuditorOverview.vue | 2161(>800) |
| views/project/RoundAuditReviewView.vue | 1077(>800) |
| views/project/MyTasksView.vue | 741 |
| components/grc/FlowPhaseBanner.vue | 627 |
| components/grc/ssp/SspTabPanel.vue | 510 |
| config/router/index.js | 1122(>800) |
重點:wildcard 完全沒有;起訖日只在使用者層不在指派層;部門範圍已存在但扁平下拉無樹;路由守衛不判能力點;專案成員四值寫死、判定邏輯散在 6 支以上檔案無共用 helper。