"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, useCallback } from "react" import { Controller, useForm } from "react-hook-form" import z from "zod" import { getPageBalance } from "@/actions/balance" import { DataTable, useDataTable } from "@/components/data-table" import { Page } from "@/components/page" import { Button } from "@/components/ui/button" import { Field, FieldError, FieldLabel } from "@/components/ui/field" import { Input } from "@/components/ui/input" import type { Balance } from "@/models/balance" type FilterValues = { user_phone?: string bill_no?: string admin_id?: string created_at_start?: Date created_at_end?: Date } const filterSchema = z .object({ phone: z.string().optional(), bill_no: z.string().optional(), admin_id: 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 FormValues = z.infer export default function BalancePage() { const searchParams = useSearchParams() const billNo = searchParams.get("bill_no") const router = useRouter() const { control, handleSubmit, reset, getValues } = useForm({ resolver: zodResolver(filterSchema), defaultValues: { phone: "", bill_no: billNo || "", admin_id: "", created_at_start: "", created_at_end: "", }, }) const fetchUsers = useCallback( (page: number, size: number) => { const result: FilterValues = {} const filters = getValues() if (filters.phone?.trim()) result.user_phone = filters.phone.trim() if (filters.bill_no?.trim()) result.bill_no = filters.bill_no.trim() 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 getPageBalance({ page, size, ...result }) }, [getValues], ) const table = useDataTable(fetchUsers) const onFilter = handleSubmit(() => { table.pagination.onPageChange(1) }) return (
( 会员号 {fieldState.error?.message} )} /> ( 账单号 {fieldState.error?.message} )} /> ( 开始时间 {fieldState.error?.message} )} /> ( 结束时间 {fieldState.error?.message} )} />
{...table} columns={[ { header: "会员号", accessorFn: row => row.user?.phone || "", }, { header: "账单编号", accessorKey: "bill?.bill_no", cell: ({ row }) => { const bill_no = row.original.bill?.bill_no return ( {bill_no} ) }, }, { header: "管理员", accessorKey: "admin_id", accessorFn: row => row.admin?.name || "", }, { header: "变动金额", accessorKey: "amount", cell: ({ row }) => { const amount = row.original.amount const isPositive = Number(amount) > 0 return (
{isPositive ? "+" : ""} {Number(amount).toFixed(2)}
) }, }, { header: "余额变化", accessorKey: "balance_prev", cell: ({ row }) => (
¥{Number(row.original.balance_prev).toFixed(2)} ¥{Number(row.original.balance_curr).toFixed(2)}
), }, { header: "备注", accessorKey: "remark", }, { header: "创建时间", accessorKey: "created_at", cell: ({ row }) => { const createdAt = row.original.created_at if (!createdAt) return - const date = new Date(createdAt) if (isNaN(date.getTime())) return - return format(date, "yyyy-MM-dd HH:mm:ss") }, }, ]} />
) }