From 632a0267a408c11c189964b5036a942d96414e41 Mon Sep 17 00:00:00 2001 From: wsy182 <2392948297@qq.com> Date: Mon, 23 Mar 2026 21:13:38 +0800 Subject: [PATCH] update --- src/api/mahjong.ts | 9 +- src/state/active-room.ts | 139 +++++++++++++ src/views/ChengduGamePage.vue | 365 ++++++++++++++++++++++++++++------ src/views/HallPage.vue | 61 +++++- 4 files changed, 498 insertions(+), 76 deletions(-) create mode 100644 src/state/active-room.ts diff --git a/src/api/mahjong.ts b/src/api/mahjong.ts index ba9059d..901634f 100644 --- a/src/api/mahjong.ts +++ b/src/api/mahjong.ts @@ -7,6 +7,11 @@ export interface RoomItem { owner_id: string max_players: number player_count: number + players?: Array<{ + index: number + player_id: string + ready: boolean + }> status: string created_at: string updated_at: string @@ -58,8 +63,8 @@ export async function joinRoom( auth: AuthSession, input: { roomId: string }, onAuthUpdated?: (next: AuthSession) => void, -): Promise { - await authedRequest | RoomItem>({ +): Promise { + return authedRequest({ method: 'POST', path: ROOM_JOIN_PATH, auth, diff --git a/src/state/active-room.ts b/src/state/active-room.ts new file mode 100644 index 0000000..67706e0 --- /dev/null +++ b/src/state/active-room.ts @@ -0,0 +1,139 @@ +import { ref } from 'vue' + +export const DEFAULT_MAX_PLAYERS = 4 +export type RoomStatus = 'waiting' | 'playing' | 'finished' + +export interface RoomPlayerState { + index: number + playerId: string + ready: boolean +} + +export interface RuleState { + name: string + isBloodFlow: boolean + hasHongZhong: boolean +} + +export interface GamePlayerState { + playerId: string + index: number + ready: boolean +} + +export interface EngineState { + phase: string + dealerIndex: number + currentTurn: number + needDraw: boolean + players: GamePlayerState[] + wall: string[] + lastDiscardTile: string | null + lastDiscardBy: string + pendingClaim: Record | null + winners: string[] + scores: Record + lastDrawPlayerId: string + lastDrawFromGang: boolean + lastDrawIsLastTile: boolean + huWay: string +} + +export interface GameState { + rule: RuleState | null + state: EngineState | null +} + +export interface RoomState { + id: string + name: string + gameType: string + ownerId: string + maxPlayers: number + playerCount: number + status: RoomStatus | string + createdAt: string + updatedAt: string + game: GameState | null + players: RoomPlayerState[] + currentTurnIndex: number | null +} + +function createInitialRoomState(): RoomState { + return { + id: '', + name: '', + gameType: 'chengdu', + ownerId: '', + maxPlayers: DEFAULT_MAX_PLAYERS, + playerCount: 0, + status: 'waiting', + createdAt: '', + updatedAt: '', + game: null, + players: [], + currentTurnIndex: null, + } +} + +export const activeRoomState = ref(createInitialRoomState()) + +export function destroyActiveRoomState(): void { + activeRoomState.value = createInitialRoomState() +} + +export function resetActiveRoomState(seed?: Partial): void { + destroyActiveRoomState() + if (!seed) { + return + } + + activeRoomState.value = { + ...activeRoomState.value, + ...seed, + players: seed.players ?? [], + } +} + +export function mergeActiveRoomState(next: RoomState): void { + if (activeRoomState.value.id && next.id && next.id !== activeRoomState.value.id) { + return + } + + activeRoomState.value = { + ...activeRoomState.value, + ...next, + game: next.game ?? activeRoomState.value.game, + players: next.players.length > 0 ? next.players : activeRoomState.value.players, + currentTurnIndex: + next.currentTurnIndex !== null ? next.currentTurnIndex : activeRoomState.value.currentTurnIndex, + } +} + +export function hydrateActiveRoomFromSelection(input: { + roomId: string + roomName?: string + gameType?: string + ownerId?: string + maxPlayers?: number + playerCount?: number + status?: string + createdAt?: string + updatedAt?: string + players?: RoomPlayerState[] + currentTurnIndex?: number | null +}): void { + resetActiveRoomState({ + id: input.roomId, + name: input.roomName ?? '', + gameType: input.gameType ?? 'chengdu', + ownerId: input.ownerId ?? '', + maxPlayers: input.maxPlayers ?? DEFAULT_MAX_PLAYERS, + playerCount: input.playerCount ?? 0, + status: input.status ?? 'waiting', + createdAt: input.createdAt ?? '', + updatedAt: input.updatedAt ?? '', + players: input.players ?? [], + currentTurnIndex: input.currentTurnIndex ?? null, + }) +} diff --git a/src/views/ChengduGamePage.vue b/src/views/ChengduGamePage.vue index 4708cff..27b704c 100644 --- a/src/views/ChengduGamePage.vue +++ b/src/views/ChengduGamePage.vue @@ -1,7 +1,19 @@ @@ -508,7 +739,9 @@ onBeforeUnmount(() => {

玩家:{{ loggedInUserName }}

- +
@@ -529,7 +762,7 @@ onBeforeUnmount(() => { 人数: - {{ roomState.players.length }}/{{ roomState.maxPlayers }} + {{ roomState.playerCount }}/{{ roomState.maxPlayers }}