gcx/frontend/miniapp/src/store/auth.ts

97 lines
2.7 KiB
TypeScript

import Taro from '@tarojs/taro';
import { config } from '../config';
import { post, get } from '../utils/request';
export interface UserProfile {
id: string;
phone?: string;
email?: string;
nickname?: string;
kycLevel: number;
avatarUrl?: string;
}
interface AuthResponse {
user: UserProfile;
tokens: { accessToken: string; refreshToken: string; expiresIn: number };
}
/**
* Auth 状态管理(简单模块模式,不依赖额外状态库)
*/
let _user: UserProfile | null = null;
let _listeners: Array<() => void> = [];
function notify() {
_listeners.forEach((fn) => fn());
}
export const authStore = {
/** 获取当前用户 */
getUser(): UserProfile | null {
if (!_user) {
try {
const saved = Taro.getStorageSync(config.USER_KEY);
if (saved) _user = JSON.parse(saved);
} catch {}
}
return _user;
},
/** 是否已登录 */
isLoggedIn(): boolean {
return !!Taro.getStorageSync(config.TOKEN_KEY);
},
/** 手机号+验证码登录 */
async loginByPhone(phone: string, smsCode: string): Promise<void> {
const resp = await post<AuthResponse>('/api/v1/auth/login-phone', { phone, smsCode }, false);
Taro.setStorageSync(config.TOKEN_KEY, resp.tokens.accessToken);
Taro.setStorageSync(config.USER_KEY, JSON.stringify(resp.user));
_user = resp.user;
notify();
},
/** 发送短信验证码 (支持类型) */
async sendSmsCode(phone: string, type: 'REGISTER' | 'LOGIN' | 'RESET_PASSWORD' | 'CHANGE_PHONE' = 'LOGIN'): Promise<void> {
await post('/api/v1/auth/sms/send', { phone, type }, false);
},
/** 微信一键登录 */
async loginByWechat(): Promise<void> {
const { code } = await Taro.login();
const resp = await post<AuthResponse>('/api/v1/auth/login-wechat', { code }, false);
Taro.setStorageSync(config.TOKEN_KEY, resp.tokens.accessToken);
Taro.setStorageSync(config.USER_KEY, JSON.stringify(resp.user));
_user = resp.user;
notify();
},
/** 获取用户资料 */
async fetchProfile(): Promise<UserProfile> {
const profile = await get<UserProfile>('/api/v1/users/me');
_user = profile;
Taro.setStorageSync(config.USER_KEY, JSON.stringify(profile));
notify();
return profile;
},
/** 登出 */
logout(): void {
post('/api/v1/auth/logout').catch(() => {});
Taro.removeStorageSync(config.TOKEN_KEY);
Taro.removeStorageSync(config.USER_KEY);
_user = null;
notify();
Taro.reLaunch({ url: '/pages/login/index' });
},
/** 订阅状态变化 */
subscribe(listener: () => void): () => void {
_listeners.push(listener);
return () => {
_listeners = _listeners.filter((fn) => fn !== listener);
};
},
};