fix: VIP activation not reflecting due to stale session-status token; add missing routes

This commit is contained in:
Stevenma
2026-05-10 14:50:42 +08:00
parent 3b3ade6a97
commit e249aa56e7
4 changed files with 142 additions and 9 deletions

View File

@@ -91,9 +91,25 @@ app.get('/api/qrcode/public/current', (req, res) => {
res.json({ success: true, data: { qrcode: null, url: '' } }); res.json({ success: true, data: { qrcode: null, url: '' } });
}); });
// 弹窗 // 弹窗 (通用参数化路由)
app.get('/api/popups/', (req, res) => { app.get('/api/popups/:name', (req, res) => {
res.json({ success: true, data: [] }); const { name } = req.params;
const popups: Record<string, any> = {
test_beta_01: { id: 'test_beta_01', title: '测试弹窗', content: '', shown: false },
};
res.json({ success: true, data: popups[name] ?? null });
});
// 嘉豪弹窗
app.get('/api/jiahao', (req, res) => {
res.json({
success: true,
data: {
enabled: false,
message: '',
imageUrl: '',
},
});
}); });
// 售后教程弹窗 // 售后教程弹窗
@@ -172,6 +188,29 @@ app.get('/api/avatars', (req, res) => {
res.json({ success: true, data: [] }); res.json({ success: true, data: [] });
}); });
// ============================================
// 更新服务 (electron-updater)
// ============================================
// 更新配置
app.get('/update-config.json', (req, res) => {
res.json({
version: '7.0.4',
url: '',
notes: '',
mandatory: false,
});
});
// latest.yml (electron-updater 标准格式)
app.get('/latest.yml', (req, res) => {
res.type('text/yaml');
res.send(`version: 7.0.4
files: []
releaseDate: '2024-01-01T00:00:00.000Z'
`);
});
// ============================================ // ============================================
// 错误处理 // 错误处理
// ============================================ // ============================================

View File

@@ -211,14 +211,57 @@ router.post('/login', async (req: Request, res: Response) => {
}); });
// ============================================ // ============================================
// 会话状态 // 会话状态 (从数据库查询最新状态,避免 token 缓存导致 isVip 过期)
// ============================================ // ============================================
router.get('/session-status', authMiddleware, async (req: Request, res: Response) => { router.get('/session-status', authMiddleware, async (req: Request, res: Response) => {
res.json({ try {
success: true, const user = await prisma.user.findUnique({
valid: true, where: { id: req.user!.userId },
user: req.user, select: {
}); id: true,
username: true,
email: true,
avatar: true,
isVip: true,
vipExpireAt: true,
vipLevel: true,
},
});
if (!user) {
return res.status(401).json({
success: false,
message: '用户不存在',
code: 'USER_NOT_FOUND',
});
}
// 检查 VIP 是否过期
let isVip = user.isVip;
if (user.vipExpireAt && new Date() > user.vipExpireAt) {
isVip = false;
await prisma.user.update({
where: { id: user.id },
data: { isVip: false },
});
}
res.json({
success: true,
valid: true,
user: {
userId: user.id,
username: user.username,
email: user.email,
avatar: user.avatar,
isVip,
vipLevel: user.vipLevel,
},
});
} catch (error) {
console.error('Session status error:', error);
res.status(500).json({ success: false, message: '获取会话状态失败' });
}
}); });
// ============================================ // ============================================

View File

@@ -100,6 +100,46 @@ router.post('/', authMiddleware, async (req: Request, res: Response) => {
} }
}); });
// ============================================
// 更新滤镜 (PUT)
// ============================================
router.put('/:id', authMiddleware, async (req: Request, res: Response) => {
try {
const { id } = req.params;
const { title, description, category, filterContent, contentFormat = 'MQTS1', brand, author } = req.body;
const filter = await prisma.filterShare.findUnique({
where: { id },
select: { userId: true },
});
if (!filter) {
return res.status(404).json({ success: false, message: '滤镜不存在' });
}
if (filter.userId !== req.user!.userId) {
return res.status(403).json({ success: false, message: '无权修改此滤镜' });
}
const updateData: any = {};
if (title !== undefined) updateData.title = title;
if (description !== undefined) updateData.description = description;
if (category !== undefined) updateData.category = category;
if (filterContent !== undefined) updateData.filterContent = filterContent;
if (contentFormat !== undefined) updateData.contentFormat = contentFormat;
const updated = await prisma.filterShare.update({
where: { id },
data: updateData,
});
res.json({ success: true, message: '滤镜已更新', data: updated });
} catch (error) {
console.error('Update filter_share error:', error);
res.status(500).json({ success: false, message: '更新失败' });
}
});
// ============================================ // ============================================
// 删除滤镜 // 删除滤镜
// ============================================ // ============================================

View File

@@ -2,6 +2,7 @@ import { Router, Request, Response } from 'express';
import { PrismaClient } from '@prisma/client'; import { PrismaClient } from '@prisma/client';
import { z } from 'zod'; import { z } from 'zod';
import { authMiddleware } from '../middleware/auth'; import { authMiddleware } from '../middleware/auth';
import { generateToken } from '../utils/jwt';
const router = Router(); const router = Router();
const prisma = new PrismaClient(); const prisma = new PrismaClient();
@@ -89,8 +90,18 @@ router.post('/activate-vip', authMiddleware, async (req: Request, res: Response)
}, },
}); });
// 生成新 token包含最新的 VIP 状态)
const token = generateToken({
userId: updatedUser.id,
username: updatedUser.username,
email: updatedUser.email,
isVip: true,
vipLevel: updatedUser.vipLevel,
});
res.json({ res.json({
success: true, success: true,
token,
isVip: true, isVip: true,
vipExpireAt: newExpireAt, vipExpireAt: newExpireAt,
vipLevel: updatedUser.vipLevel, vipLevel: updatedUser.vipLevel,