feat: 添加用户状态管理和会话处理功能
This commit is contained in:
parent
41a863f06c
commit
123bc55b26
|
|
@ -0,0 +1,126 @@
|
|||
import { makeAutoObservable } from 'mobx'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
import { signOut as authSignOut, useSession } from '@/lib/auth'
|
||||
|
||||
// console.log('useSession---------------', useSession)
|
||||
|
||||
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?: {
|
||||
id: string
|
||||
userId: string
|
||||
expiresAt: Date
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
activeOrganizationId?: string | null
|
||||
activeTeamId?: string | null
|
||||
impersonatedBy?: string | null
|
||||
ipAddress?: string | null
|
||||
token?: string | null
|
||||
userAgent?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
class UserStore {
|
||||
user: User | null = null
|
||||
session: Session | null = null
|
||||
isAuthenticated: boolean = false
|
||||
isLoading: boolean = false
|
||||
error: string | null = null
|
||||
|
||||
constructor() {
|
||||
// autoBind ensures methods keep `this`, and all fields become observable/actions
|
||||
makeAutoObservable(this)
|
||||
}
|
||||
|
||||
// 设置用户信息
|
||||
setUser(user: User | null) {
|
||||
this.user = user
|
||||
this.isAuthenticated = !!user
|
||||
}
|
||||
|
||||
// 设置会话信息
|
||||
setSession(session: Session | null) {
|
||||
this.session = session
|
||||
this.user = session?.user || null
|
||||
this.isAuthenticated = !!session?.user
|
||||
}
|
||||
|
||||
// 设置加载状态
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// 从session更新用户状态
|
||||
updateFromSession(sessionData: Session | null) {
|
||||
this.setSession(sessionData)
|
||||
}
|
||||
|
||||
// 重置store状态
|
||||
reset() {
|
||||
this.user = null
|
||||
this.session = null
|
||||
this.isAuthenticated = false
|
||||
this.isLoading = false
|
||||
this.error = null
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单例实例
|
||||
export const userStore = new UserStore()
|
||||
|
||||
// 创建一个hook来使用session数据更新store
|
||||
export const useUserSession = () => {
|
||||
const session = useSession()
|
||||
|
||||
// 使用useEffect在副作用中更新store状态,避免在render过程中修改
|
||||
useEffect(() => {
|
||||
userStore.setLoading(session.isPending)
|
||||
userStore.updateFromSession(session.data)
|
||||
}, [session.isPending, session.data])
|
||||
|
||||
return session
|
||||
}
|
||||
Loading…
Reference in New Issue