From 4a9b2f2db23d3dc469dd52c27853c350fe5ca7ed Mon Sep 17 00:00:00 2001 From: wsy182 <2392948297@qq.com> Date: Wed, 25 Mar 2026 14:07:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(game):=20=E5=AE=9E=E7=8E=B0=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E6=88=BF=E9=97=B4=E7=8A=B6=E6=80=81=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=92=8CWebSocket=E8=BF=9E=E6=8E=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加路由参数解析和房间状态初始化逻辑 - 实现房间玩家座位视图计算和状态映射 - 集成WebSocket客户端连接管理和重连机制 - 添加房间数据持久化存储功能 - 实现游戏界面状态显示和用户交互控制 - 更新WS代理目标地址配置 - 重构房间状态管理模块分离到独立store --- .env.development | 4 +- src/assets/styles/room.css | 2 +- src/store/index.ts | 45 +++++++ src/store/state.ts | 49 ++++++++ src/store/storage.ts | 20 +++ src/types/state/meld.ts | 4 +- src/types/state/player.ts | 4 +- src/views/ChengduGamePage.vue | 223 ++++++++++++++++++++++++++++++---- src/views/HallPage.vue | 22 +++- src/ws/client.ts | 19 ++- 10 files changed, 353 insertions(+), 39 deletions(-) create mode 100644 src/store/index.ts create mode 100644 src/store/state.ts create mode 100644 src/store/storage.ts diff --git a/.env.development b/.env.development index 4e162d6..152e027 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ VITE_API_BASE_URL=/api/v1 VITE_GAME_WS_URL=/ws -VITE_API_PROXY_TARGET=http://192.168.2.16:19000 -VITE_WS_PROXY_TARGET=http://192.168.2.16:19000 +VITE_API_PROXY_TARGET=http://192.168.1.5:19000 +VITE_WS_PROXY_TARGET=http://192.168.1.5:19000 diff --git a/src/assets/styles/room.css b/src/assets/styles/room.css index e5dcc70..89c8a20 100644 --- a/src/assets/styles/room.css +++ b/src/assets/styles/room.css @@ -148,7 +148,7 @@ position: absolute; top: -4px; left: 58px; - min-width: 124px; + min-width: 128px; padding: 8px; border-radius: 10px; border: 1px solid rgba(255, 255, 255, 0.16); diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..ddd02b7 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,45 @@ +import { ref } from 'vue' +import type { + ActiveRoomState, + ActiveRoomSelectionInput, +} from './state' +import { readActiveRoomSnapshot, saveActiveRoom } from './storage' + +const activeRoom = ref(readActiveRoomSnapshot()) + +function normalizeRoom(input: ActiveRoomSelectionInput): ActiveRoomState { + return { + roomId: input.roomId, + roomName: input.roomName ?? '', + gameType: input.gameType ?? 'chengdu', + ownerId: input.ownerId ?? '', + maxPlayers: input.maxPlayers ?? 4, + playerCount: input.playerCount ?? input.players?.length ?? 0, + status: input.status ?? 'waiting', + createdAt: input.createdAt ?? '', + updatedAt: input.updatedAt ?? '', + players: input.players ?? [], + myHand: [], + game: { + state: { + wall: [], + scores: {}, + dealerIndex: -1, + currentTurn: -1, + phase: 'waiting', + }, + }, + } +} + +// 设置当前房间 +export function setActiveRoom(input: ActiveRoomSelectionInput) { + const next = normalizeRoom(input) + activeRoom.value = next + saveActiveRoom(next) +} + +// 使用房间状态 +export function useActiveRoomState() { + return activeRoom +} \ No newline at end of file diff --git a/src/store/state.ts b/src/store/state.ts new file mode 100644 index 0000000..e1d66ff --- /dev/null +++ b/src/store/state.ts @@ -0,0 +1,49 @@ +// 房间玩家状态 +export interface RoomPlayerState { + index: number + playerId: string + displayName?: string + missingSuit?: string | null + ready: boolean + hand: string[] + melds: string[] + outTiles: string[] + hasHu: boolean +} + +// 房间整体状态 +export interface ActiveRoomState { + roomId: string + roomName: string + gameType: string + ownerId: string + maxPlayers: number + playerCount: number + status: string + createdAt: string + updatedAt: string + players: RoomPlayerState[] + myHand: string[] + game?: { + state?: { + wall?: string[] + scores?: Record + dealerIndex?: number + currentTurn?: number + phase?: string + } + } +} + +export interface ActiveRoomSelectionInput { + roomId: string + roomName?: string + gameType?: string + ownerId?: string + maxPlayers?: number + playerCount?: number + status?: string + createdAt?: string + updatedAt?: string + players?: RoomPlayerState[] +} \ No newline at end of file diff --git a/src/store/storage.ts b/src/store/storage.ts new file mode 100644 index 0000000..5dd97e8 --- /dev/null +++ b/src/store/storage.ts @@ -0,0 +1,20 @@ +import type { ActiveRoomState } from './state' + +const KEY = 'mahjong_active_room' + +// 读取缓存 +export function readActiveRoomSnapshot(): ActiveRoomState | null { + const raw = localStorage.getItem(KEY) + if (!raw) return null + + try { + return JSON.parse(raw) + } catch { + return null + } +} + +// 写入缓存 +export function saveActiveRoom(state: ActiveRoomState) { + localStorage.setItem(KEY, JSON.stringify(state)) +} \ No newline at end of file diff --git a/src/types/state/meld.ts b/src/types/state/meld.ts index 930f382..70d7a78 100644 --- a/src/types/state/meld.ts +++ b/src/types/state/meld.ts @@ -1,4 +1,4 @@ -import type {Tile} from "../../models"; +import type { Tile } from '../tile' export type Meld = | { @@ -14,4 +14,4 @@ export type Meld = | { type: 'an_gang' tiles: Tile[] -} \ No newline at end of file +} diff --git a/src/types/state/player.ts b/src/types/state/player.ts index 6362f83..a129a99 100644 --- a/src/types/state/player.ts +++ b/src/types/state/player.ts @@ -1,5 +1,5 @@ -import type {Tile} from "../../models"; -import type {Meld} from "./meld.ts"; +import type { Tile } from '../tile' +import type { Meld } from './meld' export interface Player{ playerId: string diff --git a/src/views/ChengduGamePage.vue b/src/views/ChengduGamePage.vue index 021353c..967a46e 100644 --- a/src/views/ChengduGamePage.vue +++ b/src/views/ChengduGamePage.vue @@ -1,5 +1,6 @@