const config = require("./config"); App({ globalData: { userInfo: null, token: null, currentStore: null, ladderUser: null, wsConnected: false, // 微信登录临时信息 wxLoginInfo: null, // 从配置文件读取 baseUrl: config.baseUrl, wsUrl: config.wsUrl, }, onLaunch() { // 从本地存储读取token const token = wx.getStorageSync("token"); if (token) { this.globalData.token = token; this.getUserInfo(); } }, // 微信登录(第一步:获取openid和session_key) wxLogin() { 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) { const data = loginRes.data.data; // 保存微信登录信息(用于后续手机号授权) this.globalData.wxLoginInfo = { openid: data.openid, unionid: data.unionid, sessionKey: data.sessionKey, isNewUser: data.isNewUser, hasPhone: data.hasPhone, }; // 如果已有token(老用户),直接使用 if (data.userInfo && data.hasPhone) { // 老用户已绑定手机号,生成token并登录 this.globalData.userInfo = data.userInfo; } resolve(data); } else { reject(loginRes.data); } }, fail: reject, }); }, fail: reject, }); }); }, // 手机号授权登录(第二步:解密手机号完成注册/登录) phoneLogin(encryptedData, iv, userProfile) { return new Promise((resolve, reject) => { const wxInfo = this.globalData.wxLoginInfo; if (!wxInfo) { reject({ message: "请先进行微信登录" }); return; } wx.request({ url: `${this.globalData.baseUrl}/api/user/phone-login`, method: "POST", data: { openid: wxInfo.openid, unionid: wxInfo.unionid, sessionKey: wxInfo.sessionKey, encryptedData, iv, nickname: userProfile?.nickName || "", avatar: userProfile?.avatarUrl || "", gender: userProfile?.gender || 0, }, 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, }); }); }, // 旧的登录方法(兼容) login() { return this.wxLogin(); }, // 获取用户信息 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]; } else { // 没有天梯用户时清空 this.globalData.ladderUser = null; } 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, }); }); }, });