"use client" import { zodResolver } from "@hookform/resolvers/zod" import { format } from "date-fns" import { CheckCircle, Clock, XCircle } from "lucide-react" import { Suspense, useCallback, useState } from "react" import { Controller, useForm } from "react-hook-form" import { z } from "zod" import { getPageTrade } from "@/actions/trade" import { DataTable, useDataTable } from "@/components/data-table" import { Page } from "@/components/page" import { Button } from "@/components/ui/button" import { Field, FieldError, FieldGroup, FieldLabel, } from "@/components/ui/field" import { Input } from "@/components/ui/input" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import type { Trade } from "@/models/trade" type FilterValues = { user_phone?: string inner_no?: string method?: number platform?: number status?: number created_at_start?: Date created_at_end?: Date } const filterSchema = z .object({ user_phone: z .string() .optional() .transform(val => val?.trim()), inner_no: z .string() .optional() .transform(val => val?.trim()), method: z.string().optional(), platform: z.string().optional(), status: z.string().optional(), created_at_start: z.string().optional(), created_at_end: z.string().optional(), }) .superRefine((data, ctx) => { if (data.created_at_start && data.created_at_end) { const start = new Date(data.created_at_start) const end = new Date(data.created_at_end) if (end < start) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "结束时间不能早于开始时间", path: ["created_at_end"], }) } } }) type FilterSchema = z.infer export default function TradePage() { const [filters, setFilters] = useState({}) const { control, handleSubmit, reset } = useForm({ resolver: zodResolver(filterSchema), defaultValues: { user_phone: "", inner_no: "", method: "all", platform: "all", status: "all", created_at_start: "", created_at_end: "", }, }) const fetchTrades = useCallback( (page: number, size: number) => { return getPageTrade({ page, size, ...filters }) }, [filters], ) const table = useDataTable(fetchTrades) const onFilter = handleSubmit(data => { const result: FilterValues = {} if (data.user_phone?.trim()) result.user_phone = data.user_phone.trim() if (data.inner_no?.trim()) result.inner_no = data.inner_no.trim() if (data.method && data.method !== "all") result.method = Number(data.method) if (data.platform && data.platform !== "all") result.platform = Number(data.platform) if (data.status && data.status !== "all") result.status = Number(data.status) if (data.created_at_start) result.created_at_start = new Date(data.created_at_start) if (data.created_at_end) result.created_at_end = new Date(data.created_at_end) setFilters(result) table.pagination.onPageChange(1) }) return ( {/* 筛选表单 */}
( 会员号 {fieldState.error?.message} )} /> ( 订单号 {fieldState.error?.message} )} /> ( 支付渠道 {fieldState.error?.message} )} /> ( 支付平台 {fieldState.error?.message} )} /> ( 支付状态 {fieldState.error?.message} )} /> ( 开始时间 {fieldState.error?.message} )} /> ( 结束时间 {fieldState.error?.message} )} />
{...table} columns={[ { header: "创建时间", accessorKey: "created_at", cell: ({ row }) => format(new Date(row.original.created_at), "yyyy-MM-dd HH:mm"), }, { header: "会员号", accessorFn: row => row.user?.phone || "" }, { header: "订单号", accessorKey: "inner_no" }, { header: "购买套餐", accessorKey: "subject" }, { header: "支付金额", accessorKey: "payment", cell: ({ row }) => { const payment = typeof row.original.payment === "string" ? parseFloat(row.original.payment) : row.original.payment || 0 return (
0 ? "text-green-500" : "text-orange-500" } > ¥{payment.toFixed(2)}
) }, }, { header: "支付状态", accessorKey: "status", cell: ({ row }) => { const status = row.original.status switch (status) { case 0: return (
待支付
) case 1: return (
支付成功
) case 2: return (
取消支付
) default: return - } }, }, { header: "支付平台", accessorKey: "platform", cell: ({ row }) => { const platform = row.original.platform if (!platform) return - return (
{platform === 1 ? ( 电脑网站 ) : platform === 2 ? ( 手机网站 ) : ( - )}
) }, }, { header: "支付渠道", accessorKey: "method", cell: ({ row }) => { const methodMap: Record = { 1: "支付宝", 2: "微信", 3: "商福通", 4: "商福通渠道支付宝", 5: "商福通渠道微信", } return (
{methodMap[row.original.method as number] || "未知"}
) }, }, { header: "渠道订单号", accessorKey: "outer_no" }, ]} />
) }