diff --git a/app/components/auth/PaymentModal.tsx b/app/components/auth/PaymentModal.tsx index 3946878..7a40465 100644 --- a/app/components/auth/PaymentModal.tsx +++ b/app/components/auth/PaymentModal.tsx @@ -24,28 +24,42 @@ interface PaymentResponse { return_url: string; } +interface PaymentStatusResponse { + status: string; + error?: string; +} + export function PaymentModal({ isOpen, onClose, paymentData, onPaymentSuccess }: PaymentModalProps) { const [timeLeft, setTimeLeft] = useState(parseInt(paymentData.expires_in)); const checkPaymentStatus = useCallback(async () => { try { const response = await fetch(`/api/check-payment-status?orderNo=${paymentData.no}`); - const data = await response.json(); + if (!response.ok) { + if (response.status === 404) { + console.error('Order not found'); + return; + } + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json() as PaymentStatusResponse; if (data.status === 'completed') { - clearInterval(timer); onPaymentSuccess(); onClose(); toast.success('支付成功!'); } } catch (error) { console.error('Error checking payment status:', error); + toast.error('检查支付状态时出错,请稍后再试'); } }, [paymentData.no, onPaymentSuccess, onClose]); useEffect(() => { if (!isOpen) return; - const timer = setInterval(() => { + let timer: NodeJS.Timeout; + + const checkAndUpdateStatus = () => { setTimeLeft((prevTime) => { if (prevTime <= 1) { clearInterval(timer); @@ -57,7 +71,9 @@ export function PaymentModal({ isOpen, onClose, paymentData, onPaymentSuccess }: }); checkPaymentStatus(); - }, 3000); // 每3秒检查一次支付状态 + }; + + timer = setInterval(checkAndUpdateStatus, 3000); // 每3秒检查一次支付状态 return () => clearInterval(timer); }, [isOpen, onClose, checkPaymentStatus]); diff --git a/app/components/auth/SubscriptionDialog.tsx b/app/components/auth/SubscriptionDialog.tsx index 00c9f54..6e384aa 100644 --- a/app/components/auth/SubscriptionDialog.tsx +++ b/app/components/auth/SubscriptionDialog.tsx @@ -15,10 +15,19 @@ interface SubscriptionDialogProps { } interface UserSubscription { - plan: SubscriptionPlan; - tokensLeft: number; - nextReloadDate: string; -} + tokenBalance: number; + subscription: { + plan: { + _id: string; + name: string; + tokens: number; + price: number; + description: string; + save_percentage?: number; + }; + expirationDate: string; + } | null; + } interface PaymentResponse { status: string; @@ -164,14 +173,14 @@ export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps)

- {isAuthenticated && userSubscription && ( + {isAuthenticated && userSubscription && userSubscription.subscription && (
- {toString(userSubscription.tokensLeft)} + {toString(userSubscription.tokenBalance)} 代币剩余。 - {userSubscription.plan.tokens.toLocaleString()}代币将在{new Date(userSubscription.nextReloadDate).toLocaleDateString()}后添加。 + {userSubscription.subscription.plan.tokens.toLocaleString()}代币将在{new Date(userSubscription.subscription.expirationDate).toLocaleDateString()}后添加。
@@ -220,7 +229,7 @@ export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps)
{subscriptionPlans.map((plan) => ( -
+

{plan.name}

{(plan.tokens / 1000000).toFixed(0)}M 代币 @@ -235,12 +244,12 @@ export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps)
))} diff --git a/app/routes/api.check-payment-status.ts b/app/routes/api.check-payment-status.ts index f4ff861..b123063 100644 --- a/app/routes/api.check-payment-status.ts +++ b/app/routes/api.check-payment-status.ts @@ -1,26 +1,35 @@ import { json } from '@remix-run/cloudflare'; import { db } from '~/utils/db.server'; +import { requireAuth } from '~/middleware/auth.server'; export async function loader({ request }: { request: Request }) { + let userId; + try { + userId = await requireAuth(request); + } catch (error) { + return error as Response; + } + const url = new URL(request.url); const orderNo = url.searchParams.get('orderNo'); if (!orderNo) { - return json({ error: 'Order number is required' }, { status: 400 }); + return json({ error: '订单号不能为空' }, { status: 400 }); } try { const transaction = await db('user_transactions') .where('transaction_id', orderNo) + .where('user_id', userId) .first(); if (!transaction) { - return json({ error: 'Transaction not found' }, { status: 404 }); + return json({ error: '订单不存在' }, { status: 404 }); } return json({ status: transaction.status }); } catch (error) { console.error('Error checking payment status:', error); - return json({ error: 'Failed to check payment status' }, { status: 500 }); + return json({ error: '检查支付状态失败' }, { status: 500 }); } } diff --git a/app/routes/api.purchase-subscription.ts b/app/routes/api.purchase-subscription.ts index 24b7a77..ddf44c6 100644 --- a/app/routes/api.purchase-subscription.ts +++ b/app/routes/api.purchase-subscription.ts @@ -35,7 +35,7 @@ export async function action({ request }: { request: Request }) { orderNo, `${plan.name} 订阅 (${billingCycle === 'yearly' ? '年付' : '月付'})`, 'alipay', // 或其他支付方式 - price * 100, // 转换为分 + price, // 不用转换为分 userId.toString() ); diff --git a/app/routes/api.user-subscription.ts b/app/routes/api.user-subscription.ts index 84f67dd..3402152 100644 --- a/app/routes/api.user-subscription.ts +++ b/app/routes/api.user-subscription.ts @@ -30,9 +30,16 @@ export async function loader({ request }: { request: Request }) { return json({ tokenBalance: user.token_balance, - subscription: subscription + subscription: subscription && subscriptionPlan ? { - planName: subscriptionPlan.name, + plan: { + _id: subscriptionPlan._id, + name: subscriptionPlan.name, + tokens: subscriptionPlan.tokens, + price: subscriptionPlan.price, + description: subscriptionPlan.description, + save_percentage: subscriptionPlan.save_percentage, + }, expirationDate: subscription.expiration_date, } : null,