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
}