import { GetServerSideProps } from 'next'; import AdminLayout from '@/components/admin/AdminLayout'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Users, FileText, ShoppingBag, DollarSign } from 'lucide-react'; import { verifyToken } from '@/lib/auth'; import { User, Article, Order } from '@/models'; import { BarChart, Bar, XAxis, YAxis, ResponsiveContainer } from 'recharts'; // 定义统计数据接口 interface DashboardStats { totalUsers: number; totalArticles: number; totalOrders: number; totalRevenue: number; } export default function AdminDashboard({ stats }: { stats: DashboardStats }) { // 模拟图表数据 (实际应从 API 获取) const data = [ { name: 'Jan', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Feb', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Mar', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Apr', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'May', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Jun', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Jul', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Aug', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Sep', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Oct', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Nov', total: Math.floor(Math.random() * 5000) + 1000 }, { name: 'Dec', total: Math.floor(Math.random() * 5000) + 1000 }, ]; return (
{/* ... (existing header and stats cards) ... */}

仪表盘

查看系统概览和关键指标。

总用户数
{stats.totalUsers}

+20.1% 较上月

文章总数
{stats.totalArticles}

+15 篇 本周新增

总订单数
{stats.totalOrders}

+19% 较上月

总收入
¥{stats.totalRevenue.toFixed(2)}

+10.5% 较上月

近期概览 `¥${value}`} /> 最新动态
{/* 模拟动态数据 */}

新用户注册

zhangsan@example.com

刚刚

新订单支付成功

¥299.00 - 年度会员

5分钟前
); } export const getServerSideProps: GetServerSideProps = async (context) => { const { req } = context; const token = req.cookies.token; // 1. 验证 Token if (!token) { return { redirect: { destination: '/auth/login?redirect=/admin', permanent: false, }, }; } const user = verifyToken(token); if (!user || user.role !== 'admin') { return { redirect: { destination: '/', // 非管理员跳转首页 permanent: false, }, }; } // 2. 获取统计数据 (SSR) // 使用 withDatabase 确保数据库连接 // 注意:getServerSideProps 中不能直接使用 withDatabase 高阶函数包裹,需要手动调用连接逻辑或确保全局连接 // 这里我们假设 mongoose 已经在 api 路由或其他地方连接过,或者我们在 _app.tsx 中处理了连接 // 为了稳妥,我们在 lib/dbConnect.ts 中应该有一个缓存连接的逻辑,这里简单起见,我们直接查询 // 更好的做法是把数据获取逻辑封装成 service // 由于 withDatabase 是 API 路由的高阶函数,这里我们直接使用 mongoose // 但为了避免连接问题,我们最好在 models/index.ts 导出时确保连接,或者在这里手动 connect // 鉴于项目结构,我们假设 models 已经可用。 // 修正:在 getServerSideProps 中直接操作数据库需要确保连接。 // 我们临时引入 mongoose 并连接。 const mongoose = require('mongoose'); if (mongoose.connection.readyState === 0) { await mongoose.connect(process.env.MONGODB_URI); } const totalUsers = await User.countDocuments(); const totalArticles = await Article.countDocuments(); const totalOrders = await Order.countDocuments(); // 计算总收入 const orders = await Order.find({ 订单状态: 'paid' }, '支付金额'); const totalRevenue = orders.reduce((acc: number, order: any) => acc + (order.支付金额 || 0), 0); return { props: { stats: { totalUsers, totalArticles, totalOrders, totalRevenue } }, }; };