import { Router, Request, Response } from 'express'; import { PrismaClient } from '@prisma/client'; import { z } from 'zod'; import { authMiddleware } from '../middleware/auth'; const router = Router(); const prisma = new PrismaClient(); // ============================================ // VIP 卡密激活 // ============================================ const activateSchema = z.object({ cardKey: z.string().regex(/^VIP\d+-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/), }); router.post('/activate-vip', authMiddleware, async (req: Request, res: Response) => { try { const body = activateSchema.parse(req.body); // 查找卡密 const card = await prisma.vipCard.findUnique({ where: { cardKey: body.cardKey }, }); if (!card) { return res.status(400).json({ success: false, message: '卡密不存在', }); } if (card.status !== 'UNUSED') { return res.status(400).json({ success: false, message: '卡密已被使用或已失效', }); } // 获取用户当前 VIP 状态 const user = await prisma.user.findUnique({ where: { id: req.user!.userId }, select: { isVip: true, vipExpireAt: true, vipLevel: true }, }); if (!user) { return res.status(404).json({ success: false, message: '用户不存在', }); } // 计算新的 VIP 过期时间 let newExpireAt: Date; if (user.vipExpireAt && user.isVip && new Date() < user.vipExpireAt) { // 已是 VIP,延长时间 newExpireAt = new Date(user.vipExpireAt.getTime() + card.days * 24 * 60 * 60 * 1000); } else { // 非 VIP,从现在开始计算 newExpireAt = new Date(Date.now() + card.days * 24 * 60 * 60 * 1000); } // 更新用户 VIP 状态 const updatedUser = await prisma.user.update({ where: { id: req.user!.userId }, data: { isVip: true, vipExpireAt: newExpireAt, vipLevel: Math.max(user.vipLevel, 1), }, }); // 更新卡密状态 await prisma.vipCard.update({ where: { id: card.id }, data: { status: 'USED', usedBy: req.user!.userId, usedAt: new Date(), }, }); // 记录日志 await prisma.userLog.create({ data: { userId: req.user!.userId, action: 'VIP_ACTIVATE', targetId: card.id, ipAddress: req.ip, }, }); res.json({ success: true, isVip: true, vipExpireAt: newExpireAt, vipLevel: updatedUser.vipLevel, message: `激活成功,VIP 有效期延长 ${card.days} 天`, }); } catch (error) { if (error instanceof z.ZodError) { return res.status(400).json({ success: false, message: '卡密格式无效', }); } console.error('Activate VIP error:', error); res.status(500).json({ success: false, message: '激活失败' }); } }); export default router;