"use client" import { zodResolver } from "@hookform/resolvers/zod" import { format } from "date-fns" import Link from "next/link" import { useRouter, useSearchParams } from "next/navigation" import { Suspense } from "react" import { Controller, useForm } from "react-hook-form" import { z } from "zod" import { getPageBatch } from "@/actions/batch" 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 { Batch } from "@/models/batch" type APIFilterParams = { user_phone?: string batch_no?: string resource_no?: string prov?: string city?: string isp?: string created_at_start?: Date created_at_end?: Date } const filterSchema = z .object({ user_phone: z.string().optional(), resource_no: z.string().optional(), batch_no: z.string().optional(), prov: z.string().optional(), city: z.string().optional(), isp: 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 BatchPage() { const searchParams = useSearchParams() const resourceNo = searchParams.get("resource_no") const batchNo = searchParams.get("batch_no") const router = useRouter() const { control, handleSubmit, reset, getValues } = useForm({ resolver: zodResolver(filterSchema), defaultValues: { user_phone: "", batch_no: batchNo || "", prov: "", resource_no: resourceNo || "", city: "", isp: "all", created_at_start: "", created_at_end: "", }, }) const table = useDataTable((page, size) => { const result: APIFilterParams = {} const filters = getValues() if (filters.user_phone?.trim()) result.user_phone = filters.user_phone.trim() if (filters.batch_no?.trim()) result.batch_no = filters.batch_no.trim() if (filters.resource_no?.trim()) result.resource_no = filters.resource_no.trim() if (filters.prov?.trim()) result.prov = filters.prov.trim() if (filters.city?.trim()) result.city = filters.city.trim() if (filters.isp && filters.isp !== "all") result.isp = filters.isp if (filters.created_at_start) result.created_at_start = new Date(filters.created_at_start) if (filters.created_at_end) result.created_at_end = new Date(filters.created_at_end) return getPageBatch({ page, size, ...result }) }) const onFilter = handleSubmit(() => { 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} )} /> ( 结束时间 {fieldState.error?.message} )} />
Loading...}> {...table} columns={[ { header: "会员号", accessorFn: row => row.user?.phone || "", }, { header: "套餐号", accessorKey: "resource.resource_no", cell: ({ row }) => { const resourceNo = row.original.resource?.resource_no const type = row.original.resource?.type return ( {resourceNo} ) }, }, { header: "提取编号", accessorKey: "batch_no", cell: ({ row }) => { const batch_no = row.original.batch_no return ( {batch_no} ) }, }, { header: "省份", accessorKey: "prov" }, { header: "城市", accessorKey: "city" }, { header: "用户IP", accessorKey: "ip" }, { header: "运营商", accessorKey: "isp" }, { header: "提取数量", accessorKey: "count" }, { header: "提取时间", accessorKey: "time", cell: ({ row }) => format(new Date(row.original.time), "yyyy-MM-dd HH:mm:ss"), }, ]} />
) }