App({ globalData: { userInfo: null, token: null, currentStore: null, ladderUser: null, wsConnected: false }, onLaunch() { // 从本地存储读取token const token = wx.getStorageSync('token') if (token) { this.globalData.token = token this.getUserInfo() } }, // 登录 login() { return new Promise((resolve, reject) => { wx.login({ success: res => { wx.request({ url: `${this.globalData.baseUrl}/api/user/login`, method: 'POST', data: { code: res.code }, success: loginRes => { if (loginRes.data.code === 0) { this.globalData.token = loginRes.data.data.token this.globalData.userInfo = loginRes.data.data.userInfo wx.setStorageSync('token', loginRes.data.data.token) this.connectWebSocket() resolve(loginRes.data.data) } else { reject(loginRes.data) } }, fail: reject }) }, fail: reject }) }) }, // 获取用户信息 getUserInfo() { return new Promise((resolve, reject) => { this.request('/api/user/info').then(res => { this.globalData.userInfo = res.data this.connectWebSocket() resolve(res.data) }).catch(reject) }) }, // 获取当前门店 getCurrentStore() { return new Promise((resolve, reject) => { wx.getLocation({ type: 'gcj02', success: loc => { this.request('/api/user/current-store', { latitude: loc.latitude, longitude: loc.longitude }).then(res => { this.globalData.currentStore = res.data if (res.data?.ladderUserId) { this.getLadderUser(res.data.storeId) } resolve(res.data) }).catch(reject) }, fail: () => { // 无法获取位置,使用默认门店 this.request('/api/user/current-store').then(res => { this.globalData.currentStore = res.data resolve(res.data) }).catch(reject) } }) }) }, // 获取天梯用户信息 getLadderUser(storeId) { return this.request('/api/user/ladder-info', { store_id: storeId }).then(res => { if (res.data && res.data.length > 0) { this.globalData.ladderUser = res.data[0] } return res.data }) }, // WebSocket连接 connectWebSocket() { if (this.globalData.wsConnected || !this.globalData.token) return const wsUrl = this.globalData.wsUrl || 'ws://localhost:3000/ws' this.ws = wx.connectSocket({ url: wsUrl, success: () => { console.log('WebSocket连接中...') } }) wx.onSocketOpen(() => { console.log('WebSocket已连接') this.globalData.wsConnected = true // 发送认证 wx.sendSocketMessage({ data: JSON.stringify({ type: 'auth', token: this.globalData.token }) }) }) wx.onSocketMessage(res => { const data = JSON.parse(res.data) this.handleWsMessage(data) }) wx.onSocketClose(() => { console.log('WebSocket已断开') this.globalData.wsConnected = false // 尝试重连 setTimeout(() => { this.connectWebSocket() }, 5000) }) wx.onSocketError(err => { console.error('WebSocket错误:', err) }) }, // 处理WebSocket消息 handleWsMessage(data) { switch (data.type) { case 'challenge_request': // 收到挑战请求 wx.showModal({ title: '收到挑战', content: `${data.data.challenger.realName} 向你发起挑战`, confirmText: '接受', cancelText: '拒绝', success: res => { this.request('/api/match/challenge/respond', { match_id: data.data.matchId, accept: res.confirm }, 'POST') } }) break case 'score_confirm_request': // 收到比分确认请求 wx.showModal({ title: '确认比分', content: `比分: ${data.data.player1Score} : ${data.data.player2Score}`, confirmText: '确认', cancelText: '有争议', success: res => { this.request('/api/match/challenge/confirm-score', { game_id: data.data.gameId, confirm: res.confirm }, 'POST') } }) break case 'match_paired': // 排位赛匹配通知 wx.showModal({ title: '匹配成功', content: `你的对手是: ${data.data.opponent.realName}`, showCancel: false }) break } }, // 封装请求 request(url, data = {}, method = 'GET') { return new Promise((resolve, reject) => { wx.request({ url: `${this.globalData.baseUrl}${url}`, method, data, header: { 'Authorization': `Bearer ${this.globalData.token}` }, success: res => { if (res.data.code === 0) { resolve(res.data) } else if (res.data.code === 401) { // 登录过期 this.globalData.token = null wx.removeStorageSync('token') wx.reLaunch({ url: '/pages/user/index' }) reject(res.data) } else { wx.showToast({ title: res.data.message, icon: 'none' }) reject(res.data) } }, fail: reject }) }) } })