"use client" import { useState, useEffect } from "react" import { useRouter } from "next/navigation" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Users, BookOpen, ShoppingBag, TrendingUp, RefreshCw, ChevronRight } from "lucide-react" export default function AdminDashboard() { const router = useRouter() const [mounted, setMounted] = useState(false) const [users, setUsers] = useState([]) const [purchases, setPurchases] = useState([]) // 从API获取数据 async function loadData() { try { // 获取用户数据 const usersRes = await fetch('/api/db/users') const usersData = await usersRes.json() if (usersData.success && usersData.users) { setUsers(usersData.users) } // 获取订单数据 const ordersRes = await fetch('/api/orders') const ordersData = await ordersRes.json() if (ordersData.success && ordersData.orders) { setPurchases(ordersData.orders) } } catch (e) { console.log('加载数据失败', e) } } useEffect(() => { setMounted(true) loadData() }, []) // 防止Hydration错误:服务端渲染时显示加载状态 if (!mounted) { return (

数据概览

{[1, 2, 3, 4].map((i) => (
))}
加载中...
) } const totalRevenue = purchases.reduce((sum, p) => sum + Number(p.amount || 0), 0) const totalUsers = users.length const totalPurchases = purchases.length // 订单类型对应中文(product_type: section | fullbook | match) const productTypeLabel = (p: { productType?: string; productId?: string; sectionTitle?: string }) => { const type = p.productType || "" if (type === "section") return p.productId ? `单章 ${p.productId}` : "单章" if (type === "fullbook") return "整本购买" if (type === "match") return "找伙伴" return p.sectionTitle || "其他" } const stats = [ { title: "总用户数", value: totalUsers, icon: Users, color: "text-blue-400", bg: "bg-blue-500/20", link: "/admin/users" }, { title: "总收入", value: `¥${Number(totalRevenue).toFixed(2)}`, icon: TrendingUp, color: "text-[#38bdac]", bg: "bg-[#38bdac]/20", link: "/admin/orders", }, { title: "订单数", value: totalPurchases, icon: ShoppingBag, color: "text-purple-400", bg: "bg-purple-500/20", link: "/admin/orders" }, { title: "转化率", value: `${totalUsers > 0 ? ((totalPurchases / totalUsers) * 100).toFixed(1) : 0}%`, icon: BookOpen, color: "text-orange-400", bg: "bg-orange-500/20", link: "/admin/distribution", }, ] return (

数据概览

{stats.map((stat, index) => ( stat.link && router.push(stat.link)} > {stat.title}
{stat.value}
))}
最近订单
{purchases .slice(-5) .reverse() .map((p) => { const referrer = p.referrerId && users.find((u: any) => u.id === p.referrerId) const inviteCode = p.referralCode || referrer?.referral_code || referrer?.nickname || p.referrerId?.slice(0, 8) return (

{productTypeLabel(p)}

{new Date(p.createdAt).toLocaleString()}

{inviteCode && (

邀请码: {inviteCode}

)}

+¥{p.amount}

{p.paymentMethod || "微信支付"}

) })} {purchases.length === 0 &&

暂无订单数据

}
新注册用户
{users .slice(-5) .reverse() .map((u) => (
{u.nickname?.charAt(0) || "?"}

{u.nickname || "匿名用户"}

{u.phone || "-"}

{u.createdAt ? new Date(u.createdAt).toLocaleDateString() : "-"}

))} {users.length === 0 &&

暂无用户数据

}
) }