diff --git a/components/activity/LotteryResultPopup.vue b/components/activity/LotteryResultPopup.vue
index 1d3b9b8..98441fa 100644
--- a/components/activity/LotteryResultPopup.vue
+++ b/components/activity/LotteryResultPopup.vue
@@ -14,7 +14,7 @@
🎉
- 恭喜中奖
+ 恭喜获得
@@ -58,7 +58,7 @@
✨
- 收下奖励
+ 知道了!
diff --git a/pages-activity/activity/duiduipeng/index.vue b/pages-activity/activity/duiduipeng/index.vue
index 9a18150..db4e536 100644
--- a/pages-activity/activity/duiduipeng/index.vue
+++ b/pages-activity/activity/duiduipeng/index.vue
@@ -94,13 +94,18 @@
+
总对数
{{ totalPairs }}
- 摸牌机会
- {{ chance }}
+ {{ countdownSeconds > 0 ? '倒计时' : '摸牌机会' }}
+
+ {{ countdownSeconds > 0 ? `${countdownSeconds}s` : chance }}
+
牌组剩余
@@ -137,9 +142,6 @@
-
@@ -240,6 +242,8 @@ const chance = ref(0)
const totalPairs = ref(0)
const gameFinished = ref(false)
const pickedHandIndex = ref(-1)
+const countdownTimer = ref(null)
+const countdownSeconds = ref(0)
const gameIdText = computed(() => String((gameEntry.value && gameEntry.value.game_id) || ''))
const deckRemaining = computed(() => {
const entry = gameEntry.value || null
@@ -738,7 +742,14 @@ async function openGame(latest) {
gameError.value = ''
await applyResumeEntry(gameEntry.value)
restoreOrInitLocalGame()
- await autoDrawIfStuck()
+
+ // 检查是否摸牌次数为0且无法继续配对
+ if (Number(chance.value || 0) <= 0 && !canEliminateNow()) {
+ // 使用 setTimeout 确保界面先显示出来,再启动倒计时
+ setTimeout(() => {
+ startCountdown()
+ }, 500)
+ }
}
function closeGame() {
@@ -748,6 +759,44 @@ function closeGame() {
gameEntry.value = null
gameIssueId.value = ''
pickedHandIndex.value = -1
+ // 清理倒计时
+ clearCountdown()
+}
+
+function startCountdown() {
+ // 清除之前的倒计时
+ clearCountdown()
+
+ countdownSeconds.value = 3
+ uni.showToast({
+ title: `摸牌次数已用完,${countdownSeconds.value}秒后结束游戏`,
+ icon: 'none',
+ duration: 1000
+ })
+
+ countdownTimer.value = setInterval(() => {
+ countdownSeconds.value -= 1
+
+ if (countdownSeconds.value > 0) {
+ uni.showToast({
+ title: `${countdownSeconds.value}秒后结束游戏`,
+ icon: 'none',
+ duration: 900
+ })
+ } else {
+ // 倒计时结束,执行游戏结束逻辑
+ clearCountdown()
+ finishAndReport()
+ }
+ }, 1000)
+}
+
+function clearCountdown() {
+ if (countdownTimer.value) {
+ clearInterval(countdownTimer.value)
+ countdownTimer.value = null
+ }
+ countdownSeconds.value = 0
}
function getSelectedCodeFromEntry(entry) {
@@ -918,6 +967,11 @@ function manualDraw() {
chance.value = Math.max(0, Number(chance.value || 0) - 1)
pickedHandIndex.value = -1
persistLocalGame()
+
+ // 检查摸牌次数是否为0且无法继续配对
+ if (Number(chance.value || 0) <= 0 && !canEliminateNow()) {
+ startCountdown()
+ }
}
async function autoDrawIfStuck() {
@@ -977,7 +1031,13 @@ async function onCellTap(cell) {
chance.value = Number(chance.value || 0) + 1
pickedHandIndex.value = -1
persistLocalGame()
- await autoDrawIfStuck()
+
+ // 检查配对后是否无法继续配对且摸牌次数为0
+ if (!canEliminateNow() && Number(chance.value || 0) <= 0) {
+ startCountdown()
+ }
+
+ // 移除自动摸牌,让玩家手动控制
return
}
@@ -1099,8 +1159,17 @@ async function advanceOne() {
return
}
+ // 移除自动摸牌逻辑,让玩家手动控制
+ // 如果无法配对,提示玩家需要摸牌
if (!canEliminateNow()) {
- await autoDrawIfStuck()
+ if (Number(chance.value || 0) > 0 && canDrawOne()) {
+ uni.showToast({ title: '请摸牌后再试', icon: 'none' })
+ } else if (Number(chance.value || 0) <= 0 && !canDrawOne()) {
+ // 摸牌次数为0且无法继续抽牌,再次确认场上无法配对才结束游戏
+ if (!canEliminateNow()) {
+ await finishAndReport()
+ }
+ }
return
}
@@ -2149,11 +2218,40 @@ onLoad((opts) => {
.game-stats {
display: flex;
justify-content: center;
- gap: 48rpx;
+ align-items: center;
+ gap: 32rpx;
padding: 24rpx 32rpx;
margin: 0 32rpx;
}
+.game-btn-draw {
+ flex-shrink: 0;
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.15);
+ border: 3rpx solid rgba(255, 255, 255, 0.3);
+ color: #FF6B6B;
+ font-size: 28rpx;
+ font-weight: 800;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ backdrop-filter: blur(10rpx);
+ box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.3);
+ transition: all 0.3s;
+
+ &:active {
+ transform: scale(0.9);
+ background: rgba(255, 255, 255, 0.25);
+ }
+
+ &[disabled] {
+ opacity: 0.3;
+ transform: none;
+ }
+}
+
.stat-item {
display: flex;
flex-direction: column;
@@ -2171,6 +2269,22 @@ onLoad((opts) => {
font-weight: 900;
color: $accent-gold;
font-family: 'DIN Alternate', sans-serif;
+
+ &.countdown {
+ color: #FF6B6B;
+ animation: pulse 1s ease-in-out infinite;
+ }
+}
+
+@keyframes pulse {
+ 0%, 100% {
+ opacity: 1;
+ transform: scale(1);
+ }
+ 50% {
+ opacity: 0.7;
+ transform: scale(1.1);
+ }
}
.game-content {
@@ -2266,13 +2380,13 @@ onLoad((opts) => {
.game-actions {
display: flex;
- gap: 24rpx;
+ justify-content: center;
padding: 32rpx;
padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
}
.game-btn {
- flex: 1;
+ width: 400rpx;
height: 96rpx;
border-radius: 48rpx;
font-size: 32rpx;
@@ -2282,11 +2396,24 @@ onLoad((opts) => {
justify-content: center;
border: none;
transition: all 0.3s;
-
+ color: #fff;
+
+ &.btn-primary {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.4);
+ }
+
+ &.btn-secondary {
+ background: rgba(255, 255, 255, 0.15);
+ border: 2rpx solid rgba(255, 255, 255, 0.3);
+ color: rgba(255, 255, 255, 0.9);
+ backdrop-filter: blur(10rpx);
+ }
+
&:active {
transform: scale(0.95);
}
-
+
&[disabled] {
opacity: 0.4;
}