feat(game): 实现游戏房间状态管理和WebSocket连接功能

- 添加路由参数解析和房间状态初始化逻辑
- 实现房间玩家座位视图计算和状态映射
- 集成WebSocket客户端连接管理和重连机制
- 添加房间数据持久化存储功能
- 实现游戏界面状态显示和用户交互控制
- 更新WS代理目标地址配置
- 重构房间状态管理模块分离到独立store
This commit is contained in:
2026-03-25 14:07:52 +08:00
parent 148e21f3b0
commit 4a9b2f2db2
10 changed files with 353 additions and 39 deletions

View File

@@ -4,10 +4,12 @@ import { useRouter } from 'vue-router'
import { AuthExpiredError, type AuthSession } from '../api/authed-request'
import { createRoom, joinRoom, listRooms, type RoomItem } from '../api/mahjong'
import { getUserInfo, type UserInfo } from '../api/user'
import { hydrateActiveRoomFromSelection } from '../store/active-room-store'
import type { RoomPlayerState } from '../store/active-room-store'
import { setActiveRoom } from '../store'
import type { RoomPlayerState } from '../store/state'
import type { StoredAuth } from '../types/session'
import { clearAuth, readStoredAuth, writeStoredAuth } from '../utils/auth-storage'
import { wsClient } from '../ws/client'
import { buildWsUrl } from '../ws/url'
const router = useRouter()
@@ -176,6 +178,14 @@ function currentSession(): AuthSession | null {
return toSession(auth.value)
}
function connectGameWs(): void {
const token = auth.value?.token
if (!token) {
return
}
wsClient.connect(buildWsUrl(token), token)
}
async function refreshRooms(): Promise<void> {
const session = currentSession()
if (!session) {
@@ -236,7 +246,7 @@ async function submitCreateRoom(): Promise<void> {
)
createdRoom.value = room
hydrateActiveRoomFromSelection({
setActiveRoom({
roomId: room.room_id,
roomName: room.name,
gameType: room.game_type,
@@ -282,7 +292,7 @@ async function handleJoinRoom(room?: { roomId?: string; roomName?: string }): Pr
roomSubmitting.value = true
try {
const joinedRoom = await joinRoom(session, { roomId: targetRoomId }, syncAuth)
hydrateActiveRoomFromSelection({
setActiveRoom({
roomId: joinedRoom.room_id,
roomName: joinedRoom.name,
gameType: joinedRoom.game_type,
@@ -297,6 +307,7 @@ async function handleJoinRoom(room?: { roomId?: string; roomName?: string }): Pr
quickJoinRoomId.value = joinedRoom.room_id
successMessage.value = `已加入房间:${joinedRoom.room_id}`
await refreshRooms()
connectGameWs()
await router.push({
path: `/game/chengdu/${joinedRoom.room_id}`,
query: joinedRoom.name ? { roomName: joinedRoom.name } : undefined,
@@ -335,7 +346,7 @@ async function enterCreatedRoom(): Promise<void> {
}
showCreatedModal.value = false
hydrateActiveRoomFromSelection({
setActiveRoom({
roomId: createdRoom.value.room_id,
roomName: createdRoom.value.name,
gameType: createdRoom.value.game_type,
@@ -347,6 +358,7 @@ async function enterCreatedRoom(): Promise<void> {
updatedAt: createdRoom.value.updated_at,
players: mapRoomPlayers(createdRoom.value),
})
connectGameWs()
await router.push({
path: `/game/chengdu/${createdRoom.value.room_id}`,
query: { roomName: createdRoom.value.name },