feat: 添加房间状态 Store

This commit is contained in:
2026-06-23 11:09:46 +08:00
parent 205b60711a
commit e2068ad95e
2 changed files with 158 additions and 0 deletions

View File

@@ -1,2 +1,3 @@
export * from './account.ts'
export * from './baseLayout.ts'
export * from './room.ts'

157
src/stores/modules/room.ts Normal file
View File

@@ -0,0 +1,157 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { RoomDetailResponse, RoomPlayerDetail, MoveItem, RoomStatus } from '@/api/modules/game'
export const useRoomStore = defineStore('room', () => {
// ===== 房间基础信息 =====
const roomId = ref<string>('')
const roomName = ref<string>('')
const gameId = ref<string>('')
const gameIcon = ref<string>('')
const gameName = ref<string>('')
const maxPlayers = ref<number>(0)
const mode = ref<string>('')
const stakes = ref<number>(0)
const status = ref<RoomStatus>('waiting')
const creatorId = ref<string>('')
const creatorName = ref<string>('')
const allowSpectate = ref<boolean>(true)
// ===== 玩家信息 =====
const players = ref<RoomPlayerDetail[]>([])
/** 当前用户是否为房主 */
const isOwner = computed(() => creatorId.value === currentUserId.value)
// ===== 对局状态 =====
const boardState = ref<number[][]>([])
const currentTurn = ref<string | null>(null)
const moves = ref<MoveItem[]>([])
const winner = ref<string | null>(null)
const resultType = ref<string | null>(null)
/** 是否对局中 */
const isPlaying = computed(() => status.value === 'playing')
/** 是否已结束 */
const isFinished = computed(() => status.value === 'finished')
// ===== 聊天消息 =====
interface ChatMessage {
userId: string
content: string
timestamp: number
}
const messages = ref<ChatMessage[]>([])
// ===== 当前用户身份 =====
const currentUserId = ref<string>('')
/** 当前用户在房间中的身份player玩家| spectator观战者 */
const myRole = ref<'player' | 'spectator'>('spectator')
/** 当前用户是否为玩家 */
const isPlayer = computed(() => myRole.value === 'player')
// ===== 求和状态 =====
const drawRequested = ref<boolean>(false)
const drawRequestFrom = ref<string | null>(null)
/**
* 从房间详情 HTTP 响应初始化 Store
* @param detail - 房间详情响应数据
* @param userId - 当前用户 ID
*/
function initFromDetail(detail: RoomDetailResponse, userId: string) {
roomId.value = detail.roomId
roomName.value = detail.name
gameId.value = detail.gameId
gameIcon.value = detail.gameIcon
gameName.value = detail.gameName
maxPlayers.value = detail.maxPlayers
mode.value = detail.mode
stakes.value = detail.stakes
status.value = detail.status
creatorId.value = detail.creatorId
creatorName.value = detail.creatorName
allowSpectate.value = detail.allowSpectate
players.value = detail.players
currentUserId.value = userId
boardState.value = detail.boardState ?? []
currentTurn.value = detail.currentTurn ?? null
moves.value = detail.moves ?? []
// 判定当前用户是玩家还是观战者
const isPlayerInRoom = detail.players.some((p) => p.userId === userId)
myRole.value = isPlayerInRoom ? 'player' : 'spectator'
}
/** 更新棋盘状态WS move 事件) */
function applyMove(row: number, col: number, playerId: string, moveIndex: number) {
moves.value.push({ moveIndex, playerId, row, col })
if (!boardState.value[row]) {
boardState.value[row] = []
}
// 判定棋子颜色moveIndex 从 1 开始,奇数=黑方(1),偶数=白方(2)
const stone = moveIndex % 2 === 1 ? 1 : 2
boardState.value[row][col] = stone
}
/** 更新当前轮次 */
function setCurrentTurn(playerId: string | null) {
currentTurn.value = playerId
}
/** 添加聊天消息 */
function addMessage(msg: ChatMessage) {
messages.value.push(msg)
}
/** 更新准备状态 */
function updateReady(userId: string, ready: boolean) {
const player = players.value.find((p) => p.userId === userId)
if (player) {
player.ready = ready
}
}
/** 玩家加入 */
function addPlayer(player: RoomPlayerDetail) {
if (!players.value.find((p) => p.userId === player.userId)) {
players.value.push(player)
}
}
/** 玩家离开 */
function removePlayer(userId: string) {
players.value = players.value.filter((p) => p.userId !== userId)
}
/** 对局结束 */
function setGameOver(winnerId: string | null, type: string) {
status.value = 'finished'
winner.value = winnerId
resultType.value = type
}
/** 重置状态 */
function reset() {
roomId.value = ''
players.value = []
boardState.value = []
currentTurn.value = null
moves.value = []
messages.value = []
winner.value = null
resultType.value = null
drawRequested.value = false
drawRequestFrom.value = null
}
return {
roomId, roomName, gameId, gameIcon, gameName,
maxPlayers, mode, stakes, status, creatorId, creatorName, allowSpectate,
players, isOwner, currentUserId, myRole, isPlayer,
boardState, currentTurn, moves, winner, resultType,
isPlaying, isFinished,
messages,
drawRequested, drawRequestFrom,
initFromDetail, applyMove, setCurrentTurn, addMessage,
updateReady, addPlayer, removePlayer, setGameOver, reset
}
})