refactor(game): 移除废弃的房间状态管理文件并优化游戏页面

- 删除 src/state/active-room.ts 文件及其相关导入引用
- 更新 ChengduGamePage.vue 中的导入路径从 features/chengdu-game/useChengduGameRoom 到 game/chengdu
- 移除 ChengduGamePage.vue 中不再需要的状态变量如 roomId、startGamePending 等
- 简化 roomStatusText 计算属性逻辑,移除 "等待中" 默认值
- 调整 phaseLabelMap 映射,移除 "摸牌" 阶段显示
- 删除多个废弃的计算属性如 centerTimer、selectedTileText、pendingClaimText 等
- 移除 actionTheme 函数及相关的按钮样式绑定
- 清理游戏场景中的装饰元素如 diamond outline、scene watermark、center desk 等
- 更新 HallPage.vue 中的导入路径到 store/active-room-store
- 添加缺失的玩家数据字段如 hand、melds、outTiles、hasHu
- 调整 CSS 样式包括工具栏位置、动画角度和时钟位置等视觉优化
This commit is contained in:
2026-03-24 22:09:03 +08:00
parent 3219639b04
commit 7316588d9e
28 changed files with 757 additions and 670 deletions

View File

@@ -17,28 +17,22 @@ import RightPlayerCard from '../components/game/RightPlayerCard.vue'
import BottomPlayerCard from '../components/game/BottomPlayerCard.vue'
import LeftPlayerCard from '../components/game/LeftPlayerCard.vue'
import type {SeatPlayerCardModel} from '../components/game/seat-player-card'
import {type SeatKey, useChengduGameRoom} from '../features/chengdu-game/useChengduGameRoom'
import {type SeatKey, useChengduGameRoom} from '../game/chengdu'
const route = useRoute()
const router = useRouter()
const {
roomState,
roomId,
roomName,
loggedInUserName,
wsStatus,
wsError,
wsMessages,
startGamePending,
leaveRoomPending,
canStartGame,
seatViews,
selectedTile,
actionButtons,
connectWs,
sendStartGame,
selectTile,
sendGameAction,
backHall,
} = useChengduGameRoom(route, router)
@@ -57,7 +51,6 @@ const roomStatusText = computed(() => {
if (roomState.value.status === 'finished') {
return '已结束'
}
return '等待中'
})
const currentPhaseText = computed(() => {
@@ -68,7 +61,6 @@ const currentPhaseText = computed(() => {
const phaseLabelMap: Record<string, string> = {
dealing: '发牌',
draw: '摸牌',
discard: '出牌',
action: '响应',
settle: '结算',
@@ -152,30 +144,6 @@ const seatDecor = computed<Record<SeatKey, SeatPlayerCardModel>>(() => {
return result
})
const centerTimer = computed(() => {
const wallLeft = roomState.value.game?.state?.wall.length
if (typeof wallLeft === 'number' && Number.isFinite(wallLeft)) {
return String(wallLeft).padStart(2, '0')
}
return String(roomState.value.playerCount).padStart(2, '0')
})
const selectedTileText = computed(() => selectedTile.value ?? '未选择')
const pendingClaimText = computed(() => {
const claim = roomState.value.game?.state?.pendingClaim
if (!claim) {
return '无'
}
try {
return JSON.stringify(claim)
} catch {
return '有待响应动作'
}
})
const rightMessages = computed(() => wsMessages.value.slice(-16).reverse())
const floatingMissingSuit = computed(() => {
@@ -193,10 +161,6 @@ const floatingMissingSuit = computed(() => {
})
function missingSuitLabel(value: string | null | undefined): string {
if (!value) {
return '未定'
}
const suitMap: Record<string, string> = {
wan: '万',
tong: '筒',
@@ -217,16 +181,6 @@ function getBackImage(seat: SeatKey): string {
return imageMap[seat]
}
function actionTheme(type: string): 'gold' | 'jade' | 'blue' {
if (type === 'hu' || type === 'gang') {
return 'gold'
}
if (type === 'pass') {
return 'jade'
}
return 'blue'
}
function toggleMenu(): void {
menuTriggerActive.value = true
if (menuTriggerTimer !== null) {
@@ -316,7 +270,6 @@ onBeforeUnmount(() => {
<div class="table-surface"></div>
<div class="inner-outline outer"></div>
<div class="inner-outline mid"></div>
<div class="inner-outline diamond"></div>
<div class="top-left-tools">
<div class="menu-trigger-wrap">
@@ -368,11 +321,6 @@ onBeforeUnmount(() => {
<span>{{ formattedClock }}</span>
</div>
<div class="scene-watermark">
<strong>四川麻将</strong>
<span>{{ roomState.name || roomName || '成都麻将房' }}</span>
<small>底注 6 亿 · 封顶 32 </small>
</div>
<TopPlayerCard :player="seatDecor.top"/>
<RightPlayerCard :player="seatDecor.right"/>
@@ -392,14 +340,6 @@ onBeforeUnmount(() => {
<img v-for="key in wallBacks.left" :key="key" :src="getBackImage('left')" alt=""/>
</div>
<div class="center-desk">
<span class="wind north"></span>
<span class="wind west">西</span>
<strong>{{ centerTimer }}</strong>
<span class="wind south"></span>
<span class="wind east"></span>
</div>
<div class="floating-status top">
<img v-if="floatingMissingSuit.top" :src="floatingMissingSuit.top" alt=""/>
<span>{{ seatDecor.top.missingSuitLabel }}</span>
@@ -413,30 +353,8 @@ onBeforeUnmount(() => {
<span>{{ seatDecor.right.missingSuitLabel }}</span>
</div>
<div class="claim-banner">
<span>{{ roomStatusText }}</span>
<strong>{{ currentPhaseText }}</strong>
</div>
<div class="bottom-control-panel">
<div class="control-copy">
<p>房间 {{ roomId || '--' }}</p>
<small>当前选择{{ selectedTileText }} · 待响应{{ pendingClaimText }}</small>
</div>
<div class="action-orbs">
<button
v-for="action in actionButtons"
:key="action.type"
class="orb-button"
:class="`theme-${actionTheme(action.type)}`"
type="button"
:disabled="action.disabled"
@click="sendGameAction(action.type)"
>
{{ action.label }}
</button>
</div>
<div class="player-hand" v-if="roomState.myHand.length > 0">
<button
@@ -450,7 +368,6 @@ onBeforeUnmount(() => {
{{ tile }}
</button>
</div>
<p v-else class="empty-hand">等待服务端下发 `my_hand`</p>
</div>
</div>
</section>