Files
fitness-coach/miniprogram/utils/auth.js
wm 70ff806042 feat: 小程序连接服务器IP + 同步未提交开发
- miniprogram/config.js: BASE_URL 指向 http://192.227.237.8:3001
- 动作标题中文化(nameZh),搜索匹配 name/nameZh/nameEn
- 新增计划/收藏/我的 等页面与组件
- 后端 Docker 化(Dockerfile/.dockerignore)与翻译脚本
- .gitignore 补充 .DS_Store
2026-07-22 14:05:30 +08:00

116 lines
3.3 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.

// 登录与用户态管理:封装 wx.login + 后端 /api/auth/login。
// 后端在首次登录时自动创建用户;开发模式(未配置 WX_APPID接受任意 code
// 并返回稳定的虚拟 openid。
const { request, setUnauthorizedHandler } = require('./request');
const TOKEN_KEY = 'access_token';
const OPENID_KEY = 'openid';
const PROFILE_KEY = 'user_profile';
// 模块加载时注册 401 自动重新登录:成功后返回新的 token失败返回 null。
setUnauthorizedHandler(async () => {
try {
await login();
return wx.getStorageSync(TOKEN_KEY);
} catch (e) {
return null;
}
});
function login() {
return new Promise((resolve, reject) => {
wx.login({
success(res) {
const code = res.code || 'tourist';
request({ url: '/api/auth/login', method: 'POST', data: { code } })
.then((r) => {
const token = r.token;
const user = r.user || {};
wx.setStorageSync(TOKEN_KEY, token);
if (user.openid) wx.setStorageSync(OPENID_KEY, user.openid);
const profile = { nickname: user.nickname || '', avatar: user.avatar || '' };
wx.setStorageSync(PROFILE_KEY, profile);
resolve(profile);
})
.catch((err) => {
wx.showToast({ title: '登录失败,请重试', icon: 'none' });
reject(err);
});
},
fail() {
// 拿不到 code 时降级为游客 code
request({ url: '/api/auth/login', method: 'POST', data: { code: 'tourist' } })
.then((r) => {
const token = r.token;
const user = r.user || {};
wx.setStorageSync(TOKEN_KEY, token);
if (user.openid) wx.setStorageSync(OPENID_KEY, user.openid);
const profile = { nickname: user.nickname || '', avatar: user.avatar || '' };
wx.setStorageSync(PROFILE_KEY, profile);
resolve(profile);
})
.catch((err) => {
wx.showToast({ title: '登录失败,请重试', icon: 'none' });
reject(err);
});
}
});
});
}
// 确保已登录:有 token 直接返回,否则执行登录。
async function ensureLogin() {
const token = getToken();
if (token) return token;
await login();
return getToken();
}
function getToken() {
return wx.getStorageSync(TOKEN_KEY) || '';
}
function getProfile() {
return wx.getStorageSync(PROFILE_KEY) || { nickname: '', avatar: '' };
}
function isLogin() {
return !!getToken();
}
function logout() {
wx.removeStorageSync(TOKEN_KEY);
wx.removeStorageSync(OPENID_KEY);
wx.removeStorageSync(PROFILE_KEY);
}
function setProfile(p) {
const profile = Object.assign({}, getProfile(), p || {});
wx.setStorageSync(PROFILE_KEY, profile);
return profile;
}
// 更新昵称 / 头像,写回后端并刷新本地状态。
function updateProfile(dto) {
return request({ url: '/api/users/me', method: 'PATCH', data: dto })
.then((user) => {
const profile = {
nickname: (user && user.nickname) || getProfile().nickname,
avatar: (user && user.avatar) || getProfile().avatar
};
wx.setStorageSync(PROFILE_KEY, profile);
return profile;
});
}
module.exports = {
login,
ensureLogin,
getToken,
getProfile,
isLogin,
logout,
setProfile,
updateProfile
};