const app = getApp() Page({ data: { matchId: null, matchInfo: null, myRole: null, // 'challenger' | 'defender' | null canAccept: false, canReject: false, canSubmitScore: false, canConfirmScore: false, showScoreModal: false, myScore: '', opponentScore: '', loading: false }, onLoad(options) { if (options.id) { this.setData({ matchId: options.id }) this.loadMatchDetail() } }, onShow() { // 每次显示页面时刷新数据 if (this.data.matchId) { this.loadMatchDetail() } }, // 加载比赛详情 async loadMatchDetail() { this.setData({ loading: true }) try { const res = await app.request(`/api/match/${this.data.matchId}`) console.log('API完整响应:', JSON.stringify(res, null, 2)) // app.request 返回的是 { code: 0, message, data } // 所以 res.data 才是真正的数据 const matchInfo = res.data console.log('比赛详情数据:', matchInfo) console.log('数据字段:', Object.keys(matchInfo || {})) if (!matchInfo) { console.error('比赛详情数据为空') wx.showToast({ title: '数据格式错误', icon: 'none' }) this.setData({ loading: false }) return } // 检查关键字段 console.log('关键字段检查:', { hasMyRole: 'myRole' in matchInfo, myRole: matchInfo.myRole, myRoleType: typeof matchInfo.myRole, hasCanAccept: 'canAccept' in matchInfo, canAccept: matchInfo.canAccept, canAcceptType: typeof matchInfo.canAccept, hasCanReject: 'canReject' in matchInfo, canReject: matchInfo.canReject, canRejectType: typeof matchInfo.canReject, status: matchInfo.status, statusType: typeof matchInfo.status }) // 确保布尔值正确设置 let canAccept = Boolean(matchInfo.canAccept) let canReject = Boolean(matchInfo.canReject) let canSubmitScore = Boolean(matchInfo.canSubmitScore) let canConfirmScore = Boolean(matchInfo.canConfirmScore) let myRole = matchInfo.myRole || null // 临时方案:如果 myRole 为 null,尝试通过其他方式判断角色 // 适用于待接受状态(status=0)和进行中状态(status=1) if (!myRole && (matchInfo.status === 0 || matchInfo.status === 1)) { const currentUser = app.globalData.userInfo console.log('尝试临时方案识别角色:', { status: matchInfo.status, currentUser: currentUser ? { id: currentUser.id, phone: currentUser.phone } : null, defender: matchInfo.defender ? { userId: matchInfo.defender.userId, phone: matchInfo.defender.phone } : null, challenger: matchInfo.challenger ? { userId: matchInfo.challenger.userId, phone: matchInfo.challenger.phone } : null }) if (currentUser) { // 尝试通过 user_id 判断 if (matchInfo.defender && matchInfo.defender.userId && matchInfo.defender.userId == currentUser.id) { myRole = 'defender' console.log('临时方案:通过defender.userId识别为被挑战者', { defenderUserId: matchInfo.defender.userId, currentUserId: currentUser.id }) } // 尝试通过手机号判断 else if (matchInfo.defender && currentUser.phone && matchInfo.defender.phone && matchInfo.defender.phone === currentUser.phone) { myRole = 'defender' console.log('临时方案:通过手机号识别为被挑战者', { defenderPhone: matchInfo.defender.phone, currentUserPhone: currentUser.phone }) } // 如果都不匹配,检查是否是挑战者 else if (matchInfo.challenger && matchInfo.challenger.userId && matchInfo.challenger.userId == currentUser.id) { myRole = 'challenger' console.log('临时方案:识别为挑战者(通过userId)') } // 通过手机号识别挑战者 else if (matchInfo.challenger && currentUser.phone && matchInfo.challenger.phone && matchInfo.challenger.phone === currentUser.phone) { myRole = 'challenger' console.log('临时方案:识别为挑战者(通过手机号)') } } } // 如果状态是待接受且角色是被挑战者,强制设置权限(即使后端没有返回) if (matchInfo.status === 0 && myRole === 'defender') { canAccept = true canReject = true console.log('强制设置接受/拒绝权限(状态=0,角色=defender)') } // 最后的备用方案:如果状态是待接受,且当前用户不是挑战者,则可能是被挑战者 // 这种情况下,显示按钮让用户尝试接受/拒绝(如果用户不是被挑战者,后端会拒绝) if (matchInfo.status === 0 && !myRole && !canAccept && !canReject) { // 检查当前用户是否是挑战者 const currentUser = app.globalData.userInfo const isChallenger = currentUser && matchInfo.challenger && (matchInfo.challenger.userId == currentUser.id || (currentUser.phone && matchInfo.challenger.phone === currentUser.phone)) // 如果不是挑战者,可能是被挑战者,显示按钮 if (!isChallenger) { myRole = 'defender' canAccept = true canReject = true console.log('备用方案:状态为待接受且不是挑战者,假设是被挑战者,显示按钮') } } // 处理"进行中"状态(status=1)的操作权限 if (matchInfo.status === 1) { const game = matchInfo.games && matchInfo.games[0] if (game) { console.log('处理进行中状态的操作权限:', { gameStatus: game.status, submitBy: game.submitBy, confirmStatus: game.confirmStatus, myRole, canSubmitScore, canConfirmScore }) // 如果游戏状态为1(进行中)且未提交比分,双方都可以填写比分 if (game.status === 1 && !game.submitBy) { // 如果后端没有返回 canSubmitScore,但状态允许,则设置权限 // 即使 myRole 为 null,也允许填写(后续会通过游戏信息识别角色) if (!canSubmitScore) { canSubmitScore = true console.log('进行中状态:设置填写比分权限(游戏状态=1,未提交)') } } // 如果游戏状态为2(已提交)且对方已提交,等待我确认 else if (game.status === 2 && game.submitBy) { // 判断当前用户是否是提交者(submitBy 是 ladder_user_id) let isSubmitter = false if (myRole) { // 如果已识别角色,通过比较 submitBy 和 challenger/defender 的 id(ladder_user_id)来判断 if (myRole === 'challenger' && matchInfo.challenger && game.submitBy == matchInfo.challenger.id) { isSubmitter = true console.log('当前用户是提交者(挑战者)') } else if (myRole === 'defender' && matchInfo.defender && game.submitBy == matchInfo.defender.id) { isSubmitter = true console.log('当前用户是提交者(被挑战者)') } } else { // 如果 myRole 为 null,通过比较当前用户的 user_id 和 challenger/defender 的 user_id 来判断 const currentUser = app.globalData.userInfo if (currentUser) { // 检查提交者是否是挑战者 if (matchInfo.challenger && game.submitBy == matchInfo.challenger.id && currentUser.id == matchInfo.challenger.userId) { isSubmitter = true console.log('当前用户是提交者(通过challenger判断)') } // 检查提交者是否是被挑战者 else if (matchInfo.defender && game.submitBy == matchInfo.defender.id && currentUser.id == matchInfo.defender.userId) { isSubmitter = true console.log('当前用户是提交者(通过defender判断)') } } } // 如果不是提交者,且确认状态为待确认,则可以确认比分 if (!isSubmitter && game.confirmStatus === 0) { if (!canConfirmScore) { canConfirmScore = true console.log('进行中状态:设置确认比分权限(对方已提交,等待确认)', { submitBy: game.submitBy, challengerId: matchInfo.challenger ? matchInfo.challenger.id : null, defenderId: matchInfo.defender ? matchInfo.defender.id : null, myRole }) } } } } // 如果 myRole 仍然为 null,但状态是进行中,尝试通过游戏中的 player1_id 和 player2_id 判断 if (!myRole && game) { const currentUser = app.globalData.userInfo if (currentUser) { console.log('尝试通过游戏信息识别角色:', { player1Id: game.player1Id, player2Id: game.player2Id, challengerId: matchInfo.challenger ? matchInfo.challenger.id : null, defenderId: matchInfo.defender ? matchInfo.defender.id : null, currentUserId: currentUser.id, challengerUserId: matchInfo.challenger ? matchInfo.challenger.userId : null, defenderUserId: matchInfo.defender ? matchInfo.defender.userId : null }) // 通过比较 challenger/defender 的 id(ladder_user_id)和 player1_id/player2_id 来判断 if (matchInfo.challenger && matchInfo.challenger.id == game.player1Id) { // 如果当前用户是挑战者,且挑战者是 player1 if (currentUser.id == matchInfo.challenger.userId) { myRole = 'challenger' console.log('通过游戏player1Id识别为挑战者') } } else if (matchInfo.challenger && matchInfo.challenger.id == game.player2Id) { // 如果当前用户是挑战者,且挑战者是 player2 if (currentUser.id == matchInfo.challenger.userId) { myRole = 'challenger' console.log('通过游戏player2Id识别为挑战者') } } if (matchInfo.defender && matchInfo.defender.id == game.player1Id) { // 如果当前用户是被挑战者,且被挑战者是 player1 if (currentUser.id == matchInfo.defender.userId) { myRole = 'defender' console.log('通过游戏player1Id识别为被挑战者') } } else if (matchInfo.defender && matchInfo.defender.id == game.player2Id) { // 如果当前用户是被挑战者,且被挑战者是 player2 if (currentUser.id == matchInfo.defender.userId) { myRole = 'defender' console.log('通过游戏player2Id识别为被挑战者') } } // 如果识别到角色,重新检查操作权限 if (myRole) { console.log('识别到角色后,重新检查操作权限:', { myRole, gameStatus: game.status, submitBy: game.submitBy }) // 如果游戏状态为1(进行中)且未提交比分,可以填写比分 if (game.status === 1 && !game.submitBy) { canSubmitScore = true console.log('识别角色后,设置填写比分权限') } // 如果游戏状态为2(已提交)且对方已提交,等待我确认 else if (game.status === 2 && game.submitBy) { // 判断当前用户是否是提交者 const isSubmitter = (myRole === 'challenger' && matchInfo.challenger && game.submitBy == matchInfo.challenger.id) || (myRole === 'defender' && matchInfo.defender && game.submitBy == matchInfo.defender.id) if (!isSubmitter && game.confirmStatus === 0) { canConfirmScore = true console.log('识别角色后,设置确认比分权限') } } } } } } console.log('最终设置的操作权限:', { canAccept, canReject, canSubmitScore, canConfirmScore, myRole, status: matchInfo.status, defenderInfo: matchInfo.defender ? { id: matchInfo.defender.id, userId: matchInfo.defender.userId, phone: matchInfo.defender.phone, realName: matchInfo.defender.realName } : null, challengerInfo: matchInfo.challenger ? { id: matchInfo.challenger.id, userId: matchInfo.challenger.userId, phone: matchInfo.challenger.phone, realName: matchInfo.challenger.realName } : null, currentUser: app.globalData.userInfo ? { id: app.globalData.userInfo.id, phone: app.globalData.userInfo.phone } : null }) this.setData({ matchInfo, myRole, canAccept, canReject, canSubmitScore, canConfirmScore, loading: false }) // 再次检查,如果还是没有按钮,输出详细日志 if (matchInfo.status === 0 && !canAccept && !canReject) { console.error('警告:状态为待接受但没有操作按钮!', { myRole, canAccept, canReject, matchInfoStatus: matchInfo.status, defenderUserId: matchInfo.defender ? matchInfo.defender.userId : null, currentUserId: app.globalData.userInfo ? app.globalData.userInfo.id : null, defenderPhone: matchInfo.defender ? matchInfo.defender.phone : null, currentUserPhone: app.globalData.userInfo ? app.globalData.userInfo.phone : null }) } } catch (e) { this.setData({ loading: false }) console.error('加载比赛详情失败:', e) console.error('错误详情:', e.message, e.data, e) wx.showToast({ title: '加载失败: ' + (e.message || '未知错误'), icon: 'none', duration: 3000 }) } }, // 处理挑战请求(从WebSocket调用) handleChallengeRequest(challengeData) { // 如果当前页面是挑战赛详情且是同一个比赛,显示弹框 if (this.data.matchId == challengeData.matchId) { this.showChallengeModal(challengeData) } else { // 否则跳转到挑战赛详情页面 wx.navigateTo({ url: `/pages/match/challenge-detail/index?id=${challengeData.matchId}` }) } }, // 显示挑战弹框 showChallengeModal(challengeData) { wx.showModal({ title: '收到挑战', content: `${challengeData.challenger.realName}(Lv${challengeData.challenger.level}, 战力${challengeData.challenger.powerScore}) 向你发起挑战`, confirmText: '接受', cancelText: '拒绝', success: (res) => { this.respondChallenge(res.confirm) } }) }, // 响应挑战 async respondChallenge(accept) { wx.showLoading({ title: accept ? '接受中...' : '拒绝中...' }) try { await app.request('/api/match/challenge/respond', { match_id: this.data.matchId, accept: accept }, 'POST') wx.hideLoading() wx.showToast({ title: accept ? '已接受挑战' : '已拒绝挑战', icon: 'success' }) // 刷新数据 setTimeout(() => { this.loadMatchDetail() }, 1500) } catch (e) { wx.hideLoading() console.error('响应挑战失败:', e) wx.showToast({ title: '操作失败', icon: 'none' }) } }, // 接受挑战 acceptChallenge() { this.respondChallenge(true) }, // 拒绝挑战 rejectChallenge() { wx.showModal({ title: '确认拒绝', content: '确定要拒绝这个挑战吗?', success: (res) => { if (res.confirm) { this.respondChallenge(false) } } }) }, // 打开填写比分弹框 openScoreModal() { this.setData({ showScoreModal: true, myScore: '', opponentScore: '' }) }, // 关闭填写比分弹框 closeScoreModal() { this.setData({ showScoreModal: false }) }, // 输入我的比分 onMyScoreInput(e) { this.setData({ myScore: e.detail.value }) }, // 输入对手比分 onOpponentScoreInput(e) { this.setData({ opponentScore: e.detail.value }) }, // 提交比分 async submitScore() { const { myScore, opponentScore } = this.data if (!myScore || !opponentScore) { wx.showToast({ title: '请填写完整比分', icon: 'none' }) return } const myScoreNum = parseInt(myScore) const opponentScoreNum = parseInt(opponentScore) if (isNaN(myScoreNum) || isNaN(opponentScoreNum)) { wx.showToast({ title: '请输入有效数字', icon: 'none' }) return } if (myScoreNum === opponentScoreNum) { wx.showToast({ title: '比分不能相同', icon: 'none' }) return } wx.showLoading({ title: '提交中...' }) try { await app.request('/api/match/challenge/submit-score', { match_id: this.data.matchId, my_score: myScoreNum, opponent_score: opponentScoreNum }, 'POST') wx.hideLoading() wx.showToast({ title: '比分已提交,等待对方确认', icon: 'success' }) this.closeScoreModal() // 刷新数据 setTimeout(() => { this.loadMatchDetail() }, 1500) } catch (e) { wx.hideLoading() console.error('提交比分失败:', e) wx.showToast({ title: e.message || '提交失败', icon: 'none' }) } }, // 确认比分 async confirmScore(confirm) { const game = this.data.matchInfo.games && this.data.matchInfo.games[0] if (!game) { wx.showToast({ title: '比赛信息错误', icon: 'none' }) return } wx.showLoading({ title: '处理中...' }) try { await app.request('/api/match/challenge/confirm-score', { game_id: game.id, confirm: confirm }, 'POST') wx.hideLoading() wx.showToast({ title: confirm ? '已确认比分' : '已标记争议', icon: 'success' }) // 刷新数据 setTimeout(() => { this.loadMatchDetail() }, 1500) } catch (e) { wx.hideLoading() console.error('确认比分失败:', e) wx.showToast({ title: '操作失败', icon: 'none' }) } }, // 确认比分按钮 confirmScoreBtn() { const game = this.data.matchInfo.games && this.data.matchInfo.games[0] if (!game) { wx.showToast({ title: '比赛信息错误', icon: 'none' }) return } // 根据当前用户角色显示正确的比分信息 let myScore = 0 let opponentScore = 0 let myName = '' let opponentName = '' if (this.data.myRole === 'challenger') { // 挑战者是 player1 还是 player2? if (this.data.matchInfo.challenger && this.data.matchInfo.challenger.id == game.player1Id) { myScore = game.player1Score || 0 opponentScore = game.player2Score || 0 myName = this.data.matchInfo.challenger.realName || '挑战者' opponentName = (this.data.matchInfo.defender && this.data.matchInfo.defender.realName) || '被挑战者' } else if (this.data.matchInfo.challenger && this.data.matchInfo.challenger.id == game.player2Id) { myScore = game.player2Score || 0 opponentScore = game.player1Score || 0 myName = this.data.matchInfo.challenger.realName || '挑战者' opponentName = (this.data.matchInfo.defender && this.data.matchInfo.defender.realName) || '被挑战者' } else { // 如果无法确定,使用默认显示 myScore = game.player1Score || 0 opponentScore = game.player2Score || 0 } } else if (this.data.myRole === 'defender') { // 被挑战者是 player1 还是 player2? if (this.data.matchInfo.defender && this.data.matchInfo.defender.id == game.player1Id) { myScore = game.player1Score || 0 opponentScore = game.player2Score || 0 myName = this.data.matchInfo.defender.realName || '被挑战者' opponentName = (this.data.matchInfo.challenger && this.data.matchInfo.challenger.realName) || '挑战者' } else if (this.data.matchInfo.defender && this.data.matchInfo.defender.id == game.player2Id) { myScore = game.player2Score || 0 opponentScore = game.player1Score || 0 myName = this.data.matchInfo.defender.realName || '被挑战者' opponentName = (this.data.matchInfo.challenger && this.data.matchInfo.challenger.realName) || '挑战者' } else { // 如果无法确定,使用默认显示 myScore = game.player1Score || 0 opponentScore = game.player2Score || 0 } } else { // 如果角色未知,使用默认显示 myScore = game.player1Score || 0 opponentScore = game.player2Score || 0 } wx.showModal({ title: '确认比分', content: `对方提交的比分为:\n${opponentName}: ${opponentScore}\n${myName}: ${myScore}\n\n请确认此比分是否正确?`, confirmText: '确认', cancelText: '有争议', success: (res) => { if (res.confirm) { this.confirmScore(true) } else { // 有争议 wx.showModal({ title: '确认争议', content: '确定要标记为有争议吗?标记后需要重新比赛。', confirmText: '确定', cancelText: '取消', success: (res2) => { if (res2.confirm) { this.confirmScore(false) } } }) } } }) }, // 阻止事件冒泡 stopPropagation() { // 空函数,用于阻止事件冒泡 } })