yingsa/miniprogram/app.js
2026-01-20 08:50:50 +08:00

213 lines
5.5 KiB
JavaScript

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
})
})
}
})