From 860c599b7ca7270e34d016b258318b35ab5b2077 Mon Sep 17 00:00:00 2001 From: wangxiaogang <1433729587@qq.com> Date: Mon, 8 Jun 2026 14:48:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=B3=BB=E7=BB=9F=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E2=80=94=20=E5=AE=89=E5=85=A8=E5=92=8C?= =?UTF-8?q?=E7=A8=B3=E5=AE=9A=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端: - config.ts 使用 requireAdmin 中间件,统一响应格式 - feedback.ts 使用 requireAdmin 中间件,移除重复权限检查 - feedback.ts 添加 affectedRows 检查(反馈不存在时返回 404) - 全局错误处理中间件兜底未捕获异常 前端: - request.ts 添加 15 秒请求超时设置 --- client/src/utils/request.ts | 1 + server/src/index.ts | 6 ++++++ server/src/routes/config.ts | 16 ++++------------ server/src/routes/feedback.ts | 25 +++++++------------------ 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/client/src/utils/request.ts b/client/src/utils/request.ts index a9fa67f..9d4ece4 100644 --- a/client/src/utils/request.ts +++ b/client/src/utils/request.ts @@ -47,6 +47,7 @@ export function request(options: RequestOptions): Promise { url: API_BASE + options.url, method: options.method || 'GET', data: options.data, + timeout: 15000, // 15秒超时 header: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}) diff --git a/server/src/index.ts b/server/src/index.ts index da92fa2..a50c228 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -171,6 +171,12 @@ app.get('/api/health', async (_req, res) => { } }) +// 全局错误处理中间件(兜底未捕获的异常) +app.use((err: any, _req: express.Request, res: express.Response, _next: express.NextFunction) => { + console.error('[Global] Unhandled error:', err) + res.status(500).json({ code: 50000, message: '服务器内部错误' }) +}) + let server: any // 生产环境:先备份再迁移,迁移出问题可恢复 diff --git a/server/src/routes/config.ts b/server/src/routes/config.ts index f72e14c..8ada268 100644 --- a/server/src/routes/config.ts +++ b/server/src/routes/config.ts @@ -1,10 +1,10 @@ import { Router } from 'express' import pool from '../db/connection' -import { authMiddleware } from '../middleware/auth' +import { requireAdmin } from '../middleware/requireAdmin' const router = Router() -/** 获取公开配置(无需管理员权限) */ +/** 获取公开配置(经过全局 authMiddleware,无需管理员权限) */ router.get('/', async (_req, res) => { try { const [rows] = await pool.execute('SELECT config_key, config_value FROM sys_config') @@ -20,19 +20,11 @@ router.get('/', async (_req, res) => { }) /** 更新配置(管理员权限) */ -router.put('/', authMiddleware, async (req, res) => { +router.put('/', requireAdmin, async (req, res) => { try { - const userId = (req as any).userId - const [users] = await pool.execute('SELECT role FROM users WHERE id = ?', [userId]) - const user = (users as any[])[0] - - if (!user || user.role !== 'admin') { - return res.status(403).json({ error: '无权限' }) - } - const data = req.body if (!data || typeof data !== 'object') { - return res.status(400).json({ error: '无效的配置数据' }) + return res.status(400).json({ code: 40001, message: '无效的配置数据' }) } // 批量更新配置 diff --git a/server/src/routes/feedback.ts b/server/src/routes/feedback.ts index dd0750e..168b7fd 100644 --- a/server/src/routes/feedback.ts +++ b/server/src/routes/feedback.ts @@ -1,6 +1,7 @@ import { Router } from 'express' import pool from '../db/connection' import { authMiddleware } from '../middleware/auth' +import { requireAdmin } from '../middleware/requireAdmin' const router = Router() @@ -30,16 +31,8 @@ router.post('/', authMiddleware, async (req, res) => { }) /** 管理员获取反馈列表 */ -router.get('/', authMiddleware, async (req, res) => { +router.get('/', requireAdmin, async (req, res) => { try { - const userId = (req as any).userId - const [users] = await pool.execute('SELECT role FROM users WHERE id = ?', [userId]) - const user = (users as any[])[0] - - if (!user || user.role !== 'admin') { - return res.status(403).json({ code: 40300, message: '无权限' }) - } - const page = Math.max(1, parseInt(req.query.page as string) || 1) const pageSize = Math.min(100, Math.max(1, parseInt(req.query.pageSize as string) || 20)) const status = req.query.status as string @@ -77,16 +70,8 @@ router.get('/', authMiddleware, async (req, res) => { }) /** 管理员更新反馈状态 */ -router.put('/:id/status', authMiddleware, async (req, res) => { +router.put('/:id/status', requireAdmin, async (req, res) => { try { - const userId = (req as any).userId - const [users] = await pool.execute('SELECT role FROM users WHERE id = ?', [userId]) - const user = (users as any[])[0] - - if (!user || user.role !== 'admin') { - return res.status(403).json({ code: 40300, message: '无权限' }) - } - const { id } = req.params const { status, admin_reply } = req.body @@ -102,6 +87,10 @@ router.put('/:id/status', authMiddleware, async (req, res) => { ) const feedback = (feedbackRows as any[])[0] + if (!feedback) { + return res.status(404).json({ code: 40400, message: '反馈不存在' }) + } + await pool.execute( 'UPDATE feedbacks SET status = ?, admin_reply = ? WHERE id = ?', [status, admin_reply || '', id]