羽毛球記分板

使用 Vite + React + TypeScript + Node.js 製作的羽毛球記分板支援選隊伍、即時記分、歷史戰績、PWA 安裝,以及即時房間觀戰。

功能

  • 選隊伍
    • 可依指定日期從資料庫載入分組資料。
    • 若資料庫沒有當天資料,可手動輸入 A、B 區名單產生分組。
    • 點選分組後可直接進入記分板。
  • 記分板
    • 隊伍名稱只顯示在最上方與最下方。
    • 可在設定隊伍面板中逐一選人,也可快速套用預設隊伍。
    • 先選到的 1、2 為一隊,3、4 為另一隊。
    • 可設定本場幾分獲勝,預設為 21 分。
    • 必須先設定先攻,才能開始記分。
    • 點擊分數直接加分,不提供加一減一按鈕。
    • 第一分記下後,設定隊伍 會切換成 上一步
    • 可交換上下兩隊位置,也可交換同隊左右站位。
    • 比賽結算 需長按 1 秒 才會觸發。
    • 比分 0:0 時不允許觸發結算。
  • 語音播報
    • 可設定是否播報得分者。
    • 可設定是否播報下一位發球者。
    • 可調整語速,最高支援到 10x
    • RURU 會以大小寫不敏感方式播報成「嚕嚕」。
  • 動畫提示
    • 先攻未設定時,先攻 文字會有提示動畫。
    • 選定先攻後,會顯示打勾讓使用者更容易辨識。
    • 連勝特效:
      • 3 連勝:大殺特殺
      • 4 連勝:暴走
      • 5 連勝:無人能擋
      • 6 連勝:主宰比賽
      • 7 連勝:像神一般的
      • 8 連勝:成為傳說
    • 達到目標分數時會顯示獲勝動畫。
  • 歷史戰績
    • 比賽結算後可選擇是否上傳戰績到資料庫。
    • 歷史戰績列表直接從資料庫 history 表讀取。
    • 可點開查看每球得分紀錄。
    • 手機上彈窗有 X 可快速關閉。
    • 每筆戰績可刪除,刪除前會確認一次。
  • 即時房間 / 觀戰
    • 只要帶入隊伍進入記分板,就會自動建立一個房間。
    • 記分板右側會顯示房號。
    • 房間列表 只顯示房號、隊伍、目標分數與最後更新時間,不顯示比分。
    • 觀戰者進入房間後可即時看到比分,不能操作。
    • 觀戰同步使用 SSE + 輪詢備援,降低漏分風險。
    • 房主重整、離開記分板或換隊伍時,未結束房間會自動清掉。
    • 達到目標分數後房間會標記結束,觀戰者會看到獲勝彈窗,按確定後返回房間列表。
  • PWA
    • 可加入手機主畫面,像 App 一樣開啟。
    • 支援自訂網站 icon / PWA icon。
    • 新版本部署後會顯示更新提示,可直接重新整理套用新版。

開發環境

Port

  • Client3501
  • Server8788

安裝

npm install

啟動開發模式

npm run dev

啟動後:

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

建置與檢查

npm run lint
npm run build

環境變數

請在專案根目錄建立 .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 部署

正式部署時:

  • App 內部服務 port8788
  • 對外 HTTPS 入口:3501

部署指令:

sudo docker compose up -d --build

部署完成後,對外入口為:

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

每次執行 sudo docker compose up -d --build,容器都會更新啟動版號,已安裝 PWA 的裝置會在偵測到新版本後顯示更新提示。

SSL 憑證目錄

Docker Compose 會直接掛載 NAS 上的憑證目錄:

/volume1/homes/JianMiau/www/certificate/

預設使用以下檔案:

  • RSA-cert.pem
  • RSA-chain.pem
  • RSA-privkey.pem

之後只要更新這個資料夾內的憑證檔即可,不需要重建 image。

資料表格式

history

  • id
  • time
  • dayOfWeek
  • score
  • winScore
  • type
    • 0:雙打
    • 1:單打
  • players
    • 1 ~ 4 編號排序的玩家陣列
  • team
    • 1、2 為一隊
    • 3、4 為一隊
  • scoreList
    • 格式:[round, 發球者編號, 連勝次數, 得分隊伍(0 或 1)]

PWA 圖示

目前網站 icon 與 PWA icon 來源為:

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

Git 中文設定

建議設定 git 使用 UTF-8避免中文 commit 或 log 顯示異常:

git config i18n.commitEncoding utf-8
git config i18n.logOutputEncoding utf-8
git config core.quotepath false
Description
羽毛球記分板系統,可用於即時顯示比分、回合進度與比賽狀態。
https://jianmiau.tk:3501/
Readme 1.8 MiB
Languages
TypeScript 60.3%
CSS 25.3%
JavaScript 12.1%
Shell 1.5%
HTML 0.5%
Other 0.3%