手冊首頁 / 租戶與組織 / 使用者管理

使用者管理(User Management)

功能群:系統管理|三層 RBAC 模型與租戶/部門組織模型先讀 功能群總覽 §2、§3

事實基準:2026-07-05 從 FE src/views/user-manage/UserManageTabView.vue / UserManage.vue)+ BE api/auth/routes/user_route.py + jedi-auth user_service.py / user_domain_service.py + routes.json / db_schema.json 掃出。

變更紀錄

日期 FR 變更
2026-07-06 FR-047 改造成 hub 導航頁:帳號表單拆至 使用者表單、Excel 匯入拆至 Excel 批次匯入;本頁保留 Tab0 帳號列表與列操作

1. 功能描述

使用者管理是本系統帳號本體的維護入口:Tab 結構(UserManageTabView.vue),Tab0「帳號管理」是帳號列表(UserManage.vue,含搜尋 / 建立導向 / 每列停用啟用刪除),Tab1「Excel 批次上傳」是批次匯入精靈。本頁作為導航 hub:帳號的新增 / 編輯走獨立表單子頁,Excel 批次匯入走獨立精靈子頁,列表本身與列上的狀態操作留在本頁。

主要使用者:系統 / 租戶管理員。權限治理(角色如何綁能力)由 角色權限管理 負責;本頁只做「使用者 ↔︎ 角色/租戶/部門」的指派入口。

角色速覽(完整定義見 _overview §2、§3):

角色 一句話
系統 / 租戶管理員(可見本選單者) 帳號 CRUD + 授權組合指派 + 批次匯入
is_admin(超級管理員 JWT 旗標) 額外可在編輯他人帳號時代改密碼;admin 帳號本身的敏感欄位(生效/到期日、刪除授權)鎖死
一般使用者 無此選單(ui_routes 可見性未命中)

1.1 功能總覽(本頁全部功能)

本頁是 hub(帳號列表 + 列操作 + 子頁導航):帳號新增/編輯表單與 Excel 批次匯入各自的 field-level 逐欄規格拆成子頁,見「詳述」欄連結。

# 功能 說明 位置 詳述
1 帳號列表 分頁表列所有使用者(登入代碼 / 名稱 / Email / 電話 / 狀態 / 租戶 / 部門 / 角色 / 登入軌跡 / 建立更新軌跡),多欄排序 Tab0 DataTable §6.2
2 搜尋帳號 login_name / nickname / email 全域關鍵字搜尋(Enter 觸發) Tab0 工具列
3 重設搜尋 清空關鍵字 / 排序 / 分頁回第一頁 Tab0 工具列
4 租戶 / 部門 / 角色 欄位展開收合 每格預設顯示 3 個 Chip,超過顯示 +N...,點擊展開全部 / 收合 Tab0 每列
5 建立帳號 導向 user-form(新增模式) Tab0 工具列 使用者表單
6 編輯帳號 導向 user-form?uid=(編輯模式),可點「編輯」鈕或登入代碼連結 Tab0 每列 使用者表單
7 停用 / 啟用帳號 切換 status(1↔︎-1);admin 帳號與登入者自己隱藏此鈕 Tab0 每列 §6.3
8 刪除帳號 軟刪除(status=-2);admin 與登入者自己隱藏此鈕 Tab0 每列 §6.3
9 Excel 批次上傳 Tab1 三步精靈(下載範本 → 上傳解析 → 勾選批次建立) Tab1 Excel 批次匯入

展開成 UC(見 §2 索引):帳號本體 CRUD 與授權組合指派在 使用者表單(UC-USER-01/02)、Excel 批次匯入在 Excel 批次匯入(UC-USER-03)。停用 / 刪除屬單一動作,於本頁 §6.3 描述,不另開 UC 流程圖。

2. Use Case(索引)

角色速覽(完整定義見 _overview §2、§3):

角色 一句話
系統 / 租戶管理員(可見本選單者) 帳號 CRUD + 授權組合指派 + 批次匯入
is_admin(超級管理員 JWT 旗標) 額外可在編輯他人帳號時代改密碼;admin 帳號本身的敏感欄位鎖死
一般使用者 無此選單

本頁三條核心路徑展開成 UC,逐條在子頁:

UC 主題 所在子頁
UC-USER-01 建立 / 編輯帳號主流程 使用者表單
UC-USER-02 授權組合(租戶 × 部門 × 角色)指派 使用者表單
UC-USER-03 Excel 批次匯入三步 Excel 批次匯入

列上的停用 / 啟用 / 刪除為單一動作,走本頁 §6.3。

3. 權限矩陣

專案層 RBAC 基調見 _overview §5。本頁(列表 + 列操作)的實際檢查點:

操作 FE 判定 BE 強制 BE 檢查位置
進入本頁 ui_routes web-menu 可見性(user 相關能力) 無端點層強制(僅 @jwt_required api/auth/routes/user_route.py(全部 method)
刪除帳號(軟刪) FE 對 login_name=='admin' 與登入者自己隱藏刪除鈕 ⚠️ 僅 @jwt_requiredBE 未擋 admin / 自刪 user_route.py:103-110UserRoute.delete
停用 / 啟用 同上(FE 隱藏規則相同) ⚠️ 僅 @jwt_requiredBE 未擋 admin / 自我停用 user_route.py:130-138UserChangeStatusRoute.post

建立 / 編輯帳號的權限見 使用者表單 §3;Excel 批次匯入見 Excel 批次匯入 §3

⚠️ 本頁列操作端點缺角色守門UserChangeStatusRouteUserRoute.delete 僅掛 @jwt_required(),jedi-auth update_user_status 內部也無角色檢查——任何已登入帳號皆可透過直打 API 停用 / 刪除他人帳號(含 admin,因「不可動 admin」只是 FE 隱藏按鈕)。與 _overview §5role-manage.md §3 一致(本群多頁通病)。收進 §12。

4. 狀態機與前置條件

帳號本身狀態單純:users.status0 未啟用 / 1 啟用 / -1 停用 / -2 軟刪除),無跨頁狀態機(不同於稽核輪次 7 態)。本頁(列表)gate:

條件 效果 出處
login_name === 'admin'login_name === 登入者自己 FE 隱藏停用 / 啟用 / 刪除鈕 UserManage.vue:254,261v-if
BE 寫入無狀態前置檢查 update_user_status 本身不檢查呼叫者角色,任何狀態的帳號都可被切換(唯一狀態轉換在此專職) jedi-auth user_domain_service.py:169

表單頁 gate(admin 鎖死、mode EDIT 鎖登入名稱、is_admin 代改密碼、is_default 唯一規則)見 使用者表單 §4

5. UI 設計

[0] 帳號管理(本頁) 開啟:使用者 Excel 批次匯入 spec [1] Excel 批次上傳 → user-import.md(UC-USER-03) 工具列:關鍵字搜尋(login_name/nickname/email)・重設 POST /users(分頁 body: pager/sort/filters) 開啟:使用者表單 spec(新增模式) +建立帳號 → Tab [0] 帳號列表 — 本頁主工作區(DataTable) 登入代碼|名稱|Email|電話|狀態|租戶/部門/角色(Chip 展開)|登入軌跡|建立更新軌跡|功能 alice ・ Alice ・ 啟用 ・ 租戶 A / 稽核部 / manager… Chip 每格預設 3 個,超過 +N 點擊展開 開啟:使用者表單 spec(編輯模式) 編輯 → GET/PUT /user 停用/刪除 POST …/change-status admin/自己隱藏 分頁 / 排序(useTableQuery:scope-by-route + scope-by-user) 狀態欄以 system_menus/USER_STATUS 轉譯文字(非數字) 彩色=有獨立子頁的區塊,整塊可點擊跳轉(teal=使用者表單/coral=Excel 匯入)|灰=hub 本頁描述|虛線框=條件顯示(admin/自己隱藏) API 僅列代表性,完整規格見 §6 與各子頁 §6
使用者管理 hub 版面 wireframe:Tab0 帳號列表(搜尋/建立/每列停用刪除)為本頁;建立/編輯導向使用者表單子頁、Tab1 導向 Excel 批次匯入子頁,皆可點跳轉

📸 實機截圖待補(亮色模式)。待補清單:Tab0 帳號列表(含租戶/部門/角色 Chip 展開態)、Tab1 Step1 上傳 dropzone、Tab1 Step2 預覽表格(含錯誤欄位紅字態)。

Tab0 列表頁骨架

user_list_layout layout 使用者管理 — Tab0 帳號管理 搜尋框(login_name/nickname/email) 重置查詢 建立帳號 功能 (編輯/停用啟用/刪除) 登入代碼 名稱 Email 電話 狀態 租戶(Chip) 部門(Chip) 角色(Chip) 登入軌跡 建立/更新軌跡 編輯|停用|刪除 (admin/自己隱藏後二者) row 1 row 1 row 1 row 1 row 1 租戶A, 租戶B, +2... 部門A, +1... 角色A, 角色B, 角色C row 1 row 1 分頁器:CurrentPageReport + 頁碼 + RowsPerPage(10/25/50)
使用者管理列表版面:搜尋列+重置+建立鈕;DataTable 欄位=功能/登入代碼/名稱/Email/電話/狀態/租戶/部門/角色/登入軌跡/建立更新軌跡;admin與自己隱藏停用刪除

狀態呈現:列表狀態欄以 system_menusUSER_STATUS group 轉譯文字(非直接顯示數字);Excel 匯入用 Steps 元件呈現 Step1(上傳)/ Step2(預覽),依 users.length 是否 > 0 自動判定(詳見 Excel 批次匯入 §5);表單頁狀態呈現見 使用者表單 §5

6. API 規格

Envelope:成功 {"code": 1, "data": …}、失敗 {"code": 0, "msg": "…"}

6.1 總清單(本 hub 呼叫的 endpoint)

分類 Method + Path 說明 完整規格
列表 POST /api/1.0/users 分頁查詢使用者(body 帶 pager / sort / filters) §6.2
選單 GET /api/1.0/users/menu 使用者下拉(uid / login_name / nickname / email) Swagger
選單 GET /api/1.0/system/menu/USER_STATUS 帳號狀態下拉(system_menus code table) Swagger
刪除 DELETE /api/1.0/user/<uid> 軟刪除(實際呼叫 update_user_status(REVOKE) Swagger
狀態 POST /api/1.0/user/change-status/<uid> 停用 / 啟用 / 軟刪除(body status §6.3

帳號 CRUD(POST/PUT/GET /user)見 使用者表單 §6;Excel 匯入四支見 Excel 批次匯入 §6

6.2 使用者列表

[POST] /api/1.0/users(列表)

Request(UserPageQueryRequest extends RequestMetaSchema):

欄位 型別 必填 說明
pager object 分頁參數 {page, page_size, with_total}
sort object 排序參數
filters object 查詢條件(UserQueryRequest),下列子欄位皆選填
filters.uid string 對外識別碼
filters.login_name string 登入代碼
filters.department_id int 部門 id
filters.job_title string 職稱
filters.nickname string 顯示名稱
filters.email string Email
filters.tel string 電話
filters.effective_date date 帳號生效日
filters.expire_date date 帳號到期日

Response data[]UserResponse exclude salt/passwordapi/auth/serializers/user.py:36-75)(陣列,每項):

欄位 型別 說明
id int 內部序號
uid string 對外識別碼
login_name string 登入代碼
nickname string 顯示名稱
email string Email
tel string 電話
job_title string 職稱
status int 帳號狀態
department_id int 部門 id
tenant_id / tenant_uid / tenant int / string / object 預設租戶 id / uid / Nested
tenants[] array Nested TenantResponse,全部租戶
org_unit_id / org_unit_uid / org_unit int / string / object 預設部門 id / uid / Nested
org_units[] array Nested OrgUnitResponse,全部部門
roles[] array Nested RoleResponse
user_roles[] array Nested UserRoleResponse
user_tenants[] / user_org_units[] array 使用者 ↔︎ 租戶 / 部門關聯
is_super_admin bool 超級管理員旗標
employee_id string 員工編號
effective_date / expire_date datetime 帳號生效 / 到期日
mfa_type string 多因素驗證類型
last_login_success_time / last_login_failed_time / login_failed_count datetime / datetime / int 登入軌跡
created_user(+_name) / created_at string / datetime 建立者 login_name(+ nickname)/ 建立時間
updated_user(+_name) / updated_at string / datetime 更新者 login_name(+ nickname)/ 更新時間

出處:api/auth/routes/user_route.py:37-54UsersRoute.post)→ app/auth/service/user_app_service.py:19-22get_users_and_pager,批次 enrich created_user_name/updated_user_name)。

單一使用者明細 GET /user/<uid>(含 auth_providers[])見 使用者表單 §6.2

6.3 狀態變更

[POST] /api/1.0/user/change-status/

Request:

{
  "status": 0 // 1 啟用 / -1 停用 / -2 軟刪除
}

(FE 只會送這三種值,BE 無值域檢查)。Response:BooleanResponse{result: true})。出處:user_route.py:130-138user_domain_service.py:169update_user_status)。FE 呼叫點:UserManage.vue:163(停用/啟用切換)、:183(刪除,固定送 -2)。DELETE /user/<uid> 內部亦委派 update_user_status(REVOKE)

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/user-manage/UserManageTabView.vue route user-manage 的實際 component;包兩個 Tab(帳號管理 / Excel 批次上傳)
src/views/user-manage/UserManage.vue Tab0:帳號列表 DataTable(搜尋 / 建立 / 每列操作 / 租戶部門角色 Chip 展開)
src/views/user-manage/UserManageUpload.vue Tab1:Excel 批次上傳(詳見 Excel 批次匯入 §7
src/views/user-manage/UserMTRBACForm.vue route user-form(建立 / 編輯表單,詳見 使用者表單 §7
src/views/user-manage/UserProfileForm.vue 個人資料頁(/user/user-profile),另屬 個人資料,非本頁
src/composables/useTableQuery.js 列表分頁 / 排序 / 搜尋狀態共用邏輯(含 scope-by-route + scope-by-user)
src/stores/queryStore.js 持久化查詢狀態(供 useTableQuery 讀寫,支援「重置查詢」)
src/config/api/api.js:32-42 USERS / USER / USER_MENU / USER_CHANGE_STATUS 等端點常數

8. 後端檔案地圖

鏈路 Route App Service 底層
使用者列表(enrich 暱稱) api/auth/routes/user_route.py::UsersRoute app/auth/service/user_app_service.py::get_users_and_pager jedi-auth UserService.get_users_and_pagerUserDomainService
狀態變更 / 軟刪除 user_route.pyUserChangeStatusRoute / UserRoute.delete 直接委派 jedi-auth user_domain_service.py::update_user_status

帳號 CRUD 鏈路見 使用者表單 §8;Excel 匯入鏈路見 Excel 批次匯入 §8

DDD 提醒:使用者列表與狀態變更的 route 直接注入 jedi-auth 的 UserService,主專案在這條鏈路只有 UserAppService(列表暱稱 enrich)一個 app service。大半 domain 邏輯在 jedi-auth 套件(~/Projects/Jedicogy/module/jedi-python-package/jedi-auth/),改行為要分清邊界(CLAUDE.md 外部套件異動規範)。

9. DB

9.1 資料表總清單(本 hub 讀寫的表)

讀/寫 說明 詳述
public.users 讀 / 寫(狀態欄) 帳號本體;本頁列表讀、列操作寫 status 使用者表單 §9.3
public.roles / public.tenants / public.org_units 列表 Chip 顯示租戶 / 部門 / 角色 _overview §6
public.system_menus USER_STATUS group:帳號狀態下拉文字 _overview §4

帳號本體與授權組合的寫入表(user_roles / user_tenants / user_org_units / 改密相關)完整欄位卡見 使用者表單 §9

9.2 ER 圖

user_er users public.users (帳號本體,寫) user_roles public.user_roles (授權組合,寫,全量取代) users->user_roles user_id user_tenants public.user_tenants (寫,全量取代) users->user_tenants user_id user_org_units public.user_org_units (寫,全量取代) users->user_org_units user_id chg_req public.user_change_password_request (寫,新增時建立) users->chg_req user_id chg_log public.user_change_pwd_logs (寫,代改密碼時) users->chg_log user_id auth_providers public.user_auth_providers (唯讀) users->auth_providers user_id roles public.roles (唯讀依賴) user_roles->roles role_id tenants public.tenants (唯讀依賴) user_roles->tenants tenant_id(授權邊界,nullable) org_units public.org_units (唯讀依賴) user_roles->org_units org_unit_id(授權邊界,nullable) user_tenants->tenants tenant_id user_org_units->org_units org_unit_id
使用者管理讀寫範圍:綠=本頁寫入(users/user_roles/user_tenants/user_org_units/改密相關)、黃=唯讀依賴(roles/tenants/org_units)

10. 頁面邏輯與資料對應

關鍵欄位對應(列表 API ↔︎ 畫面):

畫面元素 FE state API 欄位
帳號狀態欄(列表) statusMenusystem_menus/USER_STATUS)+ data.status transStatusCode() 轉譯 i18n
租戶 / 部門 / 角色 Chip(列表) data.tenants[] / data.org_units[] / data.roles[] UserResponse.tenants/org_units/roles(Nested 陣列)

表單頁與 Excel 匯入的載入時序 / 欄位對應 / 儲存流程見 使用者表單 §10Excel 批次匯入 §10

11. 背景行為與外部依賴

類型 內容
通知 無(列表 / 列操作本身不發通知;帳號建立信在 使用者表單
Job / 排程
Socket 無:帳號列表無即時推播,改動後靠前端重打 getUsers()
jedi-* 套件 jedi-auth 擁有使用者 / 角色 / 租戶 / 部門的 service / domain / repo / ORM 全部邏輯;主專案僅列表 enrich(UserAppService)一個 wrapper
系統參數 無 feature flag

12. 邊界情況與已知坑

  1. 本頁列操作端點缺角色守門(同 角色權限管理 模式):UserChangeStatusRouteUserRoute.delete@jwt_required(),jedi-auth service 層也無角色檢查——任何登入帳號可直打 API 停用 / 軟刪除任何人(含 admin,因「不可動」只是 FE 隱藏按鈕)。本 spec 只記錄不修。表單寫入與 Excel 匯入的同類坑見 使用者表單 §12Excel 批次匯入 §12
  2. login_failed_count / last_login_* 唯讀但可排序:這幾欄由登入流程寫入,本頁列表可排序顯示,但無編輯 UI(正確:不該有編輯 UI)。
  3. admin 帳號的鎖死規則分散在多處判斷(本頁:列表停用/刪除鈕隱藏;表單頁另有生效/到期日禁用等,見 使用者表單 §12):皆為 FE 字串比對 login_name==='admin',BE 無對應保護(見坑 1)——非 FE 判斷點若新增功能,記得同步排除 admin

13. 開發與驗證

  • 跑起來:BE python main_socketio.py(port 8000,log 在 log/app.log);FE 在 compliance-manager-fe/ 起 Vite dev server。BE 改 service code 後必須重啟(無 hot reload)。
  • 測試帳號:管理員帳號見 memory reference_dev_login / .env(憑證不寫入本文件)。
  • 導航路徑:登入 → 側選單「系統管理」→「使用者管理」(/auth/user-manage)→ Tab「帳號管理」或「Excel 批次上傳」。
  • 前置資料:至少一個租戶 + 一個部門 + 一個角色(tenant_id NULL 的系統角色亦可)才能完成授權組合指派。
  • E2Ecompliance-manager-test/ repo(Cucumber + Playwright);本頁相關 feature 檔以 使用者管理 / user-manage 搜尋。
  • 相關文件使用者表單(帳號本體 CRUD + 授權組合);Excel 批次匯入;權限系統設計說明書 docs/system-design/permission/角色權限管理功能群總覽