diff --git a/src/stores/modules/index.ts b/src/stores/modules/index.ts index 8f94af6..734618e 100644 --- a/src/stores/modules/index.ts +++ b/src/stores/modules/index.ts @@ -1,2 +1,3 @@ export * from './account.ts' export * from './baseLayout.ts' +export * from './room.ts' diff --git a/src/stores/modules/room.ts b/src/stores/modules/room.ts new file mode 100644 index 0000000..b456ca9 --- /dev/null +++ b/src/stores/modules/room.ts @@ -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('') + const roomName = ref('') + const gameId = ref('') + const gameIcon = ref('') + const gameName = ref('') + const maxPlayers = ref(0) + const mode = ref('') + const stakes = ref(0) + const status = ref('waiting') + const creatorId = ref('') + const creatorName = ref('') + const allowSpectate = ref(true) + + // ===== 玩家信息 ===== + const players = ref([]) + /** 当前用户是否为房主 */ + const isOwner = computed(() => creatorId.value === currentUserId.value) + + // ===== 对局状态 ===== + const boardState = ref([]) + const currentTurn = ref(null) + const moves = ref([]) + const winner = ref(null) + const resultType = ref(null) + /** 是否对局中 */ + const isPlaying = computed(() => status.value === 'playing') + /** 是否已结束 */ + const isFinished = computed(() => status.value === 'finished') + + // ===== 聊天消息 ===== + interface ChatMessage { + userId: string + content: string + timestamp: number + } + const messages = ref([]) + + // ===== 当前用户身份 ===== + const currentUserId = ref('') + /** 当前用户在房间中的身份:player(玩家)| spectator(观战者) */ + const myRole = ref<'player' | 'spectator'>('spectator') + /** 当前用户是否为玩家 */ + const isPlayer = computed(() => myRole.value === 'player') + + // ===== 求和状态 ===== + const drawRequested = ref(false) + const drawRequestFrom = ref(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 + } +})