294 lines
7.9 KiB
JavaScript
294 lines
7.9 KiB
JavaScript
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,
|
||
});
|
||
});
|
||
},
|
||
});
|