feat: 添加用户状态管理和会话处理功能

This commit is contained in:
康猛 2026-01-15 17:14:52 +08:00
parent 41a863f06c
commit 123bc55b26
1 changed files with 126 additions and 0 deletions

126
stores/userStore.ts Normal file
View File

@ -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
}