提交 885a16f8 authored 作者: lidongxu's avatar lidongxu

修改房间号号码池功能

上级 263cd89e
...@@ -421,14 +421,14 @@ function drawTeamScoreBig(ctx, x, y, team, score, isWinner) { ...@@ -421,14 +421,14 @@ function drawTeamScoreBig(ctx, x, y, team, score, isWinner) {
ctx.save() ctx.save()
// 队伍标签 // 队伍标签(失败方变灰)
ctx.textAlign = 'center' ctx.textAlign = 'center'
ctx.textBaseline = 'middle' ctx.textBaseline = 'middle'
ctx.font = 'bold 18px Arial' ctx.font = 'bold 18px Arial'
ctx.fillStyle = color ctx.fillStyle = isWinner ? color : 'rgba(150,150,150,0.6)'
ctx.fillText(`${team}队`, x, y - 28) ctx.fillText(`${team}队`, x, y - 28)
// 分数(胜利方更大更亮,失败方暗淡) // 分数(胜利方更大更亮,失败方灰色暗淡)
ctx.font = isWinner ? 'bold 56px Arial' : 'bold 42px Arial' ctx.font = isWinner ? 'bold 56px Arial' : 'bold 42px Arial'
ctx.shadowColor = glowColor ctx.shadowColor = glowColor
ctx.shadowBlur = isWinner ? 30 : 0 ctx.shadowBlur = isWinner ? 30 : 0
...@@ -439,7 +439,7 @@ function drawTeamScoreBig(ctx, x, y, team, score, isWinner) { ...@@ -439,7 +439,7 @@ function drawTeamScoreBig(ctx, x, y, team, score, isWinner) {
sg.addColorStop(1, '#F59E0B') sg.addColorStop(1, '#F59E0B')
ctx.fillStyle = sg ctx.fillStyle = sg
} else { } else {
ctx.fillStyle = 'rgba(180,160,130,0.5)' ctx.fillStyle = 'rgba(120,120,120,0.5)'
} }
ctx.fillText(String(score), x, y + 15) ctx.fillText(String(score), x, y + 15)
ctx.shadowBlur = 0 ctx.shadowBlur = 0
...@@ -453,15 +453,18 @@ function drawTeamPlayerList(ctx, x, y, w, h, team, players, isWinner) { ...@@ -453,15 +453,18 @@ function drawTeamPlayerList(ctx, x, y, w, h, team, players, isWinner) {
ctx.save() ctx.save()
// 失败方用灰色替换队伍主色
const displayColor = isWinner ? color : 'rgba(150,150,150,0.6)'
// 队伍标题 // 队伍标题
ctx.textAlign = 'center' ctx.textAlign = 'center'
ctx.textBaseline = 'middle' ctx.textBaseline = 'middle'
ctx.font = 'bold 16px Arial' ctx.font = 'bold 16px Arial'
ctx.fillStyle = color ctx.fillStyle = displayColor
ctx.fillText(`${team}队成员`, x + w / 2, y + 12) ctx.fillText(`${team}队成员`, x + w / 2, y + 12)
// 分割线 // 分割线
ctx.strokeStyle = color + '40' ctx.strokeStyle = isWinner ? color + '40' : 'rgba(150,150,150,0.2)'
ctx.lineWidth = 1 ctx.lineWidth = 1
ctx.beginPath() ctx.beginPath()
ctx.moveTo(x + 5, y + 26) ctx.moveTo(x + 5, y + 26)
...@@ -474,7 +477,7 @@ function drawTeamPlayerList(ctx, x, y, w, h, team, players, isWinner) { ...@@ -474,7 +477,7 @@ function drawTeamPlayerList(ctx, x, y, w, h, team, players, isWinner) {
const rowY = y + 45 + index * rowHeight const rowY = y + 45 + index * rowHeight
if (rowY > y + h - 20) return // 超出范围不显示 if (rowY > y + h - 20) return // 超出范围不显示
// 背景高亮(如果是胜利方) // 背景高亮(胜利方)
if (isWinner) { if (isWinner) {
ctx.fillStyle = color + '15' ctx.fillStyle = color + '15'
ctx.beginPath() ctx.beginPath()
...@@ -484,19 +487,21 @@ function drawTeamPlayerList(ctx, x, y, w, h, team, players, isWinner) { ...@@ -484,19 +487,21 @@ function drawTeamPlayerList(ctx, x, y, w, h, team, players, isWinner) {
// 排名 // 排名
ctx.textAlign = 'center' ctx.textAlign = 'center'
ctx.fillStyle = index === 0 ? '#FCD34D' : 'rgba(196,181,253,0.6)' ctx.fillStyle = isWinner
? (index === 0 ? '#FCD34D' : 'rgba(196,181,253,0.6)')
: 'rgba(120,120,120,0.5)'
ctx.fillText(String(index + 1), x + 15, rowY) ctx.fillText(String(index + 1), x + 15, rowY)
// 昵称 // 昵称
ctx.textAlign = 'left' ctx.textAlign = 'left'
ctx.fillStyle = 'rgba(255,255,255,0.9)' ctx.fillStyle = isWinner ? 'rgba(255,255,255,0.9)' : 'rgba(130,130,130,0.6)'
const nickname = player.nickname || `玩家${player.playerId}` const nickname = player.nickname || `玩家${player.playerId}`
const displayName = nickname.length > 8 ? nickname.slice(0, 8) + '...' : nickname const displayName = nickname.length > 8 ? nickname.slice(0, 8) + '...' : nickname
ctx.fillText(displayName, x + 30, rowY) ctx.fillText(displayName, x + 30, rowY)
// 分数 // 分数
ctx.textAlign = 'right' ctx.textAlign = 'right'
ctx.fillStyle = '#FCD34D' ctx.fillStyle = isWinner ? '#FCD34D' : 'rgba(120,120,120,0.5)'
ctx.font = 'bold 13px Arial' ctx.font = 'bold 13px Arial'
ctx.fillText(String(player.score || 0), x + w - 10, rowY) ctx.fillText(String(player.score || 0), x + w - 10, rowY)
ctx.font = '13px Arial' ctx.font = '13px Arial'
......
...@@ -74,7 +74,7 @@ router.get('/:roomId/check', async (req, res, next) => { ...@@ -74,7 +74,7 @@ router.get('/:roomId/check', async (req, res, next) => {
} }
}); });
// POST /api/rooms/allocate — 分配一个未被占用的房间号(001~999 // POST /api/rooms/allocate — 分配下一个递增的唯一房间号(从 001 开始,无上限
// 返回:{ roomId: string } // 返回:{ roomId: string }
router.post('/allocate', async (_req, res, next) => { router.post('/allocate', async (_req, res, next) => {
try { try {
...@@ -89,30 +89,32 @@ router.post('/allocate', async (_req, res, next) => { ...@@ -89,30 +89,32 @@ router.post('/allocate', async (_req, res, next) => {
}); });
/** /**
* 从 001~999 中随机找一个当前未处于 waiting/playing 状态的房间号。 * 分配房间号:
* 最多重试 20 次,避免极端情况死循环。 * 1. 优先复用已结束(finished)的最小房间号
* @returns {Promise<string|null>} 3位字符串房间号,如 "042",找不到返回 null * 2. 没有可复用的,则取最大房间号 +1 递增
* 3. 从 1 开始,无上限
* @returns {Promise<string>} 房间号字符串
*/ */
async function allocateRoomId() { async function allocateRoomId() {
const MAX_TRIES = 20; // 优先找一个已结束的房间号复用(取最小的)
const finished = await prisma.room.findFirst({
where: { status: 'finished' },
orderBy: { roomId: 'asc' },
select: { roomId: true },
});
for (let i = 0; i < MAX_TRIES; i++) { if (finished) {
// 生成 1~999 随机数,格式化为 3 位字符串(补零) return finished.roomId;
const num = Math.floor(Math.random() * 999) + 1;
const roomId = String(num).padStart(3, '0');
const existing = await prisma.room.findUnique({
where: { roomId },
select: { status: true },
});
// 不存在,或已结束(finished)→ 可以使用
if (!existing || existing.status === 'finished') {
return roomId;
}
} }
return null; // 没有可复用的,取最大房间号 +1
const last = await prisma.room.findFirst({
orderBy: { roomId: 'desc' },
select: { roomId: true },
});
const lastNum = last ? parseInt(last.roomId, 10) : 0;
return String(lastNum + 1);
} }
module.exports = router; module.exports = router;
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论