fix: 修改房间逻辑
This commit is contained in:
@@ -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
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user