"use client" import { zodResolver } from "@hookform/resolvers/zod" import { format } from "date-fns" import { Suspense, useCallback, useState } from "react" import { Controller, useForm } from "react-hook-form" import { z } from "zod" import { bindAdmin, getPageUsers } from "@/actions/user" import { DataTable, useDataTable } from "@/components/data-table" import { Badge } from "@/components/ui/badge" 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 { useFetch } from "@/hooks/data" import type { User } from "@/models/user" type FilterValues = { phone?: string name?: string identified?: boolean enabled?: boolean assigned?: boolean } const filterSchema = z.object({ phone: z.string().optional(), name: z.string().optional(), identified: z.string().optional(), enabled: z.string().optional(), assigned: z.string().optional(), }) type FormValues = z.infer export default function UserPage() { const [filters, setFilters] = useState({}) const { control, handleSubmit, reset } = useForm({ resolver: zodResolver(filterSchema), defaultValues: { phone: "", name: "", identified: "all", enabled: "all", assigned: "all", }, }) const fetchUsers = useCallback( (page: number, size: number) => getPageUsers({ page, size, ...filters }), [filters], ) const table = useDataTable(fetchUsers) const bind = useFetch(table, (id: number) => bindAdmin({ id }), { done: "用户已认领", fail: "用户认领失败", }) const onFilter = handleSubmit(data => { const result: FilterValues = {} if (data.phone) result.phone = data.phone if (data.name) result.name = data.name if (data.identified && data.identified !== "all") result.identified = data.identified === "1" if (data.enabled && data.enabled !== "all") result.enabled = data.enabled === "1" if (data.assigned && data.assigned !== "all") result.assigned = data.assigned === "has" setFilters(result) table.pagination.onPageChange(1) }) return (
( 手机号 {fieldState.error?.message} )} /> ( 账户 {fieldState.error?.message} )} /> ( 实名状态 {fieldState.error?.message} )} /> ( 账号状态 {fieldState.error?.message} )} /> ( 认领状态 {fieldState.error?.message} )} />
{...table} columns={[ { header: "ID", accessorKey: "id" }, { header: "账号", accessorKey: "username" }, { header: "手机", accessorKey: "phone" }, { header: "邮箱", accessorKey: "email" }, { header: "姓名", accessorKey: "name" }, { header: "余额", accessorKey: "balance", cell: ({ row }) => { const balance = Number(row.original.balance) || 0 return ( 0 ? "text-green-500" : "text-orange-500" } > ¥{balance.toFixed(2)} ) }, }, { header: "实名状态", accessorKey: "id_type", cell: ({ row }) => ( {row.original.id_type === 1 ? "已认证" : "未认证"} ), }, { header: "身份证号", accessorKey: "id_no", cell: ({ row }) => { const idNo = row.original.id_no return idNo ? `${idNo.slice(0, 6)}****${idNo.slice(-4)}` : "-" }, }, { header: "账号状态", accessorKey: "status", cell: ({ row }) => (row.original.status === 1 ? "正常" : "禁用"), }, { header: "联系方式", accessorKey: "contact_wechat" }, { header: "管理员", cell: ({ row }) => row.original.admin?.name || "-", }, { header: "最后登录时间", accessorKey: "last_login", cell: ({ row }) => row.original.last_login ? format( new Date(row.original.last_login), "yyyy-MM-dd HH:mm", ) : "-", }, { header: "最后登录IP", accessorKey: "last_login_ip", cell: ({ row }) => row.original.last_login_ip || "-", }, { header: "创建时间", accessorKey: "created_at", cell: ({ row }) => format(new Date(row.original.created_at), "yyyy-MM-dd HH:mm"), }, { id: "action", meta: { pin: "right" }, header: "操作", cell: ctx => ( ), }, ]} />
) }