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