diff --git a/src/app/admin/bills/page.tsx b/src/app/admin/bills/page.tsx index fd49bfe..da87056 100644 --- a/src/app/admin/bills/page.tsx +++ b/src/app/admin/bills/page.tsx @@ -16,7 +16,7 @@ import zod from 'zod' import {zodResolver} from '@hookform/resolvers/zod' import {Label} from '@/components/ui/label' import Page from '@/components/page' -import {PaymentStatusCell} from '@/components/composites/payment' +import {PaymentStatusCell} from './payment' const filterSchema = zod.object({ type: zod.enum(['all', '3', '1', '2']).default('all'), diff --git a/src/components/composites/payment/payment-dialog.tsx b/src/app/admin/bills/payment-dialog.tsx similarity index 100% rename from src/components/composites/payment/payment-dialog.tsx rename to src/app/admin/bills/payment-dialog.tsx diff --git a/src/components/composites/payment/payment.tsx b/src/app/admin/bills/payment.tsx similarity index 100% rename from src/components/composites/payment/payment.tsx rename to src/app/admin/bills/payment.tsx diff --git a/src/components/composites/payment/desktop-payment.tsx b/src/components/composites/payment/desktop-payment.tsx new file mode 100644 index 0000000..010e817 --- /dev/null +++ b/src/components/composites/payment/desktop-payment.tsx @@ -0,0 +1,114 @@ +'use client' +import {DialogContent, DialogHeader, DialogTitle} from '@/components/ui/dialog' +import {Button} from '@/components/ui/button' +import {completeResource} from '@/actions/resource' +import {toast} from 'sonner' +import {CheckCircle, Loader} from 'lucide-react' +import {useState, useEffect, useRef} from 'react' +import * as qrcode from 'qrcode' +import Image from 'next/image' +import wechat from '@/components/composites/purchase/_assets/wechat.svg' +import alipay from '@/components/composites/purchase/_assets/alipay.svg' +import {PaymentMethod} from './types' + +interface Trade { + inner_no: string + method: number + pay_url: string + amount?: number + status?: number +} +export function DesktopPayment({trade, onClose}: {trade: Trade, onClose: () => void}) { + const [paymentVerified, setPaymentVerified] = useState(false) + const [loading, setLoading] = useState(false) + const canvasRef = useRef(null) + + const paymentInfo = { + icon: trade.method === PaymentMethod.Alipay ? alipay : wechat, + name: trade.method === PaymentMethod.Alipay ? '支付宝' : '微信支付', + } + + useEffect(() => { + if (!canvasRef.current || trade.method === 1) return + qrcode.toCanvas(canvasRef.current, trade.pay_url, {width: 200}) + .catch((err) => { + console.error('生成二维码失败:', err) + toast.error('生成支付二维码失败') + }) + }, [trade.method, trade.pay_url]) + + const handleComplete = async () => { + setLoading(true) + try { + const resp = await completeResource({trade_no: trade.inner_no}) + if (!resp.success) throw new Error(resp.message) + toast.success('支付成功') + setPaymentVerified(true) + setTimeout(onClose, 2000) + } + catch (e) { + toast.error('支付验证失败', {description: (e as Error).message}) + } + finally { + setLoading(false) + } + } + + return ( + + + + {paymentInfo.name} + {paymentInfo.name} + + + + {paymentVerified ? ( +
+ +

支付验证成功

+
+ ) : ( +
+
+ {trade.method === 1 ? ( +