2025-12-29 18:01:16 +08:00
|
|
|
"use client"
|
2026-01-05 09:14:41 +08:00
|
|
|
import { format } from "date-fns"
|
2025-12-30 18:35:37 +08:00
|
|
|
import { Suspense } from "react"
|
2026-01-06 14:57:55 +08:00
|
|
|
import { bindAdmin, getPageUsers } from "@/actions/user"
|
2025-12-29 18:01:16 +08:00
|
|
|
import { DataTable, useDataTable } from "@/components/data-table"
|
2026-01-05 09:14:41 +08:00
|
|
|
import { Badge } from "@/components/ui/badge"
|
2025-12-30 14:40:07 +08:00
|
|
|
import { Button } from "@/components/ui/button"
|
2026-01-06 14:57:55 +08:00
|
|
|
import { useFetch } from "@/hooks/data"
|
2025-12-29 18:01:16 +08:00
|
|
|
import type { User } from "@/models/user"
|
|
|
|
|
|
|
|
|
|
export default function UserPage() {
|
|
|
|
|
const table = useDataTable<User>((page, size) => getPageUsers({ page, size }))
|
2026-01-09 18:36:08 +08:00
|
|
|
const bind = useFetch(table, (id: number) => bindAdmin({ id }), {
|
2026-01-06 14:57:55 +08:00
|
|
|
done: "用户已认领",
|
|
|
|
|
fail: "用户认领失败",
|
|
|
|
|
})
|
2025-12-29 18:01:16 +08:00
|
|
|
return (
|
|
|
|
|
<div>
|
2025-12-30 18:35:37 +08:00
|
|
|
<Suspense>
|
|
|
|
|
<DataTable<User>
|
|
|
|
|
{...table}
|
|
|
|
|
columns={[
|
|
|
|
|
{ header: "账号", accessorKey: "username" },
|
|
|
|
|
{ header: "手机", accessorKey: "phone" },
|
|
|
|
|
{ header: "邮箱", accessorKey: "email" },
|
|
|
|
|
{ header: "姓名", accessorKey: "name" },
|
2026-01-05 09:14:41 +08:00
|
|
|
{
|
|
|
|
|
header: "余额",
|
|
|
|
|
accessorKey: "balance",
|
|
|
|
|
cell: ({ row }) => {
|
|
|
|
|
const balance =
|
|
|
|
|
typeof row.original.balance === "string"
|
|
|
|
|
? parseFloat(row.original.balance)
|
|
|
|
|
: row.original.balance || 0
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex gap-1">
|
|
|
|
|
<span
|
|
|
|
|
className={
|
|
|
|
|
balance > 0 ? "text-green-500" : "text-orange-500"
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
¥{balance.toFixed(2)}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
header: "认证状态",
|
|
|
|
|
accessorKey: "id_type",
|
|
|
|
|
cell: ({ row }) => {
|
|
|
|
|
const status = row.original.id_type
|
|
|
|
|
return (
|
|
|
|
|
<Badge
|
|
|
|
|
variant={status === 1 ? "default" : "secondary"}
|
|
|
|
|
className={
|
|
|
|
|
status === 1
|
|
|
|
|
? "bg-green-100 text-green-800"
|
|
|
|
|
: "bg-gray-100 text-gray-800"
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{status === 1 ? "已认证" : "未认证"}
|
|
|
|
|
</Badge>
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
header: "账号状态",
|
|
|
|
|
accessorKey: "status",
|
|
|
|
|
cell: ({ row }) => {
|
|
|
|
|
const status = row.original.status
|
|
|
|
|
return status === 1 ? "正常" : ""
|
|
|
|
|
},
|
|
|
|
|
},
|
2025-12-30 18:35:37 +08:00
|
|
|
{ header: "联系方式", accessorKey: "contact_wechat" },
|
2026-01-09 18:36:08 +08:00
|
|
|
{
|
|
|
|
|
header: "管理员",
|
|
|
|
|
cell: ({ row }) => row.original.admin?.name,
|
|
|
|
|
},
|
2026-01-05 09:14:41 +08:00
|
|
|
{
|
|
|
|
|
header: "最后登录时间",
|
|
|
|
|
accessorKey: "last_login",
|
|
|
|
|
cell: ({ row }) =>
|
|
|
|
|
format(new Date(row.original.last_login), "yyyy-MM-dd HH:mm"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
header: "创建时间",
|
|
|
|
|
accessorKey: "created_at",
|
|
|
|
|
cell: ({ row }) =>
|
|
|
|
|
format(new Date(row.original.created_at), "yyyy-MM-dd HH:mm"),
|
|
|
|
|
},
|
2025-12-30 18:35:37 +08:00
|
|
|
{
|
|
|
|
|
header: "操作",
|
2026-01-06 14:57:55 +08:00
|
|
|
cell: ctx => (
|
|
|
|
|
<Button
|
|
|
|
|
size={"sm"}
|
|
|
|
|
onClick={() => bind(ctx.row.original.id)}
|
2026-01-09 18:36:08 +08:00
|
|
|
disabled={!!ctx.row.original.admin_id}
|
2026-01-06 14:57:55 +08:00
|
|
|
>
|
2026-01-09 18:36:08 +08:00
|
|
|
{ctx.row.original.admin_id ? "已认领" : "认领"}
|
2026-01-06 14:57:55 +08:00
|
|
|
</Button>
|
2025-12-30 18:35:37 +08:00
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
</Suspense>
|
2025-12-29 18:01:16 +08:00
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|