112 lines
2.6 KiB
TypeScript
112 lines
2.6 KiB
TypeScript
interface UserInfo {
|
|
_id: string;
|
|
openid: string;
|
|
unionid: string | null;
|
|
nickName: string | null;
|
|
avatarUrl: string | null;
|
|
totalDownloads: number;
|
|
createdAt: string;
|
|
lastActiveAt: string;
|
|
}
|
|
|
|
const STORAGE_KEY = 'user_info';
|
|
const STORAGE_EXPIRE_KEY = 'user_info_expire';
|
|
const EXPIRE_DURATION = 7 * 24 * 60 * 60 * 1000; // 7 天
|
|
|
|
/** 内存中的用户数据(App 生命周期内有效) */
|
|
let currentUser: UserInfo | null = null;
|
|
|
|
/** 登录进行中的 Promise(防止并发重复调用) */
|
|
let loginPromise: Promise<UserInfo> | null = null;
|
|
|
|
/**
|
|
* 获取当前用户,优先内存 → Storage → 云函数登录
|
|
*/
|
|
export async function getUser(): Promise<UserInfo> {
|
|
// 1. 内存中有,直接返回
|
|
if (currentUser) return currentUser;
|
|
|
|
// 2. 尝试从 Storage 读取
|
|
const cached = loadFromStorage();
|
|
if (cached) {
|
|
currentUser = cached;
|
|
return cached;
|
|
}
|
|
|
|
// 3. 静默登录(防止并发)
|
|
if (!loginPromise) {
|
|
loginPromise = silentLogin().finally(() => {
|
|
loginPromise = null;
|
|
});
|
|
}
|
|
return loginPromise;
|
|
}
|
|
|
|
/**
|
|
* 静默登录:调用云函数
|
|
*/
|
|
async function silentLogin(): Promise<UserInfo> {
|
|
const res = await wx.cloud.callFunction({
|
|
name: 'userLogin',
|
|
});
|
|
const result = (res?.result as any) || {};
|
|
|
|
if (result.code !== 0) {
|
|
throw new Error('登录失败');
|
|
}
|
|
|
|
const user = result.data as UserInfo;
|
|
currentUser = user;
|
|
saveToStorage(user);
|
|
return user;
|
|
}
|
|
|
|
/**
|
|
* 从 Storage 读取用户数据(检查过期)
|
|
*/
|
|
function loadFromStorage(): UserInfo | null {
|
|
try {
|
|
const expire = wx.getStorageSync(STORAGE_EXPIRE_KEY);
|
|
if (!expire || Date.now() > expire) {
|
|
wx.removeStorageSync(STORAGE_KEY);
|
|
wx.removeStorageSync(STORAGE_EXPIRE_KEY);
|
|
return null;
|
|
}
|
|
const user = wx.getStorageSync(STORAGE_KEY);
|
|
return user || null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 写入 Storage
|
|
*/
|
|
function saveToStorage(user: UserInfo): void {
|
|
try {
|
|
wx.setStorageSync(STORAGE_KEY, user);
|
|
wx.setStorageSync(STORAGE_EXPIRE_KEY, Date.now() + EXPIRE_DURATION);
|
|
} catch {
|
|
// Storage 写入失败不影响主流程
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 清除登录状态
|
|
*/
|
|
export function clearUser(): void {
|
|
currentUser = null;
|
|
wx.removeStorageSync(STORAGE_KEY);
|
|
wx.removeStorageSync(STORAGE_EXPIRE_KEY);
|
|
}
|
|
|
|
/**
|
|
* 强制刷新用户数据(跳过缓存)
|
|
*/
|
|
export async function refreshUser(): Promise<UserInfo> {
|
|
clearUser();
|
|
return await silentLogin();
|
|
}
|
|
|
|
export type { UserInfo };
|