2026-04-16 07:48:15 +08:00
2026-04-16 07:48:15 +08:00

badminton-scoreboard

羽毛球記分板專案,使用 Vite + React + TypeScript 建立前端,搭配 Express + MySQL 提供分組讀取、歷史戰績列表與戰績寫入 API。

功能

  • 指定日期後從 DB 讀取隊伍與分組資料
  • 若該日期沒有資料,可手動輸入名單並產生配對
  • 從指定組別選 2 隊帶入記分板
  • 記分板支援先攻設定、點擊分數直接加分、上一步回退
  • 支援上下交換隊伍、左右交換隊員位置
  • 比賽結算後可選擇是否上傳戰績到 history 資料表
  • 歷史戰績頁直接從 DB 顯示列表
  • 點擊歷史戰績可開啟彈窗,查看比分、發球人姓名、連勝次數與每球結果

Port 說明

本機開發

  • Client: 3501
  • Server API: 8788

開發模式入口:

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

Docker / NAS 部署

  • 對外入口:3501
  • 內部 Node app8788

也就是說:

  • Docker 與 NAS 部署後,使用者實際連的是 3501
  • 8788 是容器內部 app port給 Nginx 反向代理使用

本機開發

安裝套件:

npm install

啟動開發模式:

npm run dev

這會同時啟動:

  • Vite client on 3501
  • Node server on 8788

其中後端已使用 node --watch,修改 server/server.mjs 會自動重啟。

環境變數

可參考 .env.example

DB_HOST=192.168.0.15
DB_PORT=3307
DB_USER=jianmiau
DB_PASSWORD=your-password
DB_DATABASE=badminton
DB_TABLE=badminton
DB_HISTORY_TABLE=history
SERVER_PORT=8788
NGINX_SERVER_NAME=_
SSL_CERT_FILE_NAME=RSA-cert.pem
SSL_CHAIN_FILE_NAME=RSA-chain.pem
SSL_KEY_FILE_NAME=RSA-privkey.pem

資料表

badminton

  • time:日期,格式 YYYYMMDD
  • personnel:人員清單,例如 [[1,"A區成員"],[0,"B區成員"]]
  • battlecombination:分組資料,例如 {"0":[["A","B"]],"1":[...],"2":[...]}

history

  • id
  • time
  • dayOfWeek
  • score
  • winScore
  • type
  • players
  • team
  • scoreList

其中 scoreList 格式為:

[round, starter, winCount, winner]

欄位意義:

  • round:第幾球
  • starter:發球者編號,依記分板 1~4
  • winCount:該隊目前連續得分次數
  • winner:哪一隊得分,0 代表上方隊伍,1 代表下方隊伍

建置

npm run build

Docker 單次啟動

如果你只是要單獨跑 Node app可用

docker build -t badminton-scoreboard .
docker run -d \
  --name badminton-scoreboard \
  -p 8788:8788 \
  -e PORT=8788 \
  -e DB_HOST=192.168.0.15 \
  -e DB_PORT=3307 \
  -e DB_USER=jianmiau \
  -e DB_PASSWORD=your-password \
  -e DB_DATABASE=badminton \
  -e DB_TABLE=badminton \
  -e DB_HISTORY_TABLE=history \
  badminton-scoreboard

這種方式只會直接提供 Node app 本身,不含 Nginx SSL 入口。

NAS 部署

專案提供 docker-compose.yml,會啟動兩個服務:

  1. badminton-scoreboard 說明Node app內部使用 8788

  2. badminton-scoreboard-web 說明Nginx SSL 入口,對外使用 3501

在 NAS 專案目錄中可直接執行:

sudo docker compose up -d --build

SSL 憑證掛載

Nginx 直接掛載這個 NAS 目錄:

/volume1/homes/JianMiau/www/certificate/

目前預設使用你現有的檔名:

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

Nginx 會在容器內自動組合:

  • RSA-cert.pem + RSA-chain.pem => fullchain
  • RSA-privkey.pem => private key

另外已加入憑證檔變更監看,所以你之後只要更新:

/volume1/homes/JianMiau/www/certificate/

容器內的 Nginx 就會自動 reload不需要重建 image。

NAS .env 範例

部署前請先在 NAS 專案目錄準備 .env,至少要有:

DB_HOST=192.168.0.15
DB_PORT=3307
DB_USER=jianmiau
DB_PASSWORD=你的密碼
DB_DATABASE=badminton
DB_TABLE=badminton
DB_HISTORY_TABLE=history
NGINX_SERVER_NAME=你的網域
SSL_CERT_FILE_NAME=RSA-cert.pem
SSL_CHAIN_FILE_NAME=RSA-chain.pem
SSL_KEY_FILE_NAME=RSA-privkey.pem

NAS 對外入口

部署後請從這個入口使用:

https://你的網域:3501

如果你的憑證是簽給特定網域,請不要用 IP 直接開,否則瀏覽器會跳憑證警告。

注意事項

  • sudo docker compose up -d --build 現在可以直接使用
  • Docker / NAS 對外入口是 3501,不是 8788
  • 8788 是 Node app 內部服務埠,不是給使用者直接連的
  • 若 NAS 上 3501 已被其他服務使用,請改 docker-compose.yml 左側對外埠
  • 若憑證檔名之後改了,只要更新 .env 中對應的 SSL_*_FILE_NAME 即可

Git 設定

這個 repo 已設定:

  • i18n.commitEncoding=utf-8
  • i18n.logOutputEncoding=utf-8
  • core.quotepath=false

之後可直接使用中文 commit 訊息與中文 git log。

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%