'use client'; import { useState } from 'react'; import { QRCodeSVG } from 'qrcode.react'; import { PageHeader } from '@/components/layout/page-header'; import { useC2cBotStatus, useEnableC2cBot, useDisableC2cBot, useC2cBotOrders, } from '@/features/c2c-bot/hooks/use-c2c-bot'; import { Card, CardContent, CardHeader, CardTitle, CardDescription, } from '@/components/ui/card'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; import { Badge } from '@/components/ui/badge'; import { Switch } from '@/components/ui/switch'; import { RefreshCw, Wallet, BarChart3, Copy, Check, ChevronLeft, ChevronRight, AlertCircle, CheckCircle2, Zap, } from 'lucide-react'; import { format } from 'date-fns'; import { zhCN } from 'date-fns/locale'; function formatNumber(value: string | undefined | null, decimals: number = 2) { if (!value) return '0'; const num = parseFloat(value); if (isNaN(num)) return '0'; return num.toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals, }); } function truncateAddress(addr: string | null | undefined, chars: number = 8) { if (!addr) return '-'; if (addr.length <= chars * 2 + 2) return addr; return `${addr.slice(0, chars + 2)}...${addr.slice(-chars)}`; } export default function C2cBotPage() { const [orderPage, setOrderPage] = useState(1); const [copied, setCopied] = useState(false); const pageSize = 20; const { data: status, isLoading: statusLoading, refetch } = useC2cBotStatus(); const { data: ordersData, isLoading: ordersLoading } = useC2cBotOrders(orderPage, pageSize); const enableMutation = useEnableC2cBot(); const disableMutation = useDisableC2cBot(); const totalPages = ordersData ? Math.ceil(ordersData.total / pageSize) : 0; const handleToggle = (checked: boolean) => { if (checked) { enableMutation.mutate(); } else { disableMutation.mutate(); } }; const handleCopyAddress = () => { if (status?.hotWallet?.address) { navigator.clipboard.writeText(status.hotWallet.address); setCopied(true); setTimeout(() => setCopied(false), 2000); } }; if (statusLoading) { return (
); } return (
{/* 状态卡片 */}
{/* Bot 开关 */} Bot 状态 自动购买用户卖单
运行状态
{status?.enabled ? ( 运行中 ) : ( 已停止 )}
区块链服务 {status?.blockchainAvailable ? (
可用
) : (
不可用
)}
Bot 每 10 秒扫描一次待处理卖单,自动转账 dUSDT 完成购买
{/* 热钱包 */} 热钱包 Bot 使用的 dUSDT 钱包

dUSDT 余额

{formatNumber(status?.hotWallet?.balance, 4)}

{status?.hotWallet?.address ? ( <>

钱包地址 (Kava EVM)

{status.hotWallet.address}
向此地址转入 dUSDT (Kava链) 即可为 Bot 充值
) : (
热钱包未配置
)}
{/* 统计 */} 统计 Bot 自动购买统计

总成交订单

{status?.stats?.totalBotOrders ?? 0}

总成交金额

{formatNumber(status?.stats?.totalBotAmount, 4)}

{/* 订单历史 */} Bot 订单历史 {ordersData && ( 共 {ordersData.total} 条 )} {ordersLoading ? (
) : ordersData && ordersData.data.length > 0 ? ( 订单号 卖家 金额 数量 Kava 地址 TxHash 完成时间 {ordersData.data.map((order) => ( {order.orderNo}
{order.makerNickname || order.makerPhone || order.makerAccountSequence}
{formatNumber(order.totalAmount, 4)} {formatNumber(order.quantity, 4)} {truncateAddress(order.sellerKavaAddress, 6)} {order.paymentTxHash ? ( {truncateAddress(order.paymentTxHash, 6)} ) : ( '-' )} {order.completedAt ? format(new Date(order.completedAt), 'yyyy-MM-dd HH:mm:ss', { locale: zhCN }) : '-'}
))}
) : (
暂无 Bot 订单记录
)} {/* 分页 */} {totalPages > 1 && (
第 {orderPage} / {totalPages} 页
)}
); }