feat(chengdu): 更新结算界面添加准备状态和房间管理功能
- 添加玩家准备状态显示和切换功能 - 实现房主控制下一局开始的游戏流程 - 添加退出房间按钮和相关状态管理 - 集成准备状态的计算逻辑和UI展示 - 更新组件props传递准备和房间状态数据 - 重构结算界面按钮布局和交互逻辑
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
isLastRound: boolean
|
||||
currentRound: number
|
||||
@@ -10,16 +12,27 @@ defineProps<{
|
||||
score: number
|
||||
isWinner: boolean
|
||||
seatIndex: number
|
||||
isReady: boolean
|
||||
}>
|
||||
loggedInUserId: string
|
||||
nextRoundPending: boolean
|
||||
isRoomOwner: boolean
|
||||
selfIsReady: boolean
|
||||
readyTogglePending: boolean
|
||||
startNextRoundPending: boolean
|
||||
leaveRoomPending: boolean
|
||||
settlementCountdown: number | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
nextRound: []
|
||||
ready: []
|
||||
startNextRound: []
|
||||
exit: []
|
||||
backHall: []
|
||||
}>()
|
||||
|
||||
const allPlayersReady = computed(() =>
|
||||
props.settlementPlayers.length > 0 && props.settlementPlayers.every((p) => p.isReady),
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -44,29 +57,63 @@ const emit = defineEmits<{
|
||||
<span class="settlement-score" :class="{ 'is-positive': item.score > 0, 'is-negative': item.score < 0 }">
|
||||
{{ item.score > 0 ? '+' : '' }}{{ item.score }}
|
||||
</span>
|
||||
<span class="settlement-ready-badge" :class="{ 'is-ready': item.isReady }">
|
||||
{{ item.isReady ? '已准备' : '等待...' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settlement-actions">
|
||||
<button
|
||||
v-if="!isLastRound"
|
||||
class="ready-toggle ready-toggle-inline settlement-btn"
|
||||
type="button"
|
||||
:disabled="nextRoundPending"
|
||||
@click="emit('nextRound')"
|
||||
>
|
||||
<span class="ready-toggle-label">
|
||||
{{
|
||||
nextRoundPending
|
||||
? '准备中...'
|
||||
: settlementCountdown != null && settlementCountdown > 0
|
||||
? `下一局 (${settlementCountdown}s)`
|
||||
: '下一局'
|
||||
}}
|
||||
</span>
|
||||
</button>
|
||||
<!-- 非末局:准备按钮 + 房主开始游戏按钮 -->
|
||||
<template v-if="!isLastRound">
|
||||
<button
|
||||
class="ready-toggle ready-toggle-inline settlement-btn"
|
||||
:class="{ 'is-ready': selfIsReady }"
|
||||
type="button"
|
||||
:disabled="selfIsReady || readyTogglePending"
|
||||
@click="emit('ready')"
|
||||
>
|
||||
<span class="ready-toggle-label">
|
||||
{{
|
||||
readyTogglePending
|
||||
? '请求中...'
|
||||
: selfIsReady
|
||||
? '已准备'
|
||||
: '准备'
|
||||
}}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="isRoomOwner"
|
||||
class="ready-toggle ready-toggle-inline settlement-btn"
|
||||
type="button"
|
||||
:disabled="!allPlayersReady || startNextRoundPending"
|
||||
@click="emit('startNextRound')"
|
||||
>
|
||||
<span class="ready-toggle-label">
|
||||
{{
|
||||
startNextRoundPending
|
||||
? '开始中...'
|
||||
: allPlayersReady
|
||||
? '开始游戏'
|
||||
: `开始游戏 (${settlementPlayers.filter((p) => p.isReady).length}/${settlementPlayers.length})`
|
||||
}}
|
||||
</span>
|
||||
</button>
|
||||
<p v-else-if="allPlayersReady" class="settlement-waiting-owner">等待房主开始...</p>
|
||||
</template>
|
||||
<!-- 末局:返回大厅 -->
|
||||
<button v-else class="ready-toggle ready-toggle-inline settlement-btn" type="button" @click="emit('backHall')">
|
||||
<span class="ready-toggle-label">返回大厅</span>
|
||||
</button>
|
||||
<!-- 退出按钮(始终显示) -->
|
||||
<button
|
||||
class="ready-toggle ready-toggle-inline settlement-btn settlement-btn-exit"
|
||||
type="button"
|
||||
:disabled="leaveRoomPending"
|
||||
@click="emit('exit')"
|
||||
>
|
||||
<span class="ready-toggle-label">{{ leaveRoomPending ? '退出中...' : '退出' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -41,11 +41,11 @@ const {
|
||||
roomCountdown,
|
||||
leaveRoomPending,
|
||||
readyTogglePending,
|
||||
nextRoundPending: startNextRoundPending,
|
||||
dingQuePending,
|
||||
discardPending,
|
||||
claimActionPending,
|
||||
turnActionPending,
|
||||
nextRoundPending,
|
||||
selectedDiscardTileId,
|
||||
menuOpen,
|
||||
isTrustMode,
|
||||
@@ -263,9 +263,15 @@ function handleLeaveRoom(): void {
|
||||
:total-rounds="gameStore.totalRounds"
|
||||
:settlement-players="settlementPlayers"
|
||||
:logged-in-user-id="loggedInUserId"
|
||||
:next-round-pending="nextRoundPending"
|
||||
:is-room-owner="isRoomOwner"
|
||||
:self-is-ready="myReadyState"
|
||||
:ready-toggle-pending="readyTogglePending"
|
||||
:start-next-round-pending="startNextRoundPending"
|
||||
:leave-room-pending="leaveRoomPending"
|
||||
:settlement-countdown="settlementCountdown"
|
||||
@next-round="nextRound"
|
||||
@ready="toggleReadyState"
|
||||
@start-next-round="nextRound"
|
||||
@exit="backHall"
|
||||
@back-hall="backHall"
|
||||
/>
|
||||
|
||||
|
||||
@@ -230,6 +230,7 @@ export function useChengduTableView(deps: TableViewDeps): TableViewResult {
|
||||
score: deps.gameStore.scores[player.playerId] ?? 0,
|
||||
isWinner: winnerSet.has(player.playerId),
|
||||
seatIndex: player.seatIndex,
|
||||
isReady: Boolean(player.isReady),
|
||||
}))
|
||||
.sort((a, b) => b.score - a.score)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user