更新了购买套餐里的充值和立即支付的传参,增加我的账单模块待支付链接跳转和弹窗
This commit is contained in:
@@ -17,15 +17,20 @@ 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 {useEffect, useRef, useState} from 'react'
|
||||
import {useEffect, useMemo, useRef, useState} from 'react'
|
||||
import {Loader} from 'lucide-react'
|
||||
import {RechargeByAlipay, RechargeByAlipayConfirm, RechargeByWechat, RechargeByWechatConfirm} from '@/actions/user'
|
||||
import {RechargeByPay, RechargeByAlipayConfirm, RechargeByWechat, RechargeByWechatConfirm} from '@/actions/user'
|
||||
import * as qrcode from 'qrcode'
|
||||
import {useProfileStore} from '@/components/providers/StoreProvider'
|
||||
import {merge} from '@/lib/utils'
|
||||
import {
|
||||
Platform,
|
||||
PAYMENT_METHODS,
|
||||
usePlatformType,
|
||||
} from '@/lib/models/trade'
|
||||
|
||||
const schema = zod.object({
|
||||
method: zod.enum(['alipay', 'wechat']),
|
||||
method: zod.enum(['alipay', 'wechat', 'sft', 'sftAlipay', 'sftWeChat']),
|
||||
amount: zod.number().min(1, '充值金额必须大于 0'),
|
||||
})
|
||||
|
||||
@@ -39,7 +44,7 @@ export type RechargeModelProps = {
|
||||
|
||||
export default function RechargeModal(props: RechargeModelProps) {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const platform = usePlatformType()
|
||||
const form = useForm<Schema>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
@@ -57,55 +62,66 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
pay_url: string
|
||||
}>()
|
||||
|
||||
// 获取当前平台可用的支付方法
|
||||
const availableMethods = useMemo(() => {
|
||||
console.log(PAYMENT_METHODS, 'PAYMENT_METHODS')
|
||||
|
||||
return Object.values(PAYMENT_METHODS)
|
||||
.filter(method => method.availablePlatforms.includes(platform))
|
||||
.map(method => ({
|
||||
value: method.formValue,
|
||||
name: method.name,
|
||||
icon: method.icon,
|
||||
}))
|
||||
}, [platform])
|
||||
const canvas = useRef<HTMLCanvasElement>(null)
|
||||
useEffect(() => {
|
||||
if (canvas.current && payInfo) {
|
||||
qrcode.toCanvas(canvas.current, payInfo.pay_url, {
|
||||
width: 200,
|
||||
margin: 0,
|
||||
})
|
||||
}
|
||||
}, [payInfo])
|
||||
console.log('Canvas ref:', canvas.current)
|
||||
if (!payInfo || !canvas.current || method.includes('alipay')) return
|
||||
qrcode.toCanvas(canvas.current, payInfo.pay_url, {
|
||||
width: 200,
|
||||
margin: 0,
|
||||
})
|
||||
}, [payInfo, method])
|
||||
|
||||
const refreshProfile = useProfileStore(store => store.refreshProfile)
|
||||
|
||||
const createRecharge = async (data: Schema) => {
|
||||
try {
|
||||
switch (data.method) {
|
||||
case 'alipay':
|
||||
const aliRes = await RechargeByAlipay({
|
||||
amount: data.amount.toString(),
|
||||
})
|
||||
if (aliRes.success) {
|
||||
setStep(1)
|
||||
setPayInfo(aliRes.data)
|
||||
}
|
||||
else {
|
||||
toast.error(`创建订单失败`, {
|
||||
description: aliRes.message,
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'wechat':
|
||||
const weRes = await RechargeByWechat({
|
||||
amount: data.amount.toString(),
|
||||
})
|
||||
if (weRes.success) {
|
||||
setStep(1)
|
||||
setPayInfo(weRes.data)
|
||||
}
|
||||
else {
|
||||
toast.error(`创建订单失败`, {
|
||||
description: weRes.message,
|
||||
})
|
||||
}
|
||||
break
|
||||
const paymentMethod = Object.entries(PAYMENT_METHODS).find(
|
||||
([_, config]) => config.formValue === data.method,
|
||||
)
|
||||
console.log(paymentMethod, 'paymentMethod')
|
||||
|
||||
if (!paymentMethod) {
|
||||
throw new Error('无效的支付方式')
|
||||
}
|
||||
const resp = {
|
||||
amount: data.amount.toString(),
|
||||
platform: platform,
|
||||
method: paymentMethod[1].actualMethod,
|
||||
}
|
||||
console.log(resp, 'resp')
|
||||
|
||||
// const result = await RechargeByPay({
|
||||
// amount: data.amount.toString(),
|
||||
// platform: platform,
|
||||
// method: parseInt(paymentMethod[0]) as PaymentMethod,
|
||||
// })
|
||||
const result = await RechargeByPay(resp)
|
||||
console.log(result, 'result')
|
||||
|
||||
if (result.success) {
|
||||
setStep(1)
|
||||
setPayInfo(result.data)
|
||||
}
|
||||
else {
|
||||
throw new Error(result.message)
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e)
|
||||
toast.error(`创建订单失败`, {
|
||||
description: (e as Error).message,
|
||||
catch (error) {
|
||||
toast.error('创建订单失败', {
|
||||
description: error instanceof Error ? error.message : '未知错误',
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -151,6 +167,7 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
setOpen(false)
|
||||
setPayInfo(undefined)
|
||||
setStep(0)
|
||||
form.reset()
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -159,7 +176,7 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
<Button theme="accent" type="button" className={merge(`px-4 h-8`, props.classNames?.trigger)}>去充值</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogContent className={platform === Platform.Mobile ? 'max-w-[95vw]' : 'max-w-md'}>
|
||||
<DialogTitle className="flex flex-col gap-2">
|
||||
充值中心
|
||||
</DialogTitle>
|
||||
@@ -235,22 +252,18 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
defaultValue={field.value}
|
||||
onValueChange={field.onChange}
|
||||
className="flex gap-2">
|
||||
<FormOption
|
||||
id={`${id}-alipay`}
|
||||
value="alipay"
|
||||
compare={field.value}
|
||||
className="flex-1 flex-row justify-center items-center">
|
||||
<Image src={alipay} alt="支付宝 logo" className="w-6 h-6"/>
|
||||
<span>支付宝</span>
|
||||
</FormOption>
|
||||
<FormOption
|
||||
id={`${id}-wechat`}
|
||||
value="wechat"
|
||||
compare={field.value}
|
||||
className="flex-1 flex-row justify-center items-center">
|
||||
<Image src={wechat} alt="微信 logo" className="w-6 h-6"/>
|
||||
<span>微信</span>
|
||||
</FormOption>
|
||||
{availableMethods.map(({value, name, icon}) => (
|
||||
<FormOption
|
||||
key={value}
|
||||
id={`${id}-${value}`}
|
||||
value={value}
|
||||
compare={field.value}
|
||||
className="flex-1 flex-row justify-center items-center"
|
||||
>
|
||||
{icon && <Image src={icon} alt={`${name} logo`} className="w-6 h-6"/>}
|
||||
<span>{name}</span>
|
||||
</FormOption>
|
||||
))}
|
||||
</RadioGroup>
|
||||
)}
|
||||
</FormField>
|
||||
|
||||
Reference in New Issue
Block a user