189 lines
4.5 KiB
TypeScript
189 lines
4.5 KiB
TypeScript
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()
|