fix: 修改房间逻辑
This commit is contained in:
@@ -137,6 +137,18 @@ export const useRoomStore = defineStore('room', () => {
|
|||||||
spectatorCount.value = count
|
spectatorCount.value = count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 收到求和请求 */
|
||||||
|
function receiveDrawRequest(fromUserId: string) {
|
||||||
|
drawRequested.value = true
|
||||||
|
drawRequestFrom.value = fromUserId
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 清除求和请求状态 */
|
||||||
|
function clearDrawRequest() {
|
||||||
|
drawRequested.value = false
|
||||||
|
drawRequestFrom.value = null
|
||||||
|
}
|
||||||
|
|
||||||
/** 重置状态 */
|
/** 重置状态 */
|
||||||
function reset() {
|
function reset() {
|
||||||
roomId.value = ''
|
roomId.value = ''
|
||||||
@@ -160,6 +172,7 @@ export const useRoomStore = defineStore('room', () => {
|
|||||||
messages,
|
messages,
|
||||||
drawRequested, drawRequestFrom, spectatorCount,
|
drawRequested, drawRequestFrom, spectatorCount,
|
||||||
initFromDetail, applyMove, setCurrentTurn, addMessage,
|
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)
|
roomStore.setSpectatorCount(data.count)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case 'draw_requested': {
|
||||||
|
const data = msg.data as { fromUserId: string }
|
||||||
|
roomStore.receiveDrawRequest(data.fromUserId)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'draw_rejected': {
|
||||||
|
roomStore.clearDrawRequest()
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -20,12 +20,27 @@
|
|||||||
|
|
||||||
<!-- 对局中:认输、求和 -->
|
<!-- 对局中:认输、求和 -->
|
||||||
<template v-if="store.isPlaying && store.isPlayer">
|
<template v-if="store.isPlaying && store.isPlayer">
|
||||||
<button class="room-actions__btn room-actions__btn--danger" @click="resign">
|
<!-- 收到对手求和请求 -->
|
||||||
认输
|
<template v-if="store.drawRequested && store.drawRequestFrom !== currentUserId">
|
||||||
</button>
|
<div class="room-actions__draw-notice">
|
||||||
<button class="room-actions__btn room-actions__btn--warn" @click="requestDraw">
|
{{ opponentName }} 向你发起求和请求
|
||||||
求和
|
</div>
|
||||||
</button>
|
<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>
|
</template>
|
||||||
|
|
||||||
<!-- 离开房间(始终显示) -->
|
<!-- 离开房间(始终显示) -->
|
||||||
@@ -40,6 +55,7 @@ import { computed, inject } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useRoomStore } from '@/stores'
|
import { useRoomStore } from '@/stores'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { ElMessageBox } from 'element-plus'
|
||||||
import type { RoomSocket } from '@/common/websocket/roomSocket'
|
import type { RoomSocket } from '@/common/websocket/roomSocket'
|
||||||
|
|
||||||
const store = useRoomStore()
|
const store = useRoomStore()
|
||||||
@@ -55,6 +71,12 @@ const isReady = computed(() => {
|
|||||||
return me?.ready ?? false
|
return me?.ready ?? false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/** 对手昵称 */
|
||||||
|
const opponentName = computed(() => {
|
||||||
|
const opponent = players.value.find((p) => p.userId !== currentUserId.value)
|
||||||
|
return opponent?.nickname ?? '对手'
|
||||||
|
})
|
||||||
|
|
||||||
function toggleReady() {
|
function toggleReady() {
|
||||||
socket.send('ready')
|
socket.send('ready')
|
||||||
}
|
}
|
||||||
@@ -71,7 +93,29 @@ function requestDraw() {
|
|||||||
socket.send('draw_request')
|
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.send('leave')
|
||||||
socket.close()
|
socket.close()
|
||||||
router.push('/')
|
router.push('/')
|
||||||
@@ -130,5 +174,27 @@ function leaveRoom() {
|
|||||||
border: 1px solid var(--border-default);
|
border: 1px solid var(--border-default);
|
||||||
&:hover { border-color: var(--text-secondary); color: var(--text-primary); }
|
&: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>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user