feat(game): 添加成都麻将游戏页面和大厅功能
- 实现 ChengduGamePage.vue 组件,包含完整的麻将游戏界面 - 实现 HallPage.vue 组件,支持房间列表展示、创建和加入功能 - 添加 mahjong API 接口用于房间管理操作 - 集成 store 状态管理和本地存储功能 - 实现 ChengduBottomActions 等游戏控制组件 - 添加 websocket 连接和游戏会话管理逻辑 - 实现游戏倒计时、结算等功能模块
This commit is contained in:
112
src/components/chengdu/ChengduTableHeader.vue
Normal file
112
src/components/chengdu/ChengduTableHeader.vue
Normal file
@@ -0,0 +1,112 @@
|
||||
<script setup lang="ts">
|
||||
import type { ActionCountdownView } from '../../views/chengdu/types'
|
||||
|
||||
defineProps<{
|
||||
leaveRoomPending: boolean
|
||||
menuOpen: boolean
|
||||
menuTriggerActive: boolean
|
||||
isTrustMode: boolean
|
||||
wallCount: number
|
||||
networkLabel: string
|
||||
wsStatus: string
|
||||
formattedClock: string
|
||||
roomName: string
|
||||
currentPhaseText: string
|
||||
playerCount: number
|
||||
maxPlayers: number
|
||||
roundText: string
|
||||
roomStatusText: string
|
||||
wsError: string
|
||||
actionCountdown: ActionCountdownView | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
toggleMenu: []
|
||||
toggleTrustMode: []
|
||||
leaveRoom: []
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="top-left-tools">
|
||||
<div class="menu-trigger-wrap">
|
||||
<button
|
||||
class="metal-circle menu-trigger"
|
||||
:class="{ 'is-feedback': menuTriggerActive }"
|
||||
type="button"
|
||||
:disabled="leaveRoomPending"
|
||||
@click.stop="emit('toggleMenu')"
|
||||
>
|
||||
<span class="menu-trigger-icon">☰</span>
|
||||
</button>
|
||||
<transition name="menu-pop">
|
||||
<div v-if="menuOpen" class="menu-popover" @click.stop>
|
||||
<div class="menu-list">
|
||||
<button class="menu-item menu-item-delay-1" type="button" @click="emit('toggleTrustMode')">
|
||||
<slot name="robot-icon" />
|
||||
<span>{{ isTrustMode ? '取消托管' : '托管' }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="menu-item menu-item-danger menu-item-delay-2"
|
||||
type="button"
|
||||
:disabled="leaveRoomPending"
|
||||
@click="emit('leaveRoom')"
|
||||
>
|
||||
<slot name="exit-icon" />
|
||||
<span>{{ leaveRoomPending ? '退出中...' : '退出' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<div class="left-counter">
|
||||
<span class="counter-light"></span>
|
||||
<strong>{{ wallCount }}</strong>
|
||||
</div>
|
||||
<span v-if="isTrustMode" class="trust-chip">托管中</span>
|
||||
</div>
|
||||
|
||||
<div class="top-right-clock">
|
||||
<div class="signal-chip">
|
||||
<span class="wifi-dot" :class="`is-${wsStatus}`"></span>
|
||||
<strong>{{ networkLabel }}</strong>
|
||||
</div>
|
||||
<span>{{ formattedClock }}</span>
|
||||
</div>
|
||||
|
||||
<div class="room-status-panel">
|
||||
<div class="room-status-grid">
|
||||
<div class="room-status-item">
|
||||
<span>房间</span>
|
||||
<strong>{{ roomName || '未命名' }}</strong>
|
||||
</div>
|
||||
<div class="room-status-item">
|
||||
<span>阶段</span>
|
||||
<strong>{{ currentPhaseText }}</strong>
|
||||
</div>
|
||||
<div class="room-status-item">
|
||||
<span>人数</span>
|
||||
<strong>{{ playerCount }}/{{ maxPlayers }}</strong>
|
||||
</div>
|
||||
<div v-if="roundText" class="room-status-item">
|
||||
<span>局数</span>
|
||||
<strong>{{ roundText }}</strong>
|
||||
</div>
|
||||
<div class="room-status-item">
|
||||
<span>状态</span>
|
||||
<strong>{{ roomStatusText }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="wsError" class="room-status-error">{{ wsError }}</p>
|
||||
</div>
|
||||
|
||||
<div v-if="actionCountdown" class="action-countdown" :class="{ 'is-self': actionCountdown.isSelf }">
|
||||
<div class="action-countdown-head">
|
||||
<span>{{ actionCountdown.playerLabel }}操作倒计时</span>
|
||||
<strong>{{ actionCountdown.remaining }}s</strong>
|
||||
</div>
|
||||
<div class="action-countdown-track">
|
||||
<span class="action-countdown-fill" :style="{ width: `${actionCountdown.progress}%` }"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user