import { root } from '@repo/core' import { DeviceController } from '@repo/sdk' import * as Application from 'expo-application' import { router } from 'expo-router' import { makeAutoObservable, runInAction } from 'mobx' import { Platform } from 'react-native' import { getSession, signOut as authSignOut } from '@/lib/auth' import { storage } from '@/utils' interface User { id: string email: string name?: string image?: string | null createdAt: Date updatedAt: Date emailVerified?: boolean username?: string | null banExpires?: Date | null banReason?: string | null banned?: boolean | null displayUsername?: string | null metadata?: any | null phoneNumber?: string | null phoneNumberVerified?: boolean | null role?: string | null stripeCustomerId?: string | null } interface Session { user?: User session?: { expiresAt: Date token: string createdAt: Date updatedAt: Date ipAddress?: string | null userAgent?: string | null userId: string impersonatedBy?: string | null activeOrganizationId?: string | null activeTeamId?: string | null id: string } } class UserStore { user: User | null = null session: Session | null = null isLogin: boolean = true isLoading: boolean = false error: string | null = null scannedQR: string | null = null // 扫描的二维码 constructor() { // autoBind ensures methods keep `this`, and all fields become observable/actions makeAutoObservable(this) this.loadLoginState() } async loadLoginState() { const isLogin = await storage.get('isLogin') runInAction(() => { this.isLogin = !!isLogin }) } // 设置用户信息 async setUser(user: User | null) { runInAction(() => { this.user = user this.isLogin = !!user }) await storage.set('isLogin', !!user) } async getUserData() { const sessionRes = await getSession() // console.log('getUserData sessionRes--------:', JSON.stringify(sessionRes)) const data = sessionRes.data if (!data) { this.reset() router.replace('/auth') return } const { session, user } = data // console.log('获取用户信息--------:', JSON.stringify(data)) runInAction(() => { this.session = { session, user } this.user = user || null this.isLogin = !!user }) if (user?.id) { this.bindDevice() } } // 设置加载状态 setLoading(loading: boolean) { this.isLoading = loading } // 设置错误信息 setError(error: string | null) { this.error = error } // 登出方法 signOut = async () => { this.setLoading(true) try { await authSignOut() this.reset() // 登出时重置余额store const { userBalanceStore } = await import('./userBalanceStore') userBalanceStore.reset() } catch (error) { this.setError(error instanceof Error ? error.message : '登出失败') console.error('登出失败:', error) } finally { this.setLoading(false) } } // 重置store状态 reset() { this.session = null this.isLoading = false this.error = null this.scannedQR = null this.setUser(null) } // ==================== 二维码相关方法 ==================== // 设置扫描的二维码 setScannedQR(value: string) { this.scannedQR = value } // 绑定设备信息 async bindDevice() { const deviceController = root.get(DeviceController) const isIos = Platform.OS === 'ios' const userDeviceId = isIos ? await Application.getIosIdForVendorAsync() : Application.getAndroidId() const appVersion = Application.nativeApplicationVersion! const data = { appVersion, userDeviceId: userDeviceId!, } // console.log('绑定设备数据--------:', data) deviceController.upsertUserDevice(data).then((r) => { console.log('绑定设备成功:', r) }) } // 绑定吧唧蓝牙设备 async bindBluetooth(params: { sn: string; version: string; userDeviceId?: string }) { const deviceController = root.get(DeviceController) const isIos = Platform.OS === 'ios' const userDeviceId = isIos ? await Application.getIosIdForVendorAsync() : Application.getAndroidId() const data = { sn: params.sn, userDeviceId: params.userDeviceId || userDeviceId!, version: params.version, } // console.log('bindBluetooth--------', data) deviceController.upsertBluetoothDevice(data).then((r) => { console.log('bindBluetooth--------', r) }) } } // 创建单例实例 export const userStore = new UserStore()