const express = require('express'); const ChatService = require('../services/ChatService'); const router = express.Router(); const chatService = new ChatService(); /** * 发送消息 * POST /api/chat/send */ router.post('/send', async (req, res) => { try { const { conversationId, message, options = {} } = req.body; // 验证必需参数 if (!conversationId || isNaN(conversationId)) { return res.status(400).json({ success: false, error: '无效的对话ID', message: '参数错误' }); } if (!message || message.trim().length === 0) { return res.status(400).json({ success: false, error: '消息内容不能为空', message: '参数错误' }); } // 限制消息长度 if (message.length > 10000) { return res.status(400).json({ success: false, error: '消息长度不能超过10000个字符', message: '参数错误' }); } // 处理消息 const result = await chatService.processMessage( parseInt(conversationId), message.trim(), options ); res.json({ success: true, data: result, message: '消息发送成功' }); } catch (error) { console.error('发送消息API错误:', error); // 根据错误类型返回不同的HTTP状态码 let statusCode = 500; let errorMessage = '发送消息失败'; if (error.message === '对话不存在') { statusCode = 404; errorMessage = '对话未找到'; } else if (error.message.includes('AI服务配置错误')) { statusCode = 503; errorMessage = 'AI服务配置错误'; } else if (error.message.includes('请求过于频繁')) { statusCode = 429; errorMessage = '请求过于频繁'; } else if (error.message.includes('网络')) { statusCode = 503; errorMessage = '网络连接异常'; } res.status(statusCode).json({ success: false, error: error.message, message: errorMessage }); } }); /** * 发送流式消息 * POST /api/chat/stream */ router.post('/stream', async (req, res) => { try { const { conversationId, message, options = {} } = req.body; // 验证必需参数 if (!conversationId || isNaN(conversationId)) { return res.status(400).json({ success: false, error: '无效的对话ID', message: '参数错误' }); } if (!message || message.trim().length === 0) { return res.status(400).json({ success: false, error: '消息内容不能为空', message: '参数错误' }); } // 设置流式响应头 res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); const streamResult = await chatService.processStreamMessage( parseInt(conversationId), message.trim(), options ); // 发送用户消息信息 res.write(JSON.stringify({ type: 'user_message', data: streamResult.userMessage }) + '\n'); let fullContent = ''; // 处理流式响应 streamResult.stream.on('data', (chunk) => { const lines = chunk.toString().split('\n'); for (const line of lines) { if (line.startsWith('data: ')) { const data = line.slice(6); if (data === '[DONE]') { // 流式响应结束 res.write(JSON.stringify({ type: 'done', data: { content: fullContent } }) + '\n'); res.end(); // 保存完整的AI回复 chatService.completeStreamMessage(conversationId, fullContent) .catch(error => { console.error('保存流式消息失败:', error); }); return; } try { const parsed = JSON.parse(data); const delta = parsed.choices?.[0]?.delta; if (delta?.content) { fullContent += delta.content; // 发送增量内容 res.write(JSON.stringify({ type: 'content', data: { delta: delta.content, content: fullContent } }) + '\n'); } } catch (parseError) { console.error('解析流式数据失败:', parseError); } } } }); streamResult.stream.on('error', (error) => { console.error('流式响应错误:', error); res.write(JSON.stringify({ type: 'error', data: { error: error.message } }) + '\n'); res.end(); }); } catch (error) { console.error('流式消息API错误:', error); if (!res.headersSent) { res.status(500).json({ success: false, error: error.message, message: '流式消息发送失败' }); } else { res.write(JSON.stringify({ type: 'error', data: { error: error.message } }) + '\n'); res.end(); } } }); /** * 重新生成回复 * POST /api/chat/regenerate */ router.post('/regenerate', async (req, res) => { try { const { conversationId, options = {} } = req.body; if (!conversationId || isNaN(conversationId)) { return res.status(400).json({ success: false, error: '无效的对话ID', message: '参数错误' }); } const result = await chatService.regenerateResponse( parseInt(conversationId), options ); res.json({ success: true, data: result, message: '重新生成回复成功' }); } catch (error) { console.error('重新生成回复API错误:', error); let statusCode = 500; let errorMessage = '重新生成回复失败'; if (error.message === '对话不存在') { statusCode = 404; errorMessage = '对话未找到'; } else if (error.message === '没有找到用户消息') { statusCode = 400; errorMessage = '没有可重新生成的消息'; } res.status(statusCode).json({ success: false, error: error.message, message: errorMessage }); } }); /** * 检查LLM服务状态 * GET /api/chat/status */ router.get('/status', async (req, res) => { try { const status = await chatService.checkLLMStatus(); res.json({ success: true, data: status, message: 'LLM服务状态检查完成' }); } catch (error) { console.error('检查LLM状态API错误:', error); res.status(500).json({ success: false, error: error.message, message: '检查LLM状态失败' }); } }); /** * 获取聊天统计信息 * GET /api/chat/stats */ router.get('/stats', async (req, res) => { try { const stats = await chatService.getChatStats(); res.json({ success: true, data: stats, message: '获取聊天统计成功' }); } catch (error) { console.error('获取聊天统计API错误:', error); res.status(500).json({ success: false, error: error.message, message: '获取聊天统计失败' }); } }); /** * 清除缓存 * POST /api/chat/clear-cache */ router.post('/clear-cache', async (req, res) => { try { const { type = 'all' } = req.body; const cacheManager = require('../utils/cache'); if (type === 'all') { cacheManager.clearAll(); } else { cacheManager.clear(type); } res.json({ success: true, message: `${type}缓存清理成功` }); } catch (error) { console.error('清除缓存API错误:', error); res.status(500).json({ success: false, error: error.message, message: '清除缓存失败' }); } }); /** * 获取对话上下文 * GET /api/chat/context/:conversationId */ router.get('/context/:conversationId', async (req, res) => { try { const { conversationId } = req.params; const { maxTokens = 4000 } = req.query; if (!conversationId || isNaN(conversationId)) { return res.status(400).json({ success: false, error: '无效的对话ID', message: '参数错误' }); } const context = await chatService.getConversationContext( parseInt(conversationId), parseInt(maxTokens) ); res.json({ success: true, data: { context, messageCount: context.length, estimatedTokens: context.reduce((sum, msg) => sum + (msg.content?.length || 0), 0 ) }, message: '获取对话上下文成功' }); } catch (error) { console.error('获取对话上下文API错误:', error); res.status(500).json({ success: false, error: error.message, message: '获取对话上下文失败' }); } }); module.exports = router;