import { Dialog, DialogTitle, DialogDescription, DialogRoot } from '~/components/ui/Dialog'; import { useState, useEffect, useCallback } from 'react'; import { useAuth } from '~/hooks/useAuth'; import { toast } from 'react-toastify'; import { PaymentModal } from './PaymentModal'; import { LoginRegisterDialog } from './LoginRegisterDialog'; import type { SubscriptionPlan } from '~/types/subscription'; import pkg from 'lodash'; const {toString} = pkg; import { TokenReloadModal } from './TokenReloadModal'; // 新增导入 interface SubscriptionDialogProps { isOpen: boolean; onClose: () => void; } interface UserSubscription { plan: SubscriptionPlan; tokensLeft: number; nextReloadDate: string; } interface PaymentResponse { status: string; msg: string; no: string; pay_type: string; order_amount: string; pay_amount: string; qr_money: string; qr: string; qr_img: string; did: string; expires_in: string; return_url: string; } interface PurchaseResponse { success: boolean; paymentData?: PaymentResponse; error?: string; } export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps) { const [billingCycle, setBillingCycle] = useState<'monthly' | 'yearly'>('monthly'); const [subscriptionPlans, setSubscriptionPlans] = useState([]); const [userSubscription, setUserSubscription] = useState(null); const [isLoading, setIsLoading] = useState(true); const { user, token, isAuthenticated, login } = useAuth(); const [paymentData, setPaymentData] = useState(null); const [isLoginRegisterOpen, setIsLoginRegisterOpen] = useState(false); const [isTokenReloadModalOpen, setIsTokenReloadModalOpen] = useState(false); useEffect(() => { if (isOpen) { fetchSubscriptionPlans(); if (isAuthenticated && token) { fetchUserSubscription(); } } }, [isOpen, isAuthenticated, token]); const fetchSubscriptionPlans = async () => { setIsLoading(true); try { const response = await fetch('/api/subscription-plans'); if (!response.ok) { throw new Error('获取订阅计划失败'); } const data = await response.json() as SubscriptionPlan[]; setSubscriptionPlans(data); } catch (error) { console.error('获取订阅计划时出错:', error); toast.error('获取订阅计划失败,请稍后再试'); } finally { setIsLoading(false); } }; const fetchUserSubscription = async () => { if (!token) return; try { const headers = { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }; const userSubResponse = await fetch('/api/user-subscription', { headers }); if (!userSubResponse.ok) { throw new Error('获取用户订阅信息失败'); } const userSub = await userSubResponse.json() as UserSubscription; setUserSubscription(userSub); } catch (error) { console.error('获取用户订阅信息时出错:', error); toast.error('获取用户订阅信息失败,请稍后再试'); } }; const handlePurchase = async (planId: string) => { if (!isAuthenticated) { setIsLoginRegisterOpen(true); return; } if (!token) { toast.error('登录状态异常,请重新登录'); return; } try { const response = await fetch('/api/purchase-subscription', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ planId, billingCycle, }), }); const result = await response.json() as PurchaseResponse; if (response.ok && result.success && result.paymentData) { setPaymentData(result.paymentData); } else { toast.error(result.error || '获取支付信息失败,请稍后重试。'); } } catch (error) { console.error('Error initiating purchase:', error); toast.error('购买过程中出现错误,请稍后重试。'); } }; const handlePaymentSuccess = useCallback(() => { fetchUserSubscription(); // 重新获取订阅信息 toast.success('订阅成功!'); }, [fetchUserSubscription]); const handleLoginSuccess = useCallback(() => { setIsLoginRegisterOpen(false); fetchUserSubscription(); toast.success('登录成功!'); }, [fetchUserSubscription]); const handleTokenReloadClick = () => { setIsTokenReloadModalOpen(true); }; const handleTokenReloadSuccess = useCallback(() => { fetchUserSubscription(); // 重新获取用户订阅信息 toast.success('代币充值成功!'); }, [fetchUserSubscription]); if (isLoading) return null; return ( <> 订阅管理

注册免费账户以加速您在公共项目上的工作流程,或通过即时打开的生产环境提升整个团队的效率。

{isAuthenticated && userSubscription && (
{toString(userSubscription.tokensLeft)} 代币剩余。 {userSubscription.plan.tokens.toLocaleString()}代币将在{new Date(userSubscription.nextReloadDate).toLocaleDateString()}后添加。
)}
{subscriptionPlans.map((plan) => (

{plan.name}

{(plan.tokens / 1000000).toFixed(0)}M 代币 {plan.save_percentage && ( 节省 {plan.save_percentage}% )}

{plan.description}

¥{plan.price * (billingCycle === 'yearly' ? 10 : 1)}/{billingCycle === 'yearly' ? '年' : '月'}
))}
{paymentData && ( setPaymentData(null)} paymentData={paymentData} onPaymentSuccess={handlePaymentSuccess} /> )} setIsLoginRegisterOpen(false)} onLoginSuccess={handleLoginSuccess} /> setIsTokenReloadModalOpen(false)} onReloadSuccess={handleTokenReloadSuccess} /> ); }