重构认证逻辑,优化登录和用户信息获取流程,新增全局缓存支持
This commit is contained in:
@@ -10,7 +10,7 @@ import {zodResolver} from '@hookform/resolvers/zod'
|
||||
import {createResourceByBalance} from '@/actions/resource'
|
||||
import {toast} from 'sonner'
|
||||
import {useRouter} from 'next/navigation'
|
||||
import {AuthContext} from '@/components/providers/AuthProvider'
|
||||
import {StoreContext} from '@/components/providers/StoreProvider'
|
||||
|
||||
// 定义表单验证架构
|
||||
const schema = z.object({
|
||||
|
||||
@@ -6,7 +6,7 @@ import wechat from '../_assets/wechat.svg'
|
||||
import balance from '../_assets/balance.svg'
|
||||
import Image from 'next/image'
|
||||
import {useContext, useRef, useState} from 'react'
|
||||
import {AuthContext} from '@/components/providers/AuthProvider'
|
||||
import {StoreContext, useProfileStore} from '@/components/providers/StoreProvider'
|
||||
import {Alert, AlertDescription} from '@/components/ui/alert'
|
||||
import {
|
||||
prepareResourceByAlipay,
|
||||
@@ -32,7 +32,9 @@ export type PayProps = {
|
||||
|
||||
export default function Pay(props: PayProps) {
|
||||
|
||||
const ctx = useContext(AuthContext)
|
||||
const profile = useProfileStore(store=>store.profile)
|
||||
const refreshProfile = useProfileStore(store=>store.refreshProfile)
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
const [payInfo, setPayInfo] = useState<CreateResourceResp | undefined>()
|
||||
const canvas = useRef<HTMLCanvasElement>(null)
|
||||
@@ -97,7 +99,7 @@ export default function Pay(props: PayProps) {
|
||||
})
|
||||
|
||||
setOpen(false)
|
||||
await ctx.refreshProfile()
|
||||
await refreshProfile()
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e)
|
||||
@@ -133,12 +135,12 @@ export default function Pay(props: PayProps) {
|
||||
</DialogHeader>
|
||||
|
||||
{props.method === 'balance' ? (
|
||||
ctx.profile && (
|
||||
profile && (
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-weak text-sm">账户余额</span>
|
||||
<span className={`text-lg`}>{ctx.profile.balance}元</span>
|
||||
<span className={`text-lg`}>{profile.balance}元</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-weak text-sm">支付金额</span>
|
||||
@@ -147,13 +149,13 @@ export default function Pay(props: PayProps) {
|
||||
<hr className="my-2"/>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-weak text-sm">支付后余额</span>
|
||||
<span className={`text-lg ${ctx.profile.balance > props.amount ? 'text-done' : `text-fail`}`}>
|
||||
{ctx.profile.balance - props.amount}元
|
||||
<span className={`text-lg ${profile.balance > props.amount ? 'text-done' : `text-fail`}`}>
|
||||
{profile.balance - props.amount}元
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{ctx.profile.balance < props.amount && (
|
||||
{profile.balance < props.amount && (
|
||||
<Alert variant="fail">
|
||||
<AlertDescription>
|
||||
余额不足,请先充值或选择其他支付方式
|
||||
@@ -161,7 +163,7 @@ export default function Pay(props: PayProps) {
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{ctx.profile.balance >= props.amount && (
|
||||
{profile.balance >= props.amount && (
|
||||
<Alert>
|
||||
<AlertDescription>
|
||||
检查无误后,点击确认支付按钮完成支付
|
||||
@@ -200,7 +202,7 @@ export default function Pay(props: PayProps) {
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={props.method === 'balance' && !!ctx.profile && ctx.profile.balance < props.amount}
|
||||
disabled={props.method === 'balance' && !!profile && profile.balance < props.amount}
|
||||
onClick={onSubmit}
|
||||
>
|
||||
{props.method === 'balance' ? '确认支付' : '已完成支付'}
|
||||
|
||||
@@ -21,7 +21,7 @@ import {useContext, useRef, useState} from 'react'
|
||||
import {Loader} from 'lucide-react'
|
||||
import {RechargeByAlipay, RechargeByAlipayConfirm, RechargeByWechat, RechargeByWechatConfirm} from '@/actions/user'
|
||||
import * as qrcode from 'qrcode'
|
||||
import {AuthContext} from '@/components/providers/AuthProvider'
|
||||
import {StoreContext, useProfileStore} from '@/components/providers/StoreProvider'
|
||||
|
||||
const schema = zod.object({
|
||||
method: zod.enum(['alipay', 'wechat']),
|
||||
@@ -53,7 +53,7 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
pay_url: string
|
||||
}>()
|
||||
|
||||
const ctx = useContext(AuthContext)
|
||||
const refreshProfile = useProfileStore(store => store.refreshProfile)
|
||||
|
||||
const createRecharge = async (data: Schema) => {
|
||||
try {
|
||||
@@ -124,7 +124,7 @@ export default function RechargeModal(props: RechargeModelProps) {
|
||||
}
|
||||
toast.success(`充值成功`)
|
||||
closeDialog()
|
||||
await ctx.refreshProfile()
|
||||
await refreshProfile()
|
||||
}
|
||||
catch (e) {
|
||||
toast.error(`充值失败`, {
|
||||
|
||||
@@ -8,15 +8,16 @@ import Image from 'next/image'
|
||||
import alipay from '@/components/composites/purchase/_assets/alipay.svg'
|
||||
import wechat from '@/components/composites/purchase/_assets/wechat.svg'
|
||||
import balance from '@/components/composites/purchase/_assets/balance.svg'
|
||||
import {AuthContext} from '@/components/providers/AuthProvider'
|
||||
import {useProfileStore} from '@/components/providers/StoreProvider'
|
||||
import RechargeModal from '@/components/composites/purchase/_client/recharge'
|
||||
import Pay from '@/components/composites/purchase/_client/pay'
|
||||
import {Button, buttonVariants} from '@/components/ui/button'
|
||||
import Link from 'next/link'
|
||||
|
||||
export type RightProps = {}
|
||||
|
||||
export default function Right(props: RightProps) {
|
||||
const authCtx = useContext(AuthContext)
|
||||
const profile = authCtx.profile
|
||||
const profile = useProfileStore(store => store.profile)
|
||||
|
||||
const form = useContext(PurchaseFormContext)?.form
|
||||
if (!form) {
|
||||
@@ -89,58 +90,65 @@ export default function Right(props: RightProps) {
|
||||
<span>价格</span>
|
||||
<span className={`text-xl text-orange-500`}>¥{price}</span>
|
||||
</p>
|
||||
<FormField name={`pay_type`} label={`支付方式`} className={`flex flex-col gap-6`}>
|
||||
{({id, field}) => (
|
||||
<RadioGroup
|
||||
id={id}
|
||||
defaultValue={field.value}
|
||||
onValueChange={field.onChange}
|
||||
className={`flex flex-col gap-3`}>
|
||||
<div className={`w-full p-3 flex flex-col gap-4 bg-gray-100 rounded-md`}>
|
||||
<p className={`flex items-center gap-3`}>
|
||||
<Image src={balance} alt={`余额icon`}/>
|
||||
<span className={`text-sm text-gray-500`}>账户余额</span>
|
||||
</p>
|
||||
<p className={`flex justify-between items-center`}>
|
||||
<span className={`text-xl`}>{profile?.balance}</span>
|
||||
<RechargeModal/>
|
||||
</p>
|
||||
{profile ? <>
|
||||
<FormField name={`pay_type`} label={`支付方式`} className={`flex flex-col gap-6`}>
|
||||
{({id, field}) => (
|
||||
<RadioGroup
|
||||
id={id}
|
||||
defaultValue={field.value}
|
||||
onValueChange={field.onChange}
|
||||
className={`flex flex-col gap-3`}>
|
||||
|
||||
</div>
|
||||
<FormOption
|
||||
id={`${id}-balance`}
|
||||
value={`balance`}
|
||||
compare={field.value}
|
||||
className={`p-3 w-full flex-row gap-2 justify-center`}>
|
||||
<Image src={balance} alt={`余额 icon`}/>
|
||||
<span>余额</span>
|
||||
</FormOption>
|
||||
<FormOption
|
||||
id={`${id}-wechat`}
|
||||
value={`wechat`}
|
||||
compare={field.value}
|
||||
className={`p-3 w-full flex-row gap-2 justify-center`}>
|
||||
<Image src={wechat} alt={`微信 logo`}/>
|
||||
<span>微信</span>
|
||||
</FormOption>
|
||||
<FormOption
|
||||
id={`${id}-alipay`}
|
||||
value={`alipay`}
|
||||
compare={field.value}
|
||||
className={`p-3 w-full flex-row gap-2 justify-center`}>
|
||||
<Image src={alipay} alt={`支付宝 logo`}/>
|
||||
<span>支付宝</span>
|
||||
</FormOption>
|
||||
</RadioGroup>
|
||||
)}
|
||||
</FormField>
|
||||
<Pay method={payType} amount={price} resource={{
|
||||
type: Number(watchType),
|
||||
live: Number(watchLive) * 60,
|
||||
quota: watchQuota,
|
||||
expire: Number(watchExpire),
|
||||
daily_limit: watchDailyLimit,
|
||||
}}/>
|
||||
<div className={`w-full p-3 flex flex-col gap-4 bg-gray-100 rounded-md`}>
|
||||
<p className={`flex items-center gap-3`}>
|
||||
<Image src={balance} alt={`余额icon`}/>
|
||||
<span className={`text-sm text-gray-500`}>账户余额</span>
|
||||
</p>
|
||||
<p className={`flex justify-between items-center`}>
|
||||
<span className={`text-xl`}>{profile?.balance}</span>
|
||||
<RechargeModal/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<FormOption
|
||||
id={`${id}-balance`}
|
||||
value={`balance`}
|
||||
compare={field.value}
|
||||
className={`p-3 w-full flex-row gap-2 justify-center`}>
|
||||
<Image src={balance} alt={`余额 icon`}/>
|
||||
<span>余额</span>
|
||||
</FormOption>
|
||||
<FormOption
|
||||
id={`${id}-wechat`}
|
||||
value={`wechat`}
|
||||
compare={field.value}
|
||||
className={`p-3 w-full flex-row gap-2 justify-center`}>
|
||||
<Image src={wechat} alt={`微信 logo`}/>
|
||||
<span>微信</span>
|
||||
</FormOption>
|
||||
<FormOption
|
||||
id={`${id}-alipay`}
|
||||
value={`alipay`}
|
||||
compare={field.value}
|
||||
className={`p-3 w-full flex-row gap-2 justify-center`}>
|
||||
<Image src={alipay} alt={`支付宝 logo`}/>
|
||||
<span>支付宝</span>
|
||||
</FormOption>
|
||||
</RadioGroup>
|
||||
)}
|
||||
</FormField>
|
||||
<Pay method={payType} amount={price} resource={{
|
||||
type: Number(watchType),
|
||||
live: Number(watchLive) * 60,
|
||||
quota: watchQuota,
|
||||
expire: Number(watchExpire),
|
||||
daily_limit: watchDailyLimit,
|
||||
}}/>
|
||||
</> : (
|
||||
<Link href={`/login`} className={buttonVariants()}>
|
||||
登录后支付
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user