SCRUM-43 後台數據監控與管理實作分析

JIRA: SCRUM-43 Parent: SCRUM-14 (後台-數值管理頁、操作紀錄) 難度: ⭐⭐⭐⭐ (大型) 預估工作量: 5-7 天 主要工作: 前端 writeahead-admin-web + 後端 writeahead-main-api


功能概述

後台數據監控頁面,提供即時數據讓管理者確認平台狀況。包含時間篩選、10+ 核心指標、4 種時間序列圖表。


一、功能需求拆解

1.1 時間篩選模組

元件說明
快速切換按鈕全部 / 1日 / 1月 / 1年 / 自定義 (5 個)
自訂日期選擇器起始日期 + 結束日期 (點擊「自定義」時顯示)
清除按鈕重置篩選條件
篩選按鈕送出查詢

1.2 核心數據指標 (10 項)

#指標名稱類型計算方式
1活躍人數直接查詢期間內有登入的帳號數 (DISTINCT)
2做題總數直接查詢期間內全體做題累計
3平均做題數計算值做題總數 ÷ 活躍人數
4平均得分計算值總得分 ÷ 做題總數
5平均解題時間計算值總做題時間 ÷ 做題總數
6題目平均使用數計算值總批改數 ÷ 題庫總題數
7題目最大使用數統計值使用次數最多的題目 (顯示題號+次數)
8題目最小使用數統計值使用次數最少的題目 (顯示題號+次數)
9新增未批改總數直接查詢期間內建立但未批改的題目數
10平均未批改數計算值總未批改數 ÷ 活躍人數

1.3 資料圖表 (4 種)

圖表X 軸Y 軸預設
活躍人數表日期人數
做題總數表日期題數
做題數表日期題數
未批改總數表日期未批改數

切換方式: 下拉選單


二、技術架構

2.1 前端 (writeahead-admin-web)

app/pages/statistics/
└── index.vue                    # 主頁面

app/components/statistics/
├── time-filter.vue              # 時間篩選元件
├── core-metrics.vue             # 核心指標卡片群組
├── metric-card.vue              # 單一指標卡片
├── chart-selector.vue           # 圖表選擇器
└── time-series-chart.vue        # 時間序列折線圖

app/composables/
├── useStatistics.ts             # 統計頁面邏輯
└── useStatisticsApi.ts          # API 呼叫封裝

2.2 後端 (writeahead-main-api)

已存在:
├── app/Controllers/Admin/StatisticsController.php
└── app/Models/Admin/StatisticsModel.php

需新增/擴展:
├── POST /admin/statistics/getStatistics     # 核心指標 (擴展)
└── POST /admin/statistics/getChartData      # 圖表數據 (新增)

2.3 資料來源表

資料來源表
活躍人數logs_user_logins
做題/批改answer
題庫question

三、實作 Checklist

Phase 1: 後端 API (依賴: SCRUM-67, SCRUM-68)

核心指標 API 擴展

  • 確認現有 POST /admin/statistics/getStatistics 回傳格式
  • 擴展 StatisticsModel::getActiveUsersCount() 支援時間範圍
  • 擴展 StatisticsModel::getTotalAnswersCount() 支援時間範圍
  • 新增 StatisticsModel::getAverageScore() - 平均得分
  • 新增 StatisticsModel::getAverageSolvingTime() - 平均解題時間
  • 新增 StatisticsModel::getQuestionUsageStats() - 題目使用統計
    • 平均使用數
    • 最大使用數 (含題號)
    • 最小使用數 (含題號)
  • 新增 StatisticsModel::getUnreviewedStats() - 未批改統計
    • 總未批改數
    • 平均未批改數
  • 處理除以零情況 (NULLIFmax(divisor, 1))
  • 單元測試: tests/StatisticsModelTest.php

圖表數據 API

  • 新增 Controller 方法 StatisticsController::getChartData()
  • 新增 Model 方法 StatisticsModel::getTimeSeriesData($type, $start, $end)
  • 支援 4 種圖表類型:
    • active_users - 活躍人數
    • total_answers - 做題總數
    • answer_count - 做題數
    • unreviewed - 未批改總數
  • 日期填充 (無資料日期補 0)
  • 資料點限制 (建議 ≤ 365 點)

效能優化

  • 確認索引存在:
    • idx_answer_created_review on answer(created_at, is_review)
    • idx_answer_user_email on answer(user_email)
    • idx_logs_user_logins_created on logs_user_logins(created_at)
  • (選用) 快取熱門查詢 (Redis, TTL 5-15 分鐘)

Phase 2: 前端頁面

環境準備

  • 安裝圖表庫: npm install echarts vue-echarts
  • 設定 ECharts SSR 處理 (nuxt.config 或 plugin)

路由與頁面

  • 建立 app/pages/statistics/index.vue
  • 設定 layout: definePageMeta({ layout: 'default' })
  • 加入側邊欄選單項目 (若尚未存在)

時間篩選元件 (time-filter.vue)

  • 快速切換按鈕群組 (全部/1日/1月/1年/自定義)
  • 自訂日期 DatePicker x2 (起/迄)
  • 日期選擇器僅在「自定義」時顯示
  • 清除按鈕功能
  • 篩選按鈕 emit 事件
  • 預設值: 全部 (或月,依效能考量)

核心指標卡片 (core-metrics.vue + metric-card.vue)

  • 10 個指標卡片佈局 (Grid 或 Flex)
  • 單一卡片元件:
    • 指標名稱
    • 數值顯示
    • 載入狀態 (skeleton)
    • 特殊格式化 (時間顯示為 mm:ss、得分小數一位)
  • 「題目最大/最小使用數」顯示題號
  • 空值處理 (顯示 -N/A)

圖表區域 (chart-selector.vue + time-series-chart.vue)

  • 圖表類型下拉選單 (預設: 活躍人數表)
  • ECharts 折線圖元件
    • X 軸: 日期
    • Y 軸: 數值
    • Tooltip
    • 響應式寬高
  • <ClientOnly> 包裹圖表 (SSR 兼容)
  • 載入狀態處理
  • 空資料提示

Composables

  • useStatisticsApi.ts:
    • fetchCoreMetrics(params) - 核心指標
    • fetchChartData(type, params) - 圖表數據
  • useStatistics.ts:
    • 狀態管理 (loading, error, data)
    • 篩選條件響應式
    • 圖表類型切換

Phase 3: 整合測試

  • 時間篩選正確過濾資料
  • 全部範圍查詢效能測試 (>10 秒需優化)
  • 圖表切換不重複請求 (前端快取)
  • 響應式佈局 (桌面/平板)
  • 錯誤處理與使用者提示

四、API 規格草案

4.1 核心指標 API

Request: POST /admin/statistics/getStatistics

{
  "start_date": "2026-01-01",
  "end_date": "2026-02-06"
}

Response:

{
  "success": true,
  "data": {
    "active_users": 150,
    "total_answers": 1200,
    "avg_answers_per_user": 8.0,
    "avg_score": 78.5,
    "avg_solving_time": 1800,
    "question_avg_usage": 2.3,
    "question_max_usage": { "question_id": 15, "count": 78 },
    "question_min_usage": { "question_id": 3, "count": 2 },
    "total_unreviewed": 45,
    "avg_unreviewed_per_user": 0.3
  }
}

4.2 圖表數據 API

Request: POST /admin/statistics/getChartData

{
  "type": "active_users",
  "start_date": "2026-01-01",
  "end_date": "2026-02-06"
}

Response:

{
  "success": true,
  "data": {
    "labels": ["2026-01-01", "2026-01-02", "..."],
    "values": [12, 15, "..."]
  }
}

五、風險與注意事項

風險緩解措施
大時間範圍查詢慢預設「月」範圍、加索引、快取
除以零錯誤SQL 使用 NULLIF、前端顯示 N/A
圖表 SSR 錯誤<ClientOnly> 包裹
日期無資料後端填充或前端處理

六、依賴關係

SCRUM-67 (核心數據抽取)  ──┐
                           ├──→ SCRUM-43 (本任務)
SCRUM-68 (圖表數據抽取)  ──┘

建議順序: 先完成 SCRUM-67 + 68 後端 API,再進行 SCRUM-43 前端整合。


相關筆記


更新紀錄

日期更新內容
2026-02-06初始分析,建立 checklist