import { makeObservable } from 'mobx' import { AppState, type AppStateStatus } from 'react-native' import { subscription } from '@/lib/auth' import { type ApiError } from '@/lib/types' class UserBalanceStore { balance: number = 0 loading: boolean = false error: ApiError | null = null private lastLoadTime: number = 0 private loadingPromise: Promise | null = null private pollingInterval: ReturnType | null = null private pollingEnabled: boolean = false private POLLING_INTERVAL = 60e3 // 60秒轮询一次 private appStateSubscription: { remove: () => void } | null = null constructor() { makeObservable(this) this.setupAppStateListener() } private setupAppStateListener() { this.appStateSubscription = AppState.addEventListener('change', (nextAppState: AppStateStatus) => { if (nextAppState === 'active' && this.pollingEnabled) { console.log('应用回到前台,重启余额轮询') this.restartPolling() } else if (nextAppState === 'background' || nextAppState === 'inactive') { console.log('应用进入后台,暂停余额轮询') this.stopPolling() } }) } async load(force = false) { const now = Date.now() const timeSinceLastLoad = now - this.lastLoadTime // 如果不是强制刷新,且距离上次调用少于5秒,则跳过 if (!force && timeSinceLastLoad < 5e3) { console.log('跳过余额加载,距离上次调用时间过短:', timeSinceLastLoad + 'ms') return } // 如果已经在加载中且不是强制刷新,直接返回 if (this.loading && !force) { console.log('余额加载中,跳过重复请求') return this.loadingPromise } console.log('执行余额加载') this.lastLoadTime = now this.loadingPromise = this.performLoad() return this.loadingPromise } private async performLoad() { try { const { data, error } = await subscription.list() if (error) { return } const meteredSubscriptions = data?.filter((sub) => sub.type === 'metered') || [] const creditBalance = meteredSubscriptions[0]?.creditBalance?.remainingTokenBalance || 0 this.setBalance(creditBalance) } catch (e) { console.error('加载余额失败:', e) } finally { this.loadingPromise = null } } // 重置Store状态 reset() { this.stopPolling() // 停止轮询 this.setBalance(0) this.lastLoadTime = 0 this.loadingPromise = null // 清理应用状态监听器 if (this.appStateSubscription) { this.appStateSubscription.remove() this.appStateSubscription = null } } // 手动设置余额(用于乐观更新) setBalance(newBalance: number) { this.balance = newBalance } // 扣减余额(用于乐观更新) deductBalance(amount: number) { this.balance = Math.max(0, this.balance - amount) } // 开始余额轮询 startPolling() { // 先清理可能存在的旧轮询状态 this.stopPolling() console.log('开始余额轮询,间隔:', this.POLLING_INTERVAL / 1000, '秒') this.pollingEnabled = true // 立即执行一次 this.load(false) // 设置定时器 this.pollingInterval = setInterval(() => { if (this.pollingEnabled) { this.load(false) // 使用防抖机制 } }, this.POLLING_INTERVAL) } // 停止余额轮询 stopPolling() { console.log('停止余额轮询') this.pollingEnabled = false if (this.pollingInterval) { clearInterval(this.pollingInterval) this.pollingInterval = null } } // 重启轮询 restartPolling() { this.stopPolling() setTimeout(() => this.startPolling(), 1000) // 延迟1秒重启 } // 检查轮询状态 get isPolling() { return this.pollingEnabled && this.pollingInterval !== null } } // 创建单例实例 export const userBalanceStore = new UserBalanceStore()