import type { ColumnDef } from "@tanstack/react-table" import { SearchIcon } from "lucide-react" import { useCallback, useEffect, useMemo, useRef, useState } from "react" import { Link } from "react-router-dom" import { toast } from "sonner" import { fetchMyAccounts } from "@/api/account" import DataTable from "@/components/data-table" import Page from "@/components/page" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { useProducts } from "@/lib/hooks/useProducts" import { EXPIRED_DAY_OPTIONS, type MyAccountItem, type MyAccountQueryParams, } from "@/lib/models/account" type ChannelQuery = { expiredDay: string productId: string packageName: string keyword: string } const INITIAL_QUERY: ChannelQuery = { expiredDay: "-100", productId: "0", packageName: "0", keyword: "", } const PAGE_SIZE = 10 function toParams(query: ChannelQuery): MyAccountQueryParams { return { ExpiredDay: Number(query.expiredDay), ProductId: Number(query.productId) || undefined, PackageId: query.packageName === "0" ? undefined : query.packageName, Keyword: query.keyword.trim() || undefined, } } const columns: ColumnDef[] = [ { accessorKey: "StartTime", header: "开通时间", }, { accessorKey: "ProductName", header: "产品", }, { accessorKey: "PackageName", header: "套餐", }, { accessorKey: "Account", header: "账号", cell: ({ row }) => ( {row.original.Account} ), }, { accessorKey: "Pwd", header: "密码", cell: ({ row }) => ( {row.original.Pwd} ), }, { accessorKey: "ConnectCount", header: "连接数", }, { accessorKey: "EndTime", header: "到期时间", }, { accessorKey: "RestTime", header: "剩余时间", cell: ({ row }) => ( {row.original.RestTime} ), }, { accessorKey: "Status", header: "状态", cell: ({ row }) => row.original.Status === 1 ? ( 正常 ) : ( 已退货 ), }, ] export default function ChannelsPage() { const products = useProducts() const [query, setQuery] = useState(INITIAL_QUERY) const [data, setData] = useState([]) const [status, setStatus] = useState<"load" | "done" | "fail">("load") const [page, setPage] = useState(1) const [selection, setSelection] = useState>({}) const selectedProduct = useMemo( () => products.find(item => String(item.Product.Id) === query.productId) ?? null, [products, query.productId], ) const load = useCallback(async (params: MyAccountQueryParams) => { setStatus("load") const res = await fetchMyAccounts(params) if (res.success) { setData(res.data) setStatus("done") } else { setStatus("fail") toast.error(res.message) } setPage(1) setSelection({}) }, []) const loadedRef = useRef(false) useEffect(() => { if (loadedRef.current) return loadedRef.current = true load(toParams(INITIAL_QUERY)) }, [load]) const applyFilters = (patch: Partial) => { const next = { ...query, ...patch } setQuery(next) load(toParams(next)) } const handleReset = () => { setQuery(INITIAL_QUERY) load(toParams(INITIAL_QUERY)) } const paged = useMemo( () => data.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE), [data, page], ) return (

为了给您带来更好的服务体验,请完善qq号和微信号。 立即完善》

过期时间:
setQuery({ ...query, keyword: e.target.value })} onKeyDown={e => { if (e.key === "Enter") applyFilters({}) }} placeholder="账号" className="w-40" />
*批量续费可通过筛选和搜索功能精准定位账号

IP账号管理

String(row.Id)} pagination={{ page, size: PAGE_SIZE, total: data.length, onPageChange: setPage, }} />
) }