This commit is contained in:
2025-06-22 11:34:32 +08:00
parent 142992a6c9
commit 7d139b22db
55 changed files with 11035 additions and 105 deletions
+61
View File
@@ -0,0 +1,61 @@
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { verifyToken, hashPassword, verifyPassword } from '@/lib/auth'
export async function PUT(request: NextRequest) {
try {
const authHeader = request.headers.get('Authorization')
const token = authHeader?.replace('Bearer ', '')
if (!token) {
return NextResponse.json({ message: '未提供认证令牌' }, { status: 401 })
}
const decoded = verifyToken(token)
if (!decoded) {
return NextResponse.json({ message: '无效的认证令牌' }, { status: 401 })
}
const { currentPassword, newPassword } = await request.json()
if (!currentPassword || !newPassword) {
return NextResponse.json({ message: '请提供当前密码和新密码' }, { status: 400 })
}
if (newPassword.length < 6) {
return NextResponse.json({ message: '新密码长度至少6位' }, { status: 400 })
}
// 获取用户当前信息
const user = await prisma.user.findUnique({
where: { id: decoded.userId }
})
if (!user) {
return NextResponse.json({ message: '用户不存在' }, { status: 404 })
}
// 验证当前密码
const isCurrentPasswordValid = await verifyPassword(currentPassword, user.password)
if (!isCurrentPasswordValid) {
return NextResponse.json({ message: '当前密码错误' }, { status: 400 })
}
// 哈希新密码
const hashedNewPassword = await hashPassword(newPassword)
// 更新密码
await prisma.user.update({
where: { id: decoded.userId },
data: {
password: hashedNewPassword
}
})
return NextResponse.json({ message: '密码修改成功' })
} catch (error) {
console.error('修改密码失败:', error)
return NextResponse.json({ message: '修改密码失败' }, { status: 500 })
}
}
+86
View File
@@ -0,0 +1,86 @@
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { verifyToken } from '@/lib/auth'
export async function GET(request: NextRequest) {
try {
const authHeader = request.headers.get('Authorization')
const token = authHeader?.replace('Bearer ', '')
if (!token) {
return NextResponse.json({ message: '未提供认证令牌' }, { status: 401 })
}
const decoded = verifyToken(token)
if (!decoded) {
return NextResponse.json({ message: '无效的认证令牌' }, { status: 401 })
}
const user = await prisma.user.findUnique({
where: { id: decoded.userId },
select: {
id: true,
email: true,
username: true,
name: true,
phone: true,
address: true,
isAdmin: true,
createdAt: true
}
})
if (!user) {
return NextResponse.json({ message: '用户不存在' }, { status: 404 })
}
return NextResponse.json(user)
} catch (error) {
console.error('获取用户资料失败:', error)
return NextResponse.json({ message: '获取用户资料失败' }, { status: 500 })
}
}
export async function PUT(request: NextRequest) {
try {
const authHeader = request.headers.get('Authorization')
const token = authHeader?.replace('Bearer ', '')
if (!token) {
return NextResponse.json({ message: '未提供认证令牌' }, { status: 401 })
}
const decoded = verifyToken(token)
if (!decoded) {
return NextResponse.json({ message: '无效的认证令牌' }, { status: 401 })
}
const { name, phone, address } = await request.json()
const updatedUser = await prisma.user.update({
where: { id: decoded.userId },
data: {
name,
phone,
address
},
select: {
id: true,
email: true,
username: true,
name: true,
phone: true,
address: true,
isAdmin: true,
createdAt: true
}
})
return NextResponse.json(updatedUser)
} catch (error) {
console.error('更新用户资料失败:', error)
return NextResponse.json({ message: '更新用户资料失败' }, { status: 500 })
}
}
+170
View File
@@ -0,0 +1,170 @@
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { verifyToken } from '@/lib/auth'
export async function GET(request: NextRequest) {
try {
const authHeader = request.headers.get('authorization')
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return NextResponse.json(
{ message: '请先登录' },
{ status: 401 }
)
}
const token = authHeader.substring(7)
const decoded = verifyToken(token)
if (!decoded) {
return NextResponse.json(
{ message: '登录已过期' },
{ status: 401 }
)
}
// 获取用户基本信息
const user = await prisma.user.findUnique({
where: { id: decoded.userId },
select: {
id: true,
createdAt: true,
username: true,
email: true
}
})
if (!user) {
return NextResponse.json(
{ message: '用户不存在' },
{ status: 404 }
)
}
// 获取订单统计
const orderStats = await prisma.order.groupBy({
by: ['status'],
where: {
userId: decoded.userId
},
_count: {
id: true
},
_sum: {
totalAmount: true
}
})
// 获取总订单数和总消费
const totalOrders = await prisma.order.count({
where: {
userId: decoded.userId
}
})
const totalSpent = await prisma.order.aggregate({
where: {
userId: decoded.userId,
status: {
in: ['CONFIRMED', 'SHIPPED', 'DELIVERED']
}
},
_sum: {
totalAmount: true
}
}) // 获取购物车商品数量
const cartItemsCount = await prisma.cartItem.count({
where: {
userId: decoded.userId
}
})
// 获取最近订单
const recentOrders = await prisma.order.findMany({
where: {
userId: decoded.userId
},
orderBy: {
createdAt: 'desc'
},
take: 5,
select: {
id: true,
status: true,
totalAmount: true,
createdAt: true
}
})
// 按状态分组订单统计
const ordersByStatus = {
PENDING: 0,
CONFIRMED: 0,
SHIPPED: 0,
DELIVERED: 0,
CANCELLED: 0
}
orderStats.forEach(stat => {
ordersByStatus[stat.status as keyof typeof ordersByStatus] = stat._count.id
})
// 获取用户最喜欢的配件类型(购买最多的类型)
const favoriteComponentType = await prisma.orderItem.groupBy({
by: ['componentId'],
where: {
order: {
userId: decoded.userId,
status: {
in: ['CONFIRMED', 'SHIPPED', 'DELIVERED']
}
}
},
_sum: {
quantity: true
},
orderBy: {
_sum: {
quantity: 'desc'
}
},
take: 1
})
let favoriteType = null
if (favoriteComponentType.length > 0) {
const component = await prisma.component.findUnique({
where: { id: favoriteComponentType[0].componentId },
include: {
componentType: true
}
})
favoriteType = component?.componentType?.name || null
} return NextResponse.json({
user: {
id: user.id,
username: user.username,
email: user.email,
memberSince: user.createdAt
},
orderStats: {
total: totalOrders,
byStatus: ordersByStatus,
totalSpent: totalSpent._sum.totalAmount || 0
},
recentOrders,
favoriteComponentType: favoriteType, summary: {
totalOrders,
totalSpent: totalSpent._sum.totalAmount || 0,
pendingOrders: ordersByStatus.PENDING,
completedOrders: ordersByStatus.DELIVERED,
cartItems: cartItemsCount
}
})
} catch (error) {
console.error('获取用户统计失败:', error)
return NextResponse.json(
{ message: '获取统计数据失败' },
{ status: 500 }
)
}
}