diff --git a/pages-game/game/minesweeper/index.vue b/pages-game/game/minesweeper/index.vue index 6963962..70e6479 100644 --- a/pages-game/game/minesweeper/index.vue +++ b/pages-game/game/minesweeper/index.vue @@ -46,16 +46,24 @@ {{ entering ? '正在进入...' : (ticketCount > 0 ? '立即开局' : '资格不足') }} + + + 🍭 免费试玩 (正式场获胜有奖) + + - 📡 对战列表 / 围观 + 📡 对战列表 / 围观 @@ -98,8 +106,10 @@ export default { this.loading = false } }, - async enterGame() { - if (this.ticketCount <= 0 || this.entering) return + async enterGame(code) { + const targetCode = code || this.gameCode + if (targetCode !== 'minesweeper_free' && this.ticketCount <= 0) return + if (this.entering) return this.entering = true try { @@ -107,7 +117,7 @@ export default { url: '/api/app/games/enter', method: 'POST', data: { - game_code: this.gameCode + game_code: targetCode } }) @@ -310,10 +320,57 @@ export default { &.disabled { background: $text-disabled; box-shadow: none; + opacity: 0.6; pointer-events: none; } } +.btn-free { + margin-top: 24rpx; + height: 110rpx; + width: 100%; + border-radius: 55rpx; + background: rgba($brand-primary, 0.15); + border: 1px solid rgba($brand-primary, 0.3); + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s; + + &:active { + transform: scale(0.98); + background: rgba($brand-primary, 0.25); + } + + &.disabled { + opacity: 0.5; + pointer-events: none; + } +} + +.free-btn-text { + color: $brand-primary; + font-size: 32rpx; + font-weight: 700; +} + +.btn-secondary { + margin-top: 24rpx; + background: rgba(255,255,255,0.05); + border: 1px solid rgba(255,255,255,0.1); + border-radius: 55rpx; + height: 110rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.secondary-btn-text { + color: #94a3b8; + font-size: 32rpx; + font-weight: 600; +} + .enter-btn-text { font-size: 36rpx; letter-spacing: 2rpx; diff --git a/utils/nakamaManager.js b/utils/nakamaManager.js index b6f2456..9fd7484 100644 --- a/utils/nakamaManager.js +++ b/utils/nakamaManager.js @@ -118,7 +118,12 @@ class NakamaManager { // 这里不自动连接,由业务层在适当时机调用 connect() resolve(this.session); } else { - reject(new Error('Authentication failed: ' + JSON.stringify(res.data))); + // 检查是否收到 HTML 响应(通常意味着跳转或安全拦截) + if (typeof res.data === 'string' && (res.data.trim().toLowerCase().startsWith(' { diff --git a/utils/request.js b/utils/request.js index e726740..0dce64b 100644 --- a/utils/request.js +++ b/utils/request.js @@ -11,10 +11,10 @@ function handleAuthExpired() { content: '账号登录已过期,请重新登录', showCancel: true, success: (res) => { - if (res.cancel) { - console.log('用户点击取消'); - return - } + if (res.cancel) { + console.log('用户点击取消'); + return + } authModalShown = false uni.navigateTo({ url: '/pages/login/index' }) } @@ -85,17 +85,26 @@ export function redeemProductByPoints(user_id, product_id, quantity) { }) } +let cachedSystemInfo = null + +function getSystemInfo() { + if (cachedSystemInfo) return cachedSystemInfo + try { + cachedSystemInfo = uni.getSystemInfoSync() + return cachedSystemInfo + } catch (_) { + return {} + } +} + function getLanguage() { - try { return (uni.getSystemInfoSync().language || 'zh-CN') } catch (_) { return 'zh-CN' } + return getSystemInfo().language || 'zh-CN' } function getPlatform() { - try { - // 简单判断当前运行平台 - if (typeof wx !== 'undefined') return 'mp-weixin' - const info = uni.getSystemInfoSync() - return info.platform || 'unknown' - } catch (_) { return 'unknown' } + // 简单判断当前运行平台 + if (typeof wx !== 'undefined') return 'mp-weixin' + return getSystemInfo().platform || 'unknown' } function getDeviceId() { @@ -110,7 +119,7 @@ function getDeviceId() { } function buildDefaultHeaders() { - const info = uni.getSystemInfoSync() + const info = getSystemInfo() const lang = info.language || 'zh-CN' const platform = info.platform || 'unknown' const brand = info.brand || '' @@ -120,7 +129,7 @@ function buildDefaultHeaders() { const screen = `${info.screenWidth}x${info.screenHeight}` const pixelRatio = info.pixelRatio || 1 const windowSize = `${info.windowWidth}x${info.windowHeight}` - return { + const headers = { 'Accept': 'application/json', 'content-type': 'application/json', 'X-Requested-With': 'XMLHttpRequest', @@ -135,7 +144,12 @@ function buildDefaultHeaders() { 'X-Screen': screen, 'X-Pixel-Ratio': pixelRatio, 'X-Window': windowSize, - 'Cache-Control': 'no-cache', - 'User-Agent': `UniApp/${platform} (${brand} ${model}; ${osName} ${osVersion}) MiniProgram` + 'Cache-Control': 'no-cache' } + // 小程序环境禁止设置 User-Agent + // #ifndef MP + headers['User-Agent'] = `UniApp/${platform} (${brand} ${model}; ${osName} ${osVersion})` + // #endif + + return headers }