124 lines
3.1 KiB
TypeScript
124 lines
3.1 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { prisma } from '@/lib/prisma'
|
|
import { requireAdmin } from '@/lib/admin-auth'
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
await requireAdmin(request)
|
|
|
|
// 按消费金额倒排的前十用户
|
|
const topUsersBySpending = await prisma.user.findMany({
|
|
where: {
|
|
isAdmin: false,
|
|
orders: {
|
|
some: {}
|
|
}
|
|
},
|
|
select: {
|
|
id: true,
|
|
username: true,
|
|
name: true,
|
|
email: true,
|
|
orders: {
|
|
select: {
|
|
totalAmount: true
|
|
}
|
|
}
|
|
},
|
|
take: 10
|
|
})
|
|
|
|
const usersWithSpending = topUsersBySpending.map(user => ({
|
|
id: user.id,
|
|
username: user.username,
|
|
name: user.name || user.username,
|
|
email: user.email,
|
|
totalSpending: user.orders.reduce((sum, order) => sum + order.totalAmount, 0),
|
|
orderCount: user.orders.length
|
|
})).sort((a, b) => b.totalSpending - a.totalSpending)
|
|
|
|
// 按销售量倒排序的前十配件
|
|
const topComponentsBySales = await prisma.component.findMany({
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
brand: true,
|
|
price: true,
|
|
componentType: {
|
|
select: {
|
|
name: true
|
|
}
|
|
},
|
|
orderItems: {
|
|
select: {
|
|
quantity: true
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
const componentsWithSales = topComponentsBySales.map(component => ({
|
|
id: component.id,
|
|
name: component.name,
|
|
brand: component.brand,
|
|
price: component.price,
|
|
typeName: component.componentType.name,
|
|
totalSales: component.orderItems.reduce((sum, item) => sum + item.quantity, 0),
|
|
totalRevenue: component.orderItems.reduce((sum, item) => sum + (item.quantity * component.price), 0)
|
|
})).sort((a, b) => b.totalSales - a.totalSales).slice(0, 10)
|
|
|
|
// 总体统计
|
|
const totalUsers = await prisma.user.count({ where: { isAdmin: false } })
|
|
const totalOrders = await prisma.order.count()
|
|
const totalComponents = await prisma.component.count()
|
|
const totalRevenue = await prisma.order.aggregate({
|
|
_sum: {
|
|
totalAmount: true
|
|
}
|
|
})
|
|
|
|
const recentOrders = await prisma.order.findMany({
|
|
take: 5,
|
|
orderBy: {
|
|
createdAt: 'desc'
|
|
},
|
|
include: {
|
|
user: {
|
|
select: {
|
|
username: true,
|
|
name: true
|
|
}
|
|
},
|
|
orderItems: {
|
|
include: {
|
|
component: {
|
|
select: {
|
|
name: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
return NextResponse.json({
|
|
overview: {
|
|
totalUsers,
|
|
totalOrders,
|
|
totalComponents,
|
|
totalRevenue: totalRevenue._sum.totalAmount || 0
|
|
},
|
|
topUsers: usersWithSpending,
|
|
topComponents: componentsWithSales,
|
|
recentOrders
|
|
})
|
|
|
|
} catch (error: any) {
|
|
console.error('获取统计数据失败:', error)
|
|
return NextResponse.json(
|
|
{ message: error.message || '获取统计数据失败' },
|
|
{ status: error.message === '权限不足' ? 403 : 500 }
|
|
)
|
|
}
|
|
}
|