diff --git a/src/actions/dashboard.ts b/src/actions/dashboard.ts index 8b6f762..b90b0d3 100644 --- a/src/actions/dashboard.ts +++ b/src/actions/dashboard.ts @@ -81,3 +81,11 @@ export async function listInitialization(): Promise diff --git a/src/app/admin/(dashboard)/_client/charts.tsx b/src/app/admin/(dashboard)/_client/charts.tsx index e9bed99..ff121e9 100644 --- a/src/app/admin/(dashboard)/_client/charts.tsx +++ b/src/app/admin/(dashboard)/_client/charts.tsx @@ -18,34 +18,41 @@ import {toast} from 'sonner' import {addDays, format} from 'date-fns' import {Label} from '@/components/ui/label' import {ChartConfig, ChartContainer} from '@/components/ui/chart' -import {CartesianGrid, XAxis, YAxis, Tooltip, Area, AreaChart} from 'recharts' +import {CartesianGrid, XAxis, YAxis, Tooltip, Area, AreaChart, Legend} from 'recharts' -export default function Charts() { - const dateStr = '2025-03-05' - const dateStrA = '2024-03-05' - const date = new Date(dateStr) - const dateA = new Date(dateStrA) +type ChartDataItem = { + time: Date + count: number + count2: number +} + +type ChartData = ChartDataItem[] + +type ChartsProps = { + initialData?: ExtraResp +} + +export default function Charts({initialData}: ChartsProps) { // const [submittedData, setSubmittedData] = useState>() - const [submittedData, setSubmittedData] = useState>([ - {time: new Date(), count: 80}, - {time: date, count: 100}, - {time: dateA, count: 50}, - // {time: `2023-10-03`, count: 80}, - // {time: `2023-10-04`, count: 200}, - // {time: `2023-10-05`, count: 150}, - ]) - const data = [ - {time: `2023-10-01`, count: 100}, - {time: `2023-10-02`, count: 50}, - {time: `2023-10-03`, count: 80}, - {time: `2023-10-04`, count: 200}, - {time: `2023-10-05`, count: 150}, - ] - + const [submittedData, setSubmittedData] = useState>( + initialData || [ + {time: new Date(), count: 80, count2: 64}, + {time: new Date('2025-03-05'), count: 100, count2: 80}, + {time: new Date('2024-03-05'), count: 50, count2: 40}, + ], + ) const formSchema = zod.object({ resource_no: zod.string().min(11, '请输入正确的套餐编号').max(11, '请输入正确的套餐编号').optional(), create_after: zod.date().optional(), create_before: zod.date().optional(), + }).refine((data) => { + if (data.create_after && data.create_before) { + return data.create_before >= data.create_after + } + return true + }, { + message: '结束时间不得早于开始时间', + path: ['create_before'], }) type FormValues = zod.infer @@ -147,6 +154,10 @@ const config = { label: `套餐使用量`, color: `var(--color-primary)`, }, + count2: { + label: `次套餐使用量`, + color: `#82ca9d`, + }, } satisfies ChartConfig type DashboardChartProps = { @@ -154,16 +165,46 @@ type DashboardChartProps = { } function DashboardChart(props: DashboardChartProps) { + const chartData = props.data.map(item => ({ + ...item, + formattedTime: format(new Date(item.time), 'MM-dd'), + })) return ( - + - - + - - - + `日期: ${format(new Date(value), 'yyyy-MM-dd')}`} + formatter={(value, name) => { + const displayName = name === 'count' ? '主套餐使用量' : '次套餐使用量' + return [`${value}`, displayName] + }} + /> + + + ) diff --git a/src/app/admin/(dashboard)/page.tsx b/src/app/admin/(dashboard)/page.tsx index 8daf534..5f0b701 100644 --- a/src/app/admin/(dashboard)/page.tsx +++ b/src/app/admin/(dashboard)/page.tsx @@ -23,7 +23,16 @@ export default async function DashboardPage(props: DashboardPageProps) { ) } const initData = resp.data - + // 添加模拟的 usage 数据(如果 API 返回的 usage 为 null) + // if (!initData.usage) { + // initData.usage = [ + // {time: new Date('2025-03-01'), count: 100, count2: 80}, + // {time: new Date('2025-03-02'), count: 150, count2: 120}, + // {time: new Date('2025-03-03'), count: 80, count2: 64}, + // {time: new Date('2025-03-04'), count: 200, count2: 160}, + // {time: new Date('2025-03-05'), count: 120, count2: 96}, + // ] + // } return ( +
{/* 信息 */}
diff --git a/src/components/composites/payment/mobile-payment.tsx b/src/components/composites/payment/mobile-payment.tsx index eafe1b9..64d77ef 100644 --- a/src/components/composites/payment/mobile-payment.tsx +++ b/src/components/composites/payment/mobile-payment.tsx @@ -1,14 +1,35 @@ 'use client' import {DialogContent} from '@/components/ui/dialog' import {Button} from '@/components/ui/button' -import {completeResource} from '@/actions/resource' import {toast} from 'sonner' -import {CheckCircle, CreditCard} from 'lucide-react' +import {CreditCard, Loader} from 'lucide-react' import {useState} from 'react' import Image from 'next/image' import {PaymentModalProps} from './payment-modal' export function MobilePayment(props: PaymentModalProps) { + const [loading, setLoading] = useState(false) // 加载状态 + const [paymentInitiated, setPaymentInitiated] = useState(false) // 是否已发起支付 + + // 处理确认支付 + const handleConfirmPayment = async () => { + try { + // 在新窗口打开支付链接 + window.location.href = props.pay_url + setPaymentInitiated(true) + } + catch (error) { + toast.error('无法打开支付页面') + } + } + + // 处理支付完成确认 + const handlePaymentComplete = async () => { + setLoading(true) + await props.onConfirm?.() // 调用父组件传入的确认方法 + setLoading(false) + } + return (
@@ -54,15 +75,32 @@ export function MobilePayment(props: PaymentModalProps) { {/* 操作按钮 */}
- - + {!paymentInitiated ? ( // 未发起支付时显示 + <> + + + + ) : ( // 已发起支付时显示 + + )}
diff --git a/src/components/composites/purchase/index.tsx b/src/components/composites/purchase/index.tsx index 00a3ba7..147379b 100644 --- a/src/components/composites/purchase/index.tsx +++ b/src/components/composites/purchase/index.tsx @@ -1,4 +1,5 @@ -import {ReactNode} from 'react' +'use client' +import {ReactNode, useEffect, useState} from 'react' import {merge} from '@/lib/utils' import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/components/ui/tabs' import LongForm from '@/components/composites/purchase/long/form' @@ -10,10 +11,16 @@ type PurchaseProps = { defaultType: TabType } -export default async function Purchase(props: PurchaseProps) { +export default function Purchase(props: PurchaseProps) { + const [currentTab, setCurrentTab] = useState(props.defaultType) + + useEffect(() => { + setCurrentTab(props.defaultType) + }, [props.defaultType]) + return (
- + 短效动态 长效静态 diff --git a/src/components/composites/purchase/pay.tsx b/src/components/composites/purchase/pay.tsx index f804237..ad02e5d 100644 --- a/src/components/composites/purchase/pay.tsx +++ b/src/components/composites/purchase/pay.tsx @@ -10,7 +10,6 @@ import {toast} from 'sonner' import {useRouter} from 'next/navigation' import {completeResource, createResource, prepareResource} from '@/actions/resource' import { - TradePlatform, usePlatformType, TradeMethod, TradeMethodDecoration, @@ -37,18 +36,14 @@ export default function Pay(props: PayProps) { if (props.method === 'balance') return - const method = platform === TradePlatform.Desktop - ? TradeMethod.Sft - : props.method === 'alipay' - ? TradeMethod.SftAlipay - : TradeMethod.SftWechat - + const method = props.method === 'alipay' + ? TradeMethod.SftAlipay + : TradeMethod.SftWechat const res = { ...props.resource, payment_method: method, payment_platform: platform, } - console.log(res, '请求参数') const resp = await prepareResource(res) if (!resp.success) { diff --git a/src/components/composites/recharge/index.tsx b/src/components/composites/recharge/index.tsx index e8dfe6a..be651c3 100644 --- a/src/components/composites/recharge/index.tsx +++ b/src/components/composites/recharge/index.tsx @@ -58,24 +58,17 @@ export default function RechargeModal(props: RechargeModelProps) { const refreshProfile = useProfileStore(store => store.refreshProfile) const createRecharge = async (data: Schema) => { - console.log(data, 'data') - try { - const method = platform === TradePlatform.Desktop - ? TradeMethod.Sft - : data.method === 'alipay' - ? TradeMethod.SftAlipay - : TradeMethod.SftWechat - + const method = data.method === 'alipay' + ? TradeMethod.SftAlipay + : TradeMethod.SftWechat const req = { amount: data.amount.toString(), platform: platform, method: method, } - console.log(req, '请求参数') const result = await RechargePrepare(req) - console.log(result, 'result返回结果') if (result.success) { setTrade({