2026-04-15 22:56:50 +08:00
|
|
|
|
# badminton-scoreboard
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
羽毛球記分板專案,使用 `Vite + React + TypeScript` 建立前端,搭配 `Express + MySQL` 提供分組讀取、歷史戰績列表與戰績寫入 API。
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
## 功能
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
- 指定日期後從 DB 讀取隊伍與分組資料
|
|
|
|
|
|
- 若該日期沒有資料,可手動輸入名單並產生配對
|
2026-04-15 22:56:50 +08:00
|
|
|
|
- 從指定組別選 2 隊帶入記分板
|
|
|
|
|
|
- 記分板支援先攻設定、點擊分數直接加分、上一步回退
|
2026-04-15 23:04:16 +08:00
|
|
|
|
- 支援上下交換隊伍、左右交換隊員位置
|
2026-04-15 22:56:50 +08:00
|
|
|
|
- 比賽結算後可選擇是否上傳戰績到 `history` 資料表
|
2026-04-15 23:04:16 +08:00
|
|
|
|
- 歷史戰績頁直接從 DB 顯示列表,點擊可查看得分過程
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
## Port 說明
|
|
|
|
|
|
|
|
|
|
|
|
### 本機開發
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
|
|
|
|
|
- Client: `3501`
|
|
|
|
|
|
- Server API: `8788`
|
|
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
開發模式入口:
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
- 前端:`http://localhost:3501`
|
|
|
|
|
|
- API:`http://localhost:8788`
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
### Docker / NAS 部署
|
|
|
|
|
|
|
|
|
|
|
|
- 對外入口:`3501`
|
|
|
|
|
|
- 內部 Node app:`8788`
|
|
|
|
|
|
|
|
|
|
|
|
也就是說:
|
|
|
|
|
|
|
|
|
|
|
|
- Docker 部署後,使用者要連的是 `3501`
|
|
|
|
|
|
- `8788` 是容器內部 app port,給 Nginx 反向代理用
|
|
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
## 本機開發
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
安裝套件:
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
npm install
|
2026-04-15 22:56:50 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
啟動開發模式:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-04-15 16:55:54 +08:00
|
|
|
|
npm run dev
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
這會同時啟動:
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
|
|
|
|
|
- Vite client on `3501`
|
|
|
|
|
|
- Node server on `8788`
|
|
|
|
|
|
|
|
|
|
|
|
其中後端已使用 `node --watch`,修改 `server/server.mjs` 會自動重啟。
|
|
|
|
|
|
|
|
|
|
|
|
## 環境變數
|
|
|
|
|
|
|
|
|
|
|
|
可參考 [.env.example](./.env.example):
|
|
|
|
|
|
|
|
|
|
|
|
```env
|
|
|
|
|
|
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
|
2026-04-15 23:15:52 +08:00
|
|
|
|
NGINX_SERVER_NAME=_
|
|
|
|
|
|
SSL_CERT_FILE_NAME=RSA-cert.pem
|
|
|
|
|
|
SSL_CHAIN_FILE_NAME=RSA-chain.pem
|
|
|
|
|
|
SSL_KEY_FILE_NAME=RSA-privkey.pem
|
2026-04-15 22:56:50 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
## 資料表
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
|
|
|
|
|
### `badminton`
|
|
|
|
|
|
|
|
|
|
|
|
- `time`: 日期,格式 `YYYYMMDD`
|
2026-04-15 23:04:16 +08:00
|
|
|
|
- `personnel`: 人員清單,例如 `[[1,"A區成員"],[0,"B區成員"]]`
|
|
|
|
|
|
- `battlecombination`: 分組資料,例如 `{"0":[["A","B"]],"1":[...],"2":[...]}`
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
|
|
|
|
|
### `history`
|
|
|
|
|
|
|
|
|
|
|
|
- `id`
|
|
|
|
|
|
- `time`
|
|
|
|
|
|
- `dayOfWeek`
|
|
|
|
|
|
- `score`
|
|
|
|
|
|
- `winScore`
|
|
|
|
|
|
- `type`
|
|
|
|
|
|
- `players`
|
|
|
|
|
|
- `team`
|
|
|
|
|
|
- `scoreList`
|
|
|
|
|
|
|
|
|
|
|
|
其中 `scoreList` 格式為:
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
|
|
|
|
|
```text
|
2026-04-15 22:56:50 +08:00
|
|
|
|
[round, starter, winCount, winner]
|
2026-04-15 16:55:54 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
欄位意義:
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
|
|
|
|
|
- `round`: 第幾球
|
|
|
|
|
|
- `starter`: 發球者編號,依記分板 `1~4`
|
2026-04-15 23:04:16 +08:00
|
|
|
|
- `winCount`: 該隊目前連續得分次數
|
|
|
|
|
|
- `winner`: 哪一隊得分,`0` 代表上方隊伍,`1` 代表下方隊伍
|
2026-04-15 22:56:50 +08:00
|
|
|
|
|
2026-04-15 16:55:54 +08:00
|
|
|
|
## 建置
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
npm run build
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
## Docker 單次啟動
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
如果你只是要單獨跑 Node app,可用:
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docker build -t badminton-scoreboard .
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-04-15 22:56:50 +08:00
|
|
|
|
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
|
2026-04-15 16:55:54 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
這種方式只會直接提供 Node app 本身,不含 Nginx SSL 入口。
|
|
|
|
|
|
|
2026-04-15 23:04:16 +08:00
|
|
|
|
## NAS 部署
|
|
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
這個專案已提供 [docker-compose.yml](./docker-compose.yml),會啟動兩個服務:
|
|
|
|
|
|
|
|
|
|
|
|
1. `badminton-scoreboard`
|
|
|
|
|
|
說明:Node app,內部使用 `8788`
|
|
|
|
|
|
|
|
|
|
|
|
2. `badminton-scoreboard-web`
|
|
|
|
|
|
說明:Nginx SSL 入口,對外使用 `3501`
|
|
|
|
|
|
|
|
|
|
|
|
在 NAS 專案目錄中,直接執行:
|
2026-04-15 23:04:16 +08:00
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo docker compose up -d --build
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
這樣就可以部署。
|
|
|
|
|
|
|
|
|
|
|
|
## SSL 憑證掛載
|
|
|
|
|
|
|
|
|
|
|
|
Nginx 會直接掛載這個 NAS 目錄:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
/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
|
|
|
|
|
|
|
|
|
|
|
|
而且已經加上憑證檔變更監看,所以你之後只要更新:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
/volume1/homes/JianMiau/www/certificate/
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
容器內的 Nginx 就會自動 reload,不需要重建 image。
|
|
|
|
|
|
|
|
|
|
|
|
## NAS `.env` 範例
|
|
|
|
|
|
|
|
|
|
|
|
部署前請先在 NAS 專案目錄準備 `.env`,至少要有:
|
2026-04-15 23:04:16 +08:00
|
|
|
|
|
|
|
|
|
|
```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
|
2026-04-15 23:15:52 +08:00
|
|
|
|
NGINX_SERVER_NAME=你的網域
|
|
|
|
|
|
SSL_CERT_FILE_NAME=RSA-cert.pem
|
|
|
|
|
|
SSL_CHAIN_FILE_NAME=RSA-chain.pem
|
|
|
|
|
|
SSL_KEY_FILE_NAME=RSA-privkey.pem
|
2026-04-15 23:04:16 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
## NAS 對外入口
|
|
|
|
|
|
|
|
|
|
|
|
部署後請從這個入口使用:
|
2026-04-15 16:55:54 +08:00
|
|
|
|
|
|
|
|
|
|
```text
|
2026-04-15 23:15:52 +08:00
|
|
|
|
https://你的網域:3501
|
2026-04-15 16:55:54 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
如果你的憑證是簽給特定網域,請不要用 IP 直接開,否則瀏覽器會跳憑證警告。
|
|
|
|
|
|
|
|
|
|
|
|
## 注意事項
|
|
|
|
|
|
|
|
|
|
|
|
- `sudo docker compose up -d --build` 這條指令現在可以直接用,因為專案已經補上 compose 檔
|
|
|
|
|
|
- Docker/NAS 對外入口是 `3501`,不是 `8788`
|
|
|
|
|
|
- `8788` 是 Node app 內部服務埠,不是給使用者直接連的
|
|
|
|
|
|
- 如果 NAS 上 `3501` 已被其他服務使用,請改 `docker-compose.yml` 左側對外埠
|
|
|
|
|
|
- 若你的憑證檔名之後改了,只要更新 `.env` 對應的 `SSL_*_FILE_NAME` 即可
|
|
|
|
|
|
|
|
|
|
|
|
## Git 設定
|
2026-04-15 23:04:16 +08:00
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
這個 repo 已設定:
|
2026-04-15 23:04:16 +08:00
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
- `i18n.commitEncoding=utf-8`
|
|
|
|
|
|
- `i18n.logOutputEncoding=utf-8`
|
|
|
|
|
|
- `core.quotepath=false`
|
2026-04-15 23:04:16 +08:00
|
|
|
|
|
2026-04-15 23:15:52 +08:00
|
|
|
|
之後可直接使用中文 commit 訊息與中文 git log。
|