Files
CFDivePlatform/openspec/changes/archive/2026-05-10-admin-panel/tasks.md
T
a620906209 ad2c05779d feat:實作 Admin Panel — 平台管理後台
後端:
- AdminStatsController:總會員/教練/課程數統計 API
- AdminUserController:會員與教練列表、詳情、啟用/停用、教練驗證(toggle 反轉語意)
- AdminOfferController:全平台課程列表與刪除
- routes/api.php:新增 /api/admin/stats、members、providers、offers 等路由

前端(frontend/):
- adminAuth store、adminAxios(第三套獨立認證)
- /admin/* 路由群組 + requiresAdmin guard
- AdminNavBar、AdminLayout
- App.vue:isCoachPage → isBackofficePage(/coach/* 和 /admin/* 皆隱藏會員 NavBar)
- LoginView、DashboardView(統計卡片)
- MembersView、ProvidersView(含驗證操作)、OffersView(含刪除確認)

OpenSpec:
- 新增 specs:admin-auth / admin-user-management / admin-offer-management / admin-stats / admin-panel-ui
- 歸檔:openspec/changes/archive/2026-05-10-admin-panel

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 04:07:13 +08:00

5.5 KiB
Raw Blame History

1. [後端] Admin Auth — 確認現有方法可用

  • 1.1 loginAdmin() 直接可用,確認 role=admin 驗證邏輯正確
  • 1.2 logoutAdmin() 直接可用,不需改動
  • 1.3 adminProfile() 直接可用,不需改動
  • 1.4 用 Postman 建立測試用 admin 帳號:docker exec cfdive-app php artisan tinker,建立 role=admin 的 User + AdminProfile,測試 login → profile → logout

2. [後端] AdminStatsController

  • 2.1 建立 AdminStatsController,實作 index():驗證 role=admin,查詢 User::where('role','member')->count()User::where('role','provider')->count()DivingOffer::count(),回傳統計數據
  • 2.2 在 routes/api.php 的 admin middleware group 新增 GET /stats 路由

3. [後端] AdminUserController

  • 3.1 建立 AdminUserController,宣告 private checkAdmin() helper(驗證 role=admin,不符回傳 403
  • 3.2 實作 members(Request $request):搜尋 role=member 用戶(q 參數 LIKE name/email),load memberProfile,分頁 15 筆
  • 3.3 實作 member(int $id)find role=member 用戶,不存在回 404load memberProfile 後回傳
  • 3.4 實作 toggleMemberActive(int $id)find → 404,反轉 is_active,回傳新狀態與對應訊息
  • 3.5 實作 providers(Request $request):同 members,查 role=providerload providerProfile
  • 3.6 實作 provider(int $id):同 member,查 role=providerload providerProfile
  • 3.7 實作 toggleProviderActive(int $id):同 toggleMemberActive,查 role=provider
  • 3.8 實作 toggleProviderVerified(int $id)find role=provider → 404,取得 providerProfile,反轉 is_verified,儲存,回傳新狀態
  • 3.9 在 routes/api.php admin group 新增路由:
    • GET /membersGET /members/{id}PUT /members/{id}/toggle-active
    • GET /providersGET /providers/{id}PUT /providers/{id}/toggle-activePUT /providers/{id}/toggle-verified

4. [後端] AdminOfferController

  • 4.1 建立 AdminOfferController,實作 index():驗證 admin,搜尋所有課程(q 參數 LIKE title/location),分頁 15 筆
  • 4.2 實作 destroy(int $id)find → 404,刪除,回傳 200
  • 4.3 在 routes 新增 GET /offersDELETE /offers/{id}

5. [前端] Admin 基礎設施

  • 5.1 建立 frontend/src/stores/adminAuth.js:管理 admin_token / admin_user,實作 init() / setAuth() / logout()
  • 5.2 建立 frontend/src/api/adminAxios.js:獨立 Axios instancerequest interceptor 讀 admin_token
  • 5.3 在 frontend/src/router/index.js 新增 /admin/* 路由:loginpublic+ dashboard / members / providers / offers / profilerequiresAdmin
  • 5.4 router beforeEach 加入 requiresAdmin guard,未登入導向 /admin/login
  • 5.5 在 App.vueonMounted 加入 adminAuth.init(),並擴充 isCoachPageisBackofficePage(涵蓋 /coach/*/admin/*),會員 NavBar 在這兩個路徑下都不顯示

6. [前端] Admin Layout 與導覽

  • 6.1 建立 frontend/src/components/AdminNavBar.vue:顯示管理員姓名、「儀表板」、「會員管理」、「教練管理」、「課程管理」連結與登出按鈕
  • 6.2 建立 frontend/src/layouts/AdminLayout.vue:包含 AdminNavBar + <RouterView>

7. [前端] 管理員登入頁

  • 7.1 建立 frontend/src/views/admin/LoginView.vueemail/password 表單,送出呼叫 POST /api/admin/login,成功存 token 至 adminAuth store 並導向 /admin/dashboard,失敗顯示錯誤

8. [前端] 儀表板

  • 8.1 建立 frontend/src/views/admin/DashboardView.vue:掛載時呼叫 GET /api/admin/stats,以三個數字卡片顯示總會員數、總教練數、總課程數

9. [前端] 會員管理頁

  • 9.1 建立 frontend/src/views/admin/MembersView.vue:掛載時呼叫 GET /api/admin/members,以表格顯示姓名、email、帳號狀態(啟用/停用 badge)
  • 9.2 新增搜尋框,輸入後按 Enter 重新呼叫 API(帶 q 參數)
  • 9.3 每列新增啟用/停用按鈕,呼叫 PUT /api/admin/members/{id}/toggle-active,成功後更新該列狀態

10. [前端] 教練管理頁

  • 10.1 建立 frontend/src/views/admin/ProvidersView.vue:掛載時呼叫 GET /api/admin/providers,顯示姓名、email、工作室名稱、驗證狀態、帳號狀態
  • 10.2 新增搜尋框
  • 10.3 每列新增啟用/停用按鈕(呼叫 toggle-active)與驗證/取消驗證按鈕(呼叫 toggle-verified),成功後更新對應欄位

11. [前端] 課程管理頁

  • 11.1 建立 frontend/src/views/admin/OffersView.vue:掛載時呼叫 GET /api/admin/offers,顯示課程標題、地點、地區、價格、provider_id
  • 11.2 新增搜尋框
  • 11.3 每列新增刪除按鈕:顯示確認 dialog,確認後呼叫 DELETE /api/admin/offers/{id},成功後重新載入列表

12. [整合測試] 端對端驗證

  • 12.1 驗證管理員登入流程:tinker 建立 admin 帳號 → 登入 → 顯示 AdminNavBar → 登出
  • 12.2 驗證 Dashboard 統計數據正確顯示
  • 12.3 驗證會員管理:搜尋 → 停用 → 確認帳號無法登入 → 重新啟用
  • 12.4 驗證教練驗證:切換 is_verified → 確認 /coach/profile 顯示狀態更新
  • 12.5 驗證課程刪除:Admin 刪除課程 → 確認 /courses 列表消失
  • 12.6 驗證 route guard:未登入訪問 /admin/dashboard 自動跳轉 /admin/login
  • 12.7 驗證 /admin/* 路由不顯示會員 NavBar