import { login, saveUserPhone, saveUserInfo } from '@api/user'; import storage from '@utils/storage/setup'; import retry from '@utils/retry'; export const AUTH_SESSION_KEY = 'AUTH_SESSION'; /** * Session 信息 */ export type SessionModel = { // 微信登录 code code: string; // 登录态 token: string; // 用户信息 userInfo?: Record, // 创建时间 createTime?: number; // 更新时间 updateTime?: number; }; export class Session { /** * 登录 * @description 用于小程序启动时发起静默登录 */ async login(): Promise { // 调用wx.checkSession判断session_key是否过期; const hasSession = await this.checkSession(); // 本地已有可用登录态且session_key未过期,resolve if (this.getAuthTokenSync() && hasSession) { return Promise.resolve(); } // 否则,发起静默登录 await this.silentLogin(); } /** * 发起静默登录 * @description 调用wx.login获取code,发起登录接口请求 */ async silentLogin(): Promise { try { // 获取临时登录凭证code const { code } = await wx.login(); // 将code发送给服务端 const res = await login(code); // 保存登录信息 const data: SessionModel = { ...res?.data, code, createTime: Date.now(), }; storage.setSync(AUTH_SESSION_KEY, data); } catch (error) { console.error('静默登录失败', error); throw error; } } /** * 验证 sessionKey 是否过期,过期则刷新 */ async refreshLogin(): Promise { try { // 清除 Session storage.removeSync(AUTH_SESSION_KEY); // 发起静默登录 await this.silentLogin(); } catch (error) { throw error; } } /** * 验证wx.checkSession()是否过期 */ async checkSession(): Promise { try { await wx.checkSession(); return true; } catch (error) { return false; } } /** * 验证 sessionKey 是否过期,过期则刷新登录态 */ async ensureSessionKey(): Promise { const hasSession = await this.checkSession(); if (!hasSession) { console.info('sessionKey 已过期,刷新登录态'); return this.refreshLogin(); } return Promise.resolve(); } /** * 同步获取 token 登录态 */ getAuthTokenSync() { return storage.getSync(AUTH_SESSION_KEY)?.token; } /** * 同步获取 wx.login code */ getWxCodeSync() { return storage.getSync(AUTH_SESSION_KEY)?.code; } /** * 绑定微信授权手机号 * @description 微信授权手机号弹窗点击「允许」触发 */ async bindPhone(data: Omit) { // 异常时,启动重试机制 return retry(async () => { try { const code = this.getWxCodeSync(); const res = await saveUserPhone({ ...data, code }); return this.setUserInfo(res?.data); } catch (error) { throw error; } }, 3, 100, true); } /** * 绑定微信授权用户信息 * @description 微信授权用户信息点击「允许」触发 */ async updateUser(data: Omit) { // 异常时,启动重试机制 return retry(async () => { try { const code = this.getWxCodeSync(); const res = await saveUserInfo({ ...data, code }); return this.setUserInfo(res?.data); } catch (error) { throw error; } }, 3, 100, true); } /** * 更新用户信息 */ setUserInfo(obj: Record) { const data = storage.getSync(AUTH_SESSION_KEY); data.userInfo = Object.assign(data?.userInfo, obj ?? {}); data.updateTime = Date.now(); storage.setSync(AUTH_SESSION_KEY, data); return data; } } export default new Session();