# 羽毛球記分板

這是一個使用 `Vite + React + TypeScript + Node.js` 製作的羽毛球記分板，支援手機操作、PWA 安裝、即時觀戰房間、歷史戰績與 Docker / NAS 部署。

## 功能總覽

- 選隊伍
  - 可依指定日期從資料庫讀取分組資料。
  - 若指定日期沒有資料，可手動輸入 A、B 區名單建立分組。
  - 點選分組後可直接進入記分板。
- 記分板
  - 隊伍名稱只顯示在最上方與最下方。
  - 可在設定隊伍面板中逐一選人，也可快速選擇預設隊伍。
  - 先選到的 `1、2` 為一隊，`3、4` 為一隊。
  - 可設定獲勝分數，預設為 `21` 分。
  - 必須先選先攻，才能開始記分。
  - 點擊隊伍分數直接加分，不提供加一減一按鈕。
  - 第一分記下後，`設定隊伍` 會切換成 `上一步`。
  - 可交換上下兩隊位置，也可交換同隊左右站位。
  - `比賽結算` 需要長按 `1 秒` 才會觸發。
  - 比分 `0:0` 時不可結算。
  - 全站文字預設不可選取，避免手機誤觸反白。
- 語音播報
  - 可設定是否播報得分者。
  - 可設定是否播報發球者。
  - 語速最高可調到 `10x`。
  - `RURU` 以大小寫不敏感方式播報成「嚕嚕」。
- 動畫與提示
  - 未選先攻時，`先攻` 文字會有提示動畫。
  - 選定先攻後會顯示打勾。
  - 支援連勝稱號動畫與獲勝動畫。
- 歷史戰績
  - 可將比賽結果上傳到資料庫 `history`。
  - 歷史列表直接從 DB 顯示。
  - 可查看逐球得分紀錄。
  - 每筆紀錄可刪除，刪除前會確認一次。
- 即時房間 / 觀戰
  - 帶入隊伍進入記分板後會自動建立房間。
  - 記分板會顯示房號。
  - 房間列表不顯示比分，只顯示房號、隊伍、目標分數與更新時間。
  - 觀戰者只能看，不能操作。
  - 觀戰同步使用 `SSE + 輪詢備援`。
  - 房主重整、離開記分板或換隊伍時，未完成房間會自動清掉。
  - 達標獲勝時，觀戰者會收到獲勝通知。
  - 手動按 `比賽結算` 完成後，觀戰者也會收到獲勝結果，再返回房間列表。
- PWA
  - 可加入手機主畫面，像 App 一樣開啟。
  - 支援主畫面 icon 與版本更新提示。

## 開發

### Port

- Client：`3501`
- Server：`8788`

### 安裝

```bash
npm install
```

### 啟動開發模式

```bash
npm run dev
```

啟動後：

- 前端：`http://localhost:3501`
- API：`http://localhost:8788`

### 建置與檢查

```bash
npm run lint
npm run build
```

## 環境變數

請在專案根目錄建立 `.env`：

```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 內部服務：`8788`
- 對外 HTTPS 入口：`3501`

部署指令：

```bash
sudo docker compose up -d --build
```

部署完成後對外入口為：

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

每次執行 `sudo docker compose up -d --build`，容器都會刷新版本號，已安裝的 PWA 會在偵測到新版本後跳出更新提示。

## SSL 憑證目錄

Docker Compose 會直接掛載：

```text
/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 圖示

目前使用：

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

## Git 中文設定

建議設定 git 使用 UTF-8：

```bash
git config i18n.commitEncoding utf-8
git config i18n.logOutputEncoding utf-8
git config core.quotepath false
```
