import { useEffect, useState } from 'react' import { Eye, Users } from 'lucide-react' import { fetchVisits, type VisitStats } from '@/api/visits' import { cn } from '@/lib/utils' const RANGES = [7, 30, 90] export default function VisitsPage() { const [days, setDays] = useState(30) const [data, setData] = useState(null) const [error, setError] = useState('') useEffect(() => { let cancelled = false fetchVisits(days) .then((d) => { if (!cancelled) setData(d) }) .catch((e: Error) => { if (!cancelled) setError(e.message) }) return () => { cancelled = true } }, [days]) // 补全连续日期,缺失天补 0,趋势图才连贯 const map = new Map((data?.daily ?? []).map((r) => [r.date, r])) const series = Array.from({ length: days }, (_, i) => { const d = new Date() d.setDate(d.getDate() - (days - 1 - i)) const date = d.toISOString().slice(0, 10) return map.get(date) ?? { date, uv: 0, pv: 0 } }) const maxUv = Math.max(1, ...series.map((s) => s.uv)) const cards = [ { label: '今日访客 UV', value: data?.today_uv, icon: Users }, { label: '今日访问 PV', value: data?.today_pv, icon: Eye }, { label: `近 ${days} 天访客`, value: data?.total_uv, icon: Users }, { label: `近 ${days} 天访问`, value: data?.total_pv, icon: Eye }, ] return (

访问统计

用户端访问足迹,按 IP 去重

{RANGES.map((r) => ( ))}
{error && (

{error}

)}
{cards.map((c) => (
{c.label}
{c.value ?? '—'}
))}

每日访客趋势

UV
{series.map((s) => (
))}
{series[0]?.date.slice(5)} {series[series.length - 1]?.date.slice(5)}
) }