yingsa/miniprogram/app.js

291 lines
7.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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];
}
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,
});
});
},
});