fix: 修改房间逻辑

This commit is contained in:
2026-06-23 13:48:40 +08:00
parent f34dbeccb2
commit 0fae4feadb
3 changed files with 96 additions and 8 deletions

View File

@@ -137,6 +137,18 @@ export const useRoomStore = defineStore('room', () => {
spectatorCount.value = count
}
/** 收到求和请求 */
function receiveDrawRequest(fromUserId: string) {
drawRequested.value = true
drawRequestFrom.value = fromUserId
}
/** 清除求和请求状态 */
function clearDrawRequest() {
drawRequested.value = false
drawRequestFrom.value = null
}
/** 重置状态 */
function reset() {
roomId.value = ''
@@ -160,6 +172,7 @@ export const useRoomStore = defineStore('room', () => {
messages,
drawRequested, drawRequestFrom, spectatorCount,
initFromDetail, applyMove, setCurrentTurn, addMessage,
updateReady, addPlayer, removePlayer, setGameOver, setSpectatorCount, reset
updateReady, addPlayer, removePlayer, setGameOver, setSpectatorCount,
receiveDrawRequest, clearDrawRequest, reset
}
})

View File

@@ -164,6 +164,15 @@ function handleWsMessage(msg: WsMessage) {
roomStore.setSpectatorCount(data.count)
break
}
case 'draw_requested': {
const data = msg.data as { fromUserId: string }
roomStore.receiveDrawRequest(data.fromUserId)
break
}
case 'draw_rejected': {
roomStore.clearDrawRequest()
break
}
}
}
</script>

View File

@@ -20,12 +20,27 @@
<!-- 对局中认输求和 -->
<template v-if="store.isPlaying && store.isPlayer">
<button class="room-actions__btn room-actions__btn--danger" @click="resign">
认输
</button>
<button class="room-actions__btn room-actions__btn--warn" @click="requestDraw">
求和
</button>
<!-- 收到对手求和请求 -->
<template v-if="store.drawRequested && store.drawRequestFrom !== currentUserId">
<div class="room-actions__draw-notice">
{{ opponentName }} 向你发起求和请求
</div>
<button class="room-actions__btn room-actions__btn--accept" @click="respondDraw(true)">
同意求和
</button>
<button class="room-actions__btn room-actions__btn--reject" @click="respondDraw(false)">
拒绝求和
</button>
</template>
<!-- 正常操作 -->
<template v-else>
<button class="room-actions__btn room-actions__btn--danger" @click="resign">
认输
</button>
<button class="room-actions__btn room-actions__btn--warn" @click="requestDraw">
求和
</button>
</template>
</template>
<!-- 离开房间始终显示 -->
@@ -40,6 +55,7 @@ import { computed, inject } from 'vue'
import { useRouter } from 'vue-router'
import { useRoomStore } from '@/stores'
import { storeToRefs } from 'pinia'
import { ElMessageBox } from 'element-plus'
import type { RoomSocket } from '@/common/websocket/roomSocket'
const store = useRoomStore()
@@ -55,6 +71,12 @@ const isReady = computed(() => {
return me?.ready ?? false
})
/** 对手昵称 */
const opponentName = computed(() => {
const opponent = players.value.find((p) => p.userId !== currentUserId.value)
return opponent?.nickname ?? '对手'
})
function toggleReady() {
socket.send('ready')
}
@@ -71,7 +93,29 @@ function requestDraw() {
socket.send('draw_request')
}
function leaveRoom() {
function respondDraw(accept: boolean) {
socket.send('draw_response', { accept })
store.clearDrawRequest()
}
/** 离开房间(需二次确认) */
async function leaveRoom() {
const message =
store.isPlaying
? '对局进行中,离开将视为认输,确定要离开吗?'
: '确定要离开房间吗?'
try {
await ElMessageBox.confirm(message, '离开房间', {
confirmButtonText: '确定离开',
cancelButtonText: '取消',
type: store.isPlaying ? 'warning' : 'info'
})
} catch {
// 用户取消
return
}
socket.send('leave')
socket.close()
router.push('/')
@@ -130,5 +174,27 @@ function leaveRoom() {
border: 1px solid var(--border-default);
&:hover { border-color: var(--text-secondary); color: var(--text-primary); }
}
&--accept {
background-color: var(--color-success);
color: white;
&:hover { opacity: 0.9; }
}
&--reject {
background-color: transparent;
color: var(--color-danger);
border: 1px solid var(--color-danger);
&:hover { background-color: var(--color-danger); color: white; }
}
}
.room-actions__draw-notice {
padding: 10px 12px;
background-color: rgba(250, 173, 20, 0.1);
border: 1px solid var(--color-warning);
border-radius: 8px;
font-size: 13px;
color: var(--color-warning);
text-align: center;
line-height: 1.5;
}
</style>