JianMiauandClaude Opus 4.8 68618a8e04 功能:記分板側欄新增得分紀錄清單,並讓左右兩欄底部切齊
根本原因:
計分時只能看到當前比分,沒有逐球紀錄可回顧;且右側欄在「比賽結算」下方留有大片閒置空間。原本 .scoreboard-screen 用 align-items: start,記分板維持自然高度、側欄卻撐滿,導致兩欄底部不齊。

影響:
計分頁右側欄在比賽結算按鈕下方顯示逐球得分表:每列一球,得分隊亮綠標記並顯示當下比分,最新在最上、可上下捲動看舊資料;記分板與側欄底部切齊、不超出畫面,多出的高度分配給上下分數面板,中間橫幅維持原高度。

修法:
App 把既有 pointLog 傳入 ScoreboardPage,新增 pointHistoryRows 反序累計比分並渲染 rail-history 清單;CSS 將 .scoreboard-screen 改 align-items: stretch(配合 align-self: start + min-height 100% 讓內容過高時可自然長高不重疊),.scoreboard-court 以 minmax(min-content, 1fr) 把撐高空間讓給隊伍區與分數面板;行動版清單改跨滿整行並以 32dvh 限高。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:11:22 +08:00

羽毛球記分板

這是一個使用 Vite + React + TypeScript + Node.js 製作的羽毛球記分板專案,提供手機優先的記分介面、歷史戰績、房間觀戰、語音播報、PWA 安裝,以及 Docker / NAS 部署方式。

功能特色

  • 選隊伍頁面
    • 可依指定日期從資料庫讀取分組資料。
    • 若當天沒有資料,可手動輸入 A、B 區名單建立配對。
    • 點進記分板時會直接帶入該組對戰。
  • 記分板
    • 兩隊隊員可自由交換上下、左右位置。
    • 畫面編號固定為左上 1、右上 2、右下 3、左下 4
    • 先攻只能在開局設定一次,之後不會跟著發球權改變。
    • 點擊分數直接加分,沒有加一減一按鈕。
    • 第一分開始後,設定隊伍 會改成 上一步
    • 比賽結算 需要長按 1 秒才會觸發,避免誤觸。
    • 達標分數後有獲勝動畫與結算流程。
    • 手機上會盡量壓縮成單頁滿版,避免上下滑動。
  • 羽球規則
    • 預設 21 分制,可在設定隊伍時調整目標分數。
    • 支援 Deuce20:20 後需領先 2 分才獲勝。
    • 29:29 時第 30 分直接獲勝。
    • 發球方依羽球規則處理,0 分在右發球區。
    • 畫面以下方隊伍為我方、上方隊伍為對方。
    • 上方隊伍採鏡像顯示,所以我方 0:0 在右邊發球時,對方會在左邊接發。
  • 語音播報
    • 只在按下加分當下播報,不會因復原或其他操作重複報分。
    • 可選擇是否播報得分與發球者。
    • 同隊連續得分才會播報 換邊發球
    • 支援調整語速,最高可到 10x
    • RURU 會做大小寫無關判斷並以指定發音播報。
  • 歷史戰績
    • 可從資料庫讀取歷史列表。
    • 點開單筆可查看得分過程。
    • 每筆資料可刪除,刪除前會顯示確認提示。
  • 房間觀戰
    • 記分板帶入隊伍後會自動建立房間。
    • 房間列表可查看目前直播中的比賽。
    • 觀戰者只能看,不能操作記分。
    • 分數、房間狀態、比賽結算會即時同步給觀戰者。
    • 房間失效、重整、重選隊伍後也會通知觀戰者。
    • 房間列表有 重新取得列表,並帶有 5 秒冷卻。
  • PWA
    • 可安裝到 iPhone / iPad / Android 主畫面。
    • 支援 Web App 模式啟動。
    • 新版本部署後會提示重新整理或重新安裝。

本機開發

Port

  • Client: 3501
  • Server: 8788

安裝

npm install

啟動開發模式

npm run dev

啟動後:

  • 前端:http://localhost:3501
  • APIhttp://localhost:8788

檢查

npm run lint
npm run build

記分板滿版模式

  • 記分板頁面會套用 100dvh 高度。
  • 手機進入記分板時會關閉頁面捲動與 overscroll。
  • viewport 已加上 viewport-fit=cover,較能貼合 iPhone / iPad 安全區。
  • 若手機高度較矮,會再縮小字級、按鈕與分數區,盡量維持整頁顯示。

環境變數

請先建立 .env

DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_DATABASE=badminton
DB_TABLE=badminton
DB_HISTORY_TABLE=history
PORT=8788

Docker / NAS 部署

對外服務配置:

  • 容器內 Node / API8788
  • 對外 HTTPS 網址:3501

部署指令:

sudo docker compose up -d --build

部署完成後可用:

https://你的網域或 NAS IP:3501

每次執行 sudo docker compose up -d --build 都會重新建置前後端與 PWA 靜態資產。

SSL 憑證

Docker Compose 會掛載以下目錄:

/volume1/docker/certs/

需包含:

  • cert.pem
  • chain.pem
  • privkey.pem

nginx 容器會監看這個目錄,更新憑證檔案後會自動重新載入,不需要重啟容器。

憑證到期偵測

  • 後端會讀取 cert.pem 的到期日,透過 /api/version/api/health 回報給前端。
  • 前端會把到期日存在 localStorage;當 API 出現 Failed to fetch 時,若存下來的到期日已過,會明確顯示「SSL 憑證已於某日過期」而不是通用錯誤。
  • 憑證到期前 7 天,頁面會跳出提醒更新憑證的通知。

資料表格式

history

  • id
  • time
  • dayOfWeek
  • score
  • winScore
  • type
    • 0: 雙打
    • 1: 單打
  • players
    • 依照 1 ~ 4 固定編號順序儲存玩家名單。
  • team
    • 12 一隊
    • 34 一隊
  • scoreList
    • 格式:[round, 發球者編號, 連勝數, 得分隊伍(0 或 1)]

PWA Icon

目前使用:

  • public/favicon.png
  • public/apple-touch-icon.png
  • public/pwa-192.png
  • public/pwa-512.png

Git 中文顯示

若要讓 git log / commit 顯示中文,建議設定:

git config i18n.commitEncoding utf-8
git config i18n.logOutputEncoding utf-8
git config core.quotepath false
S
Description
羽毛球記分板系統,可用於即時顯示比分、回合進度與比賽狀態。
https://jianmiau.tk:3501/
Readme
2.3 MiB
Languages
TypeScript 59.4%
CSS 24.3%
JavaScript 14.7%
Shell 1%
HTML 0.4%
Other 0.2%