# 羽毛球記分板 這是一個使用 `Vite + React + TypeScript + Node.js` 製作的羽毛球記分板專案,提供手機優先的記分介面、歷史戰績、房間觀戰、語音播報、PWA 安裝,以及 Docker / NAS 部署方式。 ## 功能特色 - 選隊伍頁面 - 可依指定日期從資料庫讀取分組資料。 - 若當天沒有資料,可手動輸入 A、B 區名單建立配對。 - 點進記分板時會直接帶入該組對戰。 - 記分板 - 兩隊隊員可自由交換上下、左右位置。 - 畫面編號固定為左上 `1`、右上 `2`、右下 `3`、左下 `4`。 - 先攻只能在開局設定一次,之後不會跟著發球權改變。 - 點擊分數直接加分,沒有加一減一按鈕。 - 第一分開始後,`設定隊伍` 會改成 `上一步`。 - `比賽結算` 需要長按 `1` 秒才會觸發,避免誤觸。 - 達標分數後有獲勝動畫與結算流程。 - 手機上會盡量壓縮成單頁滿版,避免上下滑動。 - 羽球規則 - 預設 `21` 分制,可在設定隊伍時調整目標分數。 - 支援 Deuce:`20:20` 後需領先 `2` 分才獲勝。 - `29:29` 時第 `30` 分直接獲勝。 - 發球方依羽球規則處理,`0` 分在右發球區。 - 畫面以下方隊伍為我方、上方隊伍為對方。 - 上方隊伍採鏡像顯示,所以我方 `0:0` 在右邊發球時,對方會在左邊接發。 - 語音播報 - 只在按下加分當下播報,不會因復原或其他操作重複報分。 - 可選擇是否播報得分與發球者。 - 同隊連續得分才會播報 `換邊發球`。 - 支援調整語速,最高可到 `10x`。 - `RURU` 會做大小寫無關判斷並以指定發音播報。 - 歷史戰績 - 可從資料庫讀取歷史列表。 - 點開單筆可查看得分過程。 - 每筆資料可刪除,刪除前會顯示確認提示。 - 房間觀戰 - 記分板帶入隊伍後會自動建立房間。 - 房間列表可查看目前直播中的比賽。 - 觀戰者只能看,不能操作記分。 - 分數、房間狀態、比賽結算會即時同步給觀戰者。 - 房間失效、重整、重選隊伍後也會通知觀戰者。 - 房間列表有 `重新取得列表`,並帶有 `5` 秒冷卻。 - PWA - 可安裝到 iPhone / iPad / Android 主畫面。 - 支援 Web App 模式啟動。 - 新版本部署後會提示重新整理或重新安裝。 ## 本機開發 ### 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 ``` ## 記分板滿版模式 - 記分板頁面會套用 `100dvh` 高度。 - 手機進入記分板時會關閉頁面捲動與 overscroll。 - `viewport` 已加上 `viewport-fit=cover`,較能貼合 iPhone / iPad 安全區。 - 若手機高度較矮,會再縮小字級、按鈕與分數區,盡量維持整頁顯示。 ## 環境變數 請先建立 `.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 部署 對外服務配置: - 容器內 Node / API:`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` 之後只要更新這個目錄內的憑證檔案,再重新部署容器即可套用新 SSL。 ## 資料表格式 ### `history` - `id` - `time` - `dayOfWeek` - `score` - `winScore` - `type` - `0`: 雙打 - `1`: 單打 - `players` - 依照 `1 ~ 4` 固定編號順序儲存玩家名單。 - `team` - `1` 跟 `2` 一隊 - `3` 跟 `4` 一隊 - `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 顯示中文,建議設定: ```bash git config i18n.commitEncoding utf-8 git config i18n.logOutputEncoding utf-8 git config core.quotepath false ```