完善微信支付二维码生成机制
This commit is contained in:
@@ -5,7 +5,7 @@ import alipay from '../_assets/alipay.svg'
|
||||
import wechat from '../_assets/wechat.svg'
|
||||
import balance from '../_assets/balance.svg'
|
||||
import Image from 'next/image'
|
||||
import {useContext, useRef, useState} from 'react'
|
||||
import {useContext, useEffect, useRef, useState} from 'react'
|
||||
import {StoreContext, useProfileStore} from '@/components/providers/StoreProvider'
|
||||
import {Alert, AlertDescription} from '@/components/ui/alert'
|
||||
import {
|
||||
@@ -38,6 +38,14 @@ export default function Pay(props: PayProps) {
|
||||
const [open, setOpen] = useState(false)
|
||||
const [payInfo, setPayInfo] = useState<CreateResourceResp | undefined>()
|
||||
const canvas = useRef<HTMLCanvasElement>(null)
|
||||
useEffect(() => {
|
||||
if (canvas.current && payInfo) {
|
||||
qrcode.toCanvas(canvas.current, payInfo.pay_url, {
|
||||
width: 200,
|
||||
margin: 0,
|
||||
})
|
||||
}
|
||||
}, [payInfo])
|
||||
|
||||
const onOpen = async () => {
|
||||
setOpen(true)
|
||||
@@ -48,12 +56,12 @@ export default function Pay(props: PayProps) {
|
||||
|
||||
let resp: ApiResponse<CreateResourceResp>
|
||||
switch (props.method) {
|
||||
case 'alipay':
|
||||
resp = await prepareResourceByAlipay(props.resource)
|
||||
break
|
||||
case 'wechat':
|
||||
resp = await prepareResourceByWechat(props.resource)
|
||||
break
|
||||
case 'alipay':
|
||||
resp = await prepareResourceByAlipay(props.resource)
|
||||
break
|
||||
case 'wechat':
|
||||
resp = await prepareResourceByWechat(props.resource)
|
||||
break
|
||||
}
|
||||
if (!resp.success) {
|
||||
toast.error(`创建订单失败: ${resp.message}`)
|
||||
@@ -62,7 +70,6 @@ export default function Pay(props: PayProps) {
|
||||
}
|
||||
|
||||
setPayInfo(resp.data)
|
||||
await qrcode.toCanvas(canvas.current, resp.data.pay_url)
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
@@ -70,19 +77,19 @@ export default function Pay(props: PayProps) {
|
||||
let resp: ApiResponse
|
||||
try {
|
||||
switch (props.method) {
|
||||
case 'alipay':
|
||||
resp = await createResourceByAlipay({
|
||||
trade_no: payInfo!.trade_no,
|
||||
})
|
||||
break
|
||||
case 'wechat':
|
||||
resp = await createResourceByWechat({
|
||||
trade_no: payInfo!.trade_no,
|
||||
})
|
||||
break
|
||||
case 'balance':
|
||||
resp = await createResourceByBalance(props.resource)
|
||||
break
|
||||
case 'alipay':
|
||||
resp = await createResourceByAlipay({
|
||||
trade_no: payInfo!.trade_no,
|
||||
})
|
||||
break
|
||||
case 'wechat':
|
||||
resp = await createResourceByWechat({
|
||||
trade_no: payInfo!.trade_no,
|
||||
})
|
||||
break
|
||||
case 'balance':
|
||||
resp = await createResourceByBalance(props.resource)
|
||||
break
|
||||
}
|
||||
|
||||
if (!resp.success) {
|
||||
@@ -175,14 +182,10 @@ export default function Pay(props: PayProps) {
|
||||
) : (
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="bg-gray-100 w-52 h-52 flex items-center justify-center">
|
||||
<div className="bg-gray-100 size-50 flex items-center justify-center">
|
||||
{payInfo ? (
|
||||
props.method === 'alipay'
|
||||
? <iframe
|
||||
src={payInfo.pay_url}
|
||||
className="w-full h-full"
|
||||
title="支付二维码"
|
||||
/>
|
||||
? <iframe src={payInfo.pay_url} className="w-full h-full" />
|
||||
: <canvas ref={canvas} className="w-full h-full"/>
|
||||
) : (
|
||||
<Loader size={40} className={`animate-spin text-weak`}/>
|
||||
|
||||
@@ -17,7 +17,7 @@ import {zodResolver} from '@hookform/resolvers/zod'
|
||||
import {toast} from 'sonner'
|
||||
import wechat from '@/components/composites/purchase/_assets/wechat.svg'
|
||||
import alipay from '@/components/composites/purchase/_assets/alipay.svg'
|
||||
import {useRef, useState} from 'react'
|
||||
import {useEffect, useRef, useState} from 'react'
|
||||
import {Loader} from 'lucide-react'
|
||||
import {RechargeByAlipay, RechargeByAlipayConfirm, RechargeByWechat, RechargeByWechatConfirm} from '@/actions/user'
|
||||
import * as qrcode from 'qrcode'
|
||||
@@ -52,50 +52,60 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
const method = form.watch('method')
|
||||
const amount = form.watch('amount')
|
||||
|
||||
const canvas = useRef<HTMLCanvasElement>(null)
|
||||
const [step, setStep] = useState(0)
|
||||
const [payInfo, setPayInfo] = useState<{
|
||||
trade_no: string
|
||||
pay_url: string
|
||||
}>()
|
||||
|
||||
const canvas = useRef<HTMLCanvasElement>(null)
|
||||
useEffect(() => {
|
||||
if (canvas.current && payInfo) {
|
||||
qrcode.toCanvas(canvas.current, payInfo.pay_url, {
|
||||
width: 200,
|
||||
margin: 0,
|
||||
})
|
||||
}
|
||||
}, [payInfo])
|
||||
|
||||
const refreshProfile = useProfileStore(store => store.refreshProfile)
|
||||
|
||||
const createRecharge = async (data: Schema) => {
|
||||
try {
|
||||
switch (data.method) {
|
||||
case 'alipay':
|
||||
const aliRes = await RechargeByAlipay({
|
||||
amount: data.amount,
|
||||
case 'alipay':
|
||||
const aliRes = await RechargeByAlipay({
|
||||
amount: data.amount,
|
||||
})
|
||||
if (aliRes.success) {
|
||||
setStep(1)
|
||||
setPayInfo(aliRes.data)
|
||||
}
|
||||
else {
|
||||
toast.error(`创建订单失败`, {
|
||||
description: aliRes.message,
|
||||
})
|
||||
if (aliRes.success) {
|
||||
setStep(1)
|
||||
setPayInfo(aliRes.data)
|
||||
}
|
||||
else {
|
||||
toast.error(`充值失败`, {
|
||||
description: aliRes.message,
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'wechat':
|
||||
const weRes = await RechargeByWechat({
|
||||
amount: data.amount,
|
||||
}
|
||||
break
|
||||
case 'wechat':
|
||||
const weRes = await RechargeByWechat({
|
||||
amount: data.amount,
|
||||
})
|
||||
if (weRes.success) {
|
||||
setStep(1)
|
||||
setPayInfo(weRes.data)
|
||||
}
|
||||
else {
|
||||
toast.error(`创建订单失败`, {
|
||||
description: weRes.message,
|
||||
})
|
||||
if (weRes.success) {
|
||||
setStep(1)
|
||||
setPayInfo(weRes.data)
|
||||
await qrcode.toCanvas(canvas.current, weRes.data.pay_url)
|
||||
}
|
||||
else {
|
||||
toast.error(`充值失败`, {
|
||||
description: weRes.message,
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
toast.error(`充值失败`, {
|
||||
console.error(e)
|
||||
toast.error(`创建订单失败`, {
|
||||
description: (e as Error).message,
|
||||
})
|
||||
}
|
||||
@@ -110,22 +120,22 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
}
|
||||
try {
|
||||
switch (method) {
|
||||
case 'alipay':
|
||||
const aliRes = await RechargeByAlipayConfirm({
|
||||
trade_no: payInfo.trade_no,
|
||||
})
|
||||
if (!aliRes.success) {
|
||||
throw new Error(aliRes.message)
|
||||
}
|
||||
break
|
||||
case 'wechat':
|
||||
const weRes = await RechargeByWechatConfirm({
|
||||
trade_no: payInfo.trade_no,
|
||||
})
|
||||
if (!weRes.success) {
|
||||
throw new Error(weRes.message)
|
||||
}
|
||||
break
|
||||
case 'alipay':
|
||||
const aliRes = await RechargeByAlipayConfirm({
|
||||
trade_no: payInfo.trade_no,
|
||||
})
|
||||
if (!aliRes.success) {
|
||||
throw new Error(aliRes.message)
|
||||
}
|
||||
break
|
||||
case 'wechat':
|
||||
const weRes = await RechargeByWechatConfirm({
|
||||
trade_no: payInfo.trade_no,
|
||||
})
|
||||
if (!weRes.success) {
|
||||
throw new Error(weRes.message)
|
||||
}
|
||||
break
|
||||
}
|
||||
toast.success(`充值成功`)
|
||||
closeDialog()
|
||||
@@ -144,7 +154,6 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
setStep(0)
|
||||
}
|
||||
|
||||
const [step, setStep] = useState(0)
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
@@ -242,14 +251,10 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
{step == 1 && <>
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="bg-gray-100 w-52 h-52 flex items-center justify-center">
|
||||
<div className="bg-gray-100 size-50 flex items-center justify-center">
|
||||
{payInfo ?
|
||||
method === 'alipay'
|
||||
? <iframe
|
||||
src={payInfo.pay_url}
|
||||
className="w-full h-full"
|
||||
title="支付二维码"
|
||||
/>
|
||||
? <iframe src={payInfo.pay_url} className="w-full h-full"/>
|
||||
: <canvas ref={canvas} className="w-full h-full"/>
|
||||
: (
|
||||
<Loader size={40} className={`animate-spin text-weak`}/>
|
||||
|
||||
Reference in New Issue
Block a user