記分板新增隨機配對、計分人權限與換人計分,調整按鈕排法
根本原因: 每打完一輪都要人工決定誰上場、誰搭誰、誰負責記分,記分板也沒有「兩隊對換」和退回選先發球的操作,現場排場地或換人都得重開記分板。 影響: /記分 多一顆 🎲 隨機配對:勾選出席者(預設全選)後,依 tg_members.skill 與今天的 history 戰績排 2、3 號場地(休息最久優先、搭檔與對手不重複、實力平衡),預覽後一鍵推出各場地記分板;每場從休息者抽一位計分人(SCORER_EXCLUDE 不抽),只有他和管理員能按,休息人不夠則不鎖權限;開局可 🙋 換人計分、🔃 🅰️🅱️ 對換;計分鍵盤改為左欄 🅰️+1/🅱️+1,拿掉「重新開始」,0:0 時上一步可退回選先發球。 修法: - 新增 src/pairing.js:移植 badminton-match-hub V2 的配對規則,改成一次只排下一輪、以「休息輪數」取代平均場數;assignScorers 從休息者抽計分人 - history.js 新增 loadTodayGames 讀今日戰績;signup.js attendees() 帶 skill 與 user_id(權限靠 TG id 比對) - scoreboard.js 以 phase(pick → roster → paired)管理同一則訊息的選人/勾選/預覽流程,推出的記分板 ownerId 指向計分人;新增換人計分(ho / hoN / hoany / hocancel),候選排除場上、現任計分人與 SCORER_EXCLUDE - match.js 新增 swapTeams,setFirstServer 記入 history 讓 undo 可退回開局;render.js 重排鍵盤並新增勾選、預覽、換人面板與場地標題 - config 新增 SCORER_EXCLUDE;README、.env.example 與 37 個測試同步更新 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,15 @@ function fakeDb() {
|
||||
if (s.startsWith('SELECT user_id, nickname FROM attendance')) {
|
||||
return attendance.filter((r) => r.poll_date === params[0]).map((r) => ({ user_id: r.user_id, nickname: r.nickname }))
|
||||
}
|
||||
if (s.startsWith('SELECT a.nickname, a.user_id, COALESCE(m.skill')) {
|
||||
return attendance
|
||||
.filter((r) => r.poll_date === params[0])
|
||||
.map((r) => {
|
||||
const byId = members.get(r.user_id)
|
||||
const byName = [...members.values()].find((m) => m.nickname === r.nickname)
|
||||
return { nickname: r.nickname, user_id: r.user_id, skill: byId?.skill ?? byName?.skill ?? 1 }
|
||||
})
|
||||
}
|
||||
if (s.startsWith('SELECT m.nickname, m.user_id AS member')) {
|
||||
const [uid, date] = params
|
||||
const m = members.get(uid)
|
||||
@@ -175,3 +184,23 @@ test('commandRegex:支援 @BotName 後綴與中英文別名', () => {
|
||||
assert.equal('/score 小明 vs 阿強'.match(s)[1], '小明 vs 阿強')
|
||||
assert.equal('/記分'.match(s)[1], undefined)
|
||||
})
|
||||
|
||||
test('attendees:出席名單帶 tg_members.skill(user_id 對不到就用暱稱對,都沒有當 1)', async () => {
|
||||
const db = fakeDb()
|
||||
const bot = fakeBot()
|
||||
const signup = createSignup(bot, { log: silentLog, query: db.query })
|
||||
db.members.set(1, { nickname: '建喵', skill: 9 })
|
||||
db.members.set(3, { nickname: '同名', skill: 4 })
|
||||
db.attendance.push(
|
||||
{ poll_date: DATE, user_id: 1, nickname: '建喵' },
|
||||
{ poll_date: DATE, user_id: 2, nickname: '路人' },
|
||||
{ poll_date: DATE, user_id: 99, nickname: '同名' },
|
||||
{ poll_date: DATE, user_id: 100, nickname: ' ' },
|
||||
)
|
||||
assert.deepEqual(await signup.attendees(DATE), [
|
||||
{ name: '建喵', skill: 9, userId: 1 },
|
||||
{ name: '路人', skill: 1, userId: 2 },
|
||||
{ name: '同名', skill: 4, userId: 99 },
|
||||
])
|
||||
assert.deepEqual(await signup.attendees('20000101'), [])
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user