Files

1 line
14 KiB
JSON

{"repo": "cc703/pets-plants", "files": {"server/routes/ai.js": {"69c5d01a1cceaa299f3a6de5c3debb8b6318ca1c": {"t": 1785745528.0075898, "n": 4160, "h": "5fe3e73cf8f649a4", "c": "const express = require('express');\nconst { createRateLimit } = require('../middleware/rateLimit');\n\nconst router = express.Router();\nconst aiRateLimit = createRateLimit({\n windowMs: 60 * 1000,\n max: 20,\n keyPrefix: 'ai',\n});\n\nconst DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY;\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/chat/completions';\nconst DEEPSEEK_MODEL = process.env.DEEPSEEK_MODEL || 'deepseek-chat';\nconst SAFETY_NOTE = 'AI 建议仅供养宠参考,不能替代兽医诊疗;若宠物持续呕吐、精神萎靡、呼吸异常、抽搐、外伤出血等,请尽快就医。';\n\nconst SYSTEM_PROMPT = `你是\"萌宠星球\"的 AI 宠物顾问,名叫\"萌萌\"。你的职责是:\n\n1. 品种识别与推荐:根据用户描述推荐合适的宠物品种\n2. 养护知识:提供喂养、美容、运动等方面的专业建议\n3. 健康问答:解答宠物健康相关问题(注意:严重问题建议就医)\n4. 行为训练:提供宠物行为训练建议\n5. 趣味冷知识:分享有趣的宠物知识\n\n回复要求:\n- 使用中文回答\n- 语气亲切友好,适当使用 emoji\n- 回答要专业但易懂\n- 涉及医疗问题时,提醒用户咨询专业兽医\n- 回答控制在 300 字以内`;\n\nasync function requestDeepSeek(messages, options = {}) {\n if (!DEEPSEEK_API_KEY) {\n const error = new Error('DEEPSEEK_API_KEY missing');\n error.statusCode = 500;\n throw error;\n }\n\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${DEEPSEEK_API_KEY}`,\n },\n body: JSON.stringify({\n model: DEEPSEEK_MODEL,\n messages,\n max_tokens: options.maxTokens || 1024,\n temperature: options.temperature ?? 0.7,\n stream: false,\n }),\n });\n\n if (!response.ok) {\n const errBody = await response.text();\n console.error('DeepSeek API error:', response.status, errBody);\n const error = new Error('DeepSeek API error');\n error.statusCode = 502;\n throw error;\n }\n\n const data = await response.json();\n return data.choices?.[0]?.message?.content || '';\n}\n\nrouter.post('/chat', aiRateLimit, async (req, res) => {\n try {\n console.log('[AI] 收到聊天请求');\n const { messages } = req.body;\n\n if (!messages || !Array.isArray(messages) || messages.length === 0) {\n return res.status(400).json({ code: 1001, message: '消息内容不能为空' });\n }\n\n if (!DEEPSEEK_API_KEY) {\n console.error('[AI] DEEPSEEK_API_KEY 未设置');\n return res.status(500).json({ code: 5000, message: 'AI 服务未配置,请在 .env 中设置 DEEPSEEK_API_KEY' });\n }\n\n console.log('[AI] API Key 已配置,正在调用 DeepSeek...');\n\n const apiMessages = [\n { role: 'system', content: SYSTEM_PROMPT },\n ...messages.map((m) => ({\n role: m.isUser ? 'user' : 'assistant',\n content: m.text,\n })),\n ];\n\n const reply = await requestDeepSeek(apiMessages) || '抱歉,我没有理解你的问题,请换个方式描述一下~';\n console.log('[AI] DeepSeek 响应成功,回复长度:', reply.length);\n\n return res.json({ code: 0, data: { reply, safetyNote: SAFETY_NOTE } });\n } catch (error) {\n console.error('AI chat error:', error);\n return res.status(500).json({ code: 5000, message: '服务器内部错误' });\n }\n});\n\nrouter.get('/knowledge', aiRateLimit, async (req, res) => {\n try {\n if (!DEEPSEEK_API_KEY) {\n console.error('[AI] DEEPSEEK_API_KEY 未设置');\n return res.status(500).json({ code: 5000, message: 'AI 服务未配置,请在 .env 中设置 DEEPSEEK_API_KEY' });\n }\n\n const topic = String(req.query.topic || '猫狗日常养护、品种趣闻、宠物安全提醒').slice(0, 80);\n const content = await requestDeepSeek([\n {\n role: 'system',\n content:\n '你是萌宠星球的宠物知识编辑。请生成一个适合首页“今日知识”卡片的中文宠物知识点,优先给出可靠、实用、非医疗诊断的内容。',\n },\n {\n role: 'user',\n content:\n `主题范围:${topic}。只返回一条 45 到 80 个中文字符的知识正文,不要标题、编号、Markdown 或解释。`,\n },\n ], { maxTokens: 300, temperature: 0.9 });\n\n const text = content\n .replace(/^[\"“]|[\"”]$/g, '')\n .replace(/^[-*\\d.、\\s]+/, '')\n .trim();\n\n const knowledge = {\n icon: 'sparkles',\n title: 'AI 新知',\n text: text.slice(0, 120),\n source: 'DeepSeek AI',\n };\n\n if (!knowledge.text) {\n return res.status(502).json({ code: 5002, message: 'AI 知识生成失败,请稍后重试' });\n }\n\n return res.json({ code: 0, data: knowledge });\n } catch (error) {\n console.error('AI knowledge error:', error);\n const status = error.statusCode || 500;\n return res.status(status).json({\n code: status === 502 ? 5002 : 5000,\n message: status === 502 ? 'AI 服务响应异常,请稍后重试' : '服务器内部错误',\n });\n }\n});\n\nmodule.exports = router;\n"}, "ffb8bf960d53b242b380386033ac2b83121b506e": {"t": 1785753882.1213224, "n": 4160, "h": "5fe3e73cf8f649a4", "c": "const express = require('express');\nconst { createRateLimit } = require('../middleware/rateLimit');\n\nconst router = express.Router();\nconst aiRateLimit = createRateLimit({\n windowMs: 60 * 1000,\n max: 20,\n keyPrefix: 'ai',\n});\n\nconst DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY;\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/chat/completions';\nconst DEEPSEEK_MODEL = process.env.DEEPSEEK_MODEL || 'deepseek-chat';\nconst SAFETY_NOTE = 'AI 建议仅供养宠参考,不能替代兽医诊疗;若宠物持续呕吐、精神萎靡、呼吸异常、抽搐、外伤出血等,请尽快就医。';\n\nconst SYSTEM_PROMPT = `你是\"萌宠星球\"的 AI 宠物顾问,名叫\"萌萌\"。你的职责是:\n\n1. 品种识别与推荐:根据用户描述推荐合适的宠物品种\n2. 养护知识:提供喂养、美容、运动等方面的专业建议\n3. 健康问答:解答宠物健康相关问题(注意:严重问题建议就医)\n4. 行为训练:提供宠物行为训练建议\n5. 趣味冷知识:分享有趣的宠物知识\n\n回复要求:\n- 使用中文回答\n- 语气亲切友好,适当使用 emoji\n- 回答要专业但易懂\n- 涉及医疗问题时,提醒用户咨询专业兽医\n- 回答控制在 300 字以内`;\n\nasync function requestDeepSeek(messages, options = {}) {\n if (!DEEPSEEK_API_KEY) {\n const error = new Error('DEEPSEEK_API_KEY missing');\n error.statusCode = 500;\n throw error;\n }\n\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${DEEPSEEK_API_KEY}`,\n },\n body: JSON.stringify({\n model: DEEPSEEK_MODEL,\n messages,\n max_tokens: options.maxTokens || 1024,\n temperature: options.temperature ?? 0.7,\n stream: false,\n }),\n });\n\n if (!response.ok) {\n const errBody = await response.text();\n console.error('DeepSeek API error:', response.status, errBody);\n const error = new Error('DeepSeek API error');\n error.statusCode = 502;\n throw error;\n }\n\n const data = await response.json();\n return data.choices?.[0]?.message?.content || '';\n}\n\nrouter.post('/chat', aiRateLimit, async (req, res) => {\n try {\n console.log('[AI] 收到聊天请求');\n const { messages } = req.body;\n\n if (!messages || !Array.isArray(messages) || messages.length === 0) {\n return res.status(400).json({ code: 1001, message: '消息内容不能为空' });\n }\n\n if (!DEEPSEEK_API_KEY) {\n console.error('[AI] DEEPSEEK_API_KEY 未设置');\n return res.status(500).json({ code: 5000, message: 'AI 服务未配置,请在 .env 中设置 DEEPSEEK_API_KEY' });\n }\n\n console.log('[AI] API Key 已配置,正在调用 DeepSeek...');\n\n const apiMessages = [\n { role: 'system', content: SYSTEM_PROMPT },\n ...messages.map((m) => ({\n role: m.isUser ? 'user' : 'assistant',\n content: m.text,\n })),\n ];\n\n const reply = await requestDeepSeek(apiMessages) || '抱歉,我没有理解你的问题,请换个方式描述一下~';\n console.log('[AI] DeepSeek 响应成功,回复长度:', reply.length);\n\n return res.json({ code: 0, data: { reply, safetyNote: SAFETY_NOTE } });\n } catch (error) {\n console.error('AI chat error:', error);\n return res.status(500).json({ code: 5000, message: '服务器内部错误' });\n }\n});\n\nrouter.get('/knowledge', aiRateLimit, async (req, res) => {\n try {\n if (!DEEPSEEK_API_KEY) {\n console.error('[AI] DEEPSEEK_API_KEY 未设置');\n return res.status(500).json({ code: 5000, message: 'AI 服务未配置,请在 .env 中设置 DEEPSEEK_API_KEY' });\n }\n\n const topic = String(req.query.topic || '猫狗日常养护、品种趣闻、宠物安全提醒').slice(0, 80);\n const content = await requestDeepSeek([\n {\n role: 'system',\n content:\n '你是萌宠星球的宠物知识编辑。请生成一个适合首页“今日知识”卡片的中文宠物知识点,优先给出可靠、实用、非医疗诊断的内容。',\n },\n {\n role: 'user',\n content:\n `主题范围:${topic}。只返回一条 45 到 80 个中文字符的知识正文,不要标题、编号、Markdown 或解释。`,\n },\n ], { maxTokens: 300, temperature: 0.9 });\n\n const text = content\n .replace(/^[\"“]|[\"”]$/g, '')\n .replace(/^[-*\\d.、\\s]+/, '')\n .trim();\n\n const knowledge = {\n icon: 'sparkles',\n title: 'AI 新知',\n text: text.slice(0, 120),\n source: 'DeepSeek AI',\n };\n\n if (!knowledge.text) {\n return res.status(502).json({ code: 5002, message: 'AI 知识生成失败,请稍后重试' });\n }\n\n return res.json({ code: 0, data: knowledge });\n } catch (error) {\n console.error('AI knowledge error:', error);\n const status = error.statusCode || 500;\n return res.status(status).json({\n code: status === 502 ? 5002 : 5000,\n message: status === 502 ? 'AI 服务响应异常,请稍后重试' : '服务器内部错误',\n });\n }\n});\n\nmodule.exports = router;\n"}, "690fb998a281520557c257805278514f7d0107d7": {"t": 1785753883.547936, "n": 2440, "h": "f6166b06d3d15958", "c": "const express = require('express');\nconst { createRateLimit } = require('../middleware/rateLimit');\n\nconst router = express.Router();\nconst aiRateLimit = createRateLimit({\n windowMs: 60 * 1000,\n max: 20,\n keyPrefix: 'ai',\n});\n\nconst DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY;\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/chat/completions';\nconst SAFETY_NOTE = 'AI 建议仅供养宠参考,不能替代兽医诊疗;若宠物持续呕吐、精神萎靡、呼吸异常、抽搐、外伤出血等,请尽快就医。';\n\nconst SYSTEM_PROMPT = `你是\"萌宠星球\"的 AI 宠物顾问,名叫\"萌萌\"。你的职责是:\n\n1. 品种识别与推荐:根据用户描述推荐合适的宠物品种\n2. 养护知识:提供喂养、美容、运动等方面的专业建议\n3. 健康问答:解答宠物健康相关问题(注意:严重问题建议就医)\n4. 行为训练:提供宠物行为训练建议\n5. 趣味冷知识:分享有趣的宠物知识\n\n回复要求:\n- 使用中文回答\n- 语气亲切友好,适当使用 emoji\n- 回答要专业但易懂\n- 涉及医疗问题时,提醒用户咨询专业兽医\n- 回答控制在 300 字以内`;\n\nrouter.post('/chat', aiRateLimit, async (req, res) => {\n try {\n console.log('[AI] 收到聊天请求');\n const { messages } = req.body;\n\n if (!messages || !Array.isArray(messages) || messages.length === 0) {\n return res.status(400).json({ code: 1001, message: '消息内容不能为空' });\n }\n\n if (!DEEPSEEK_API_KEY) {\n console.error('[AI] DEEPSEEK_API_KEY 未设置');\n return res.status(500).json({ code: 5000, message: 'AI 服务未配置,请在 .env 中设置 DEEPSEEK_API_KEY' });\n }\n\n console.log('[AI] API Key 已配置,正在调用 DeepSeek...');\n\n const apiMessages = [\n { role: 'system', content: SYSTEM_PROMPT },\n ...messages.map((m) => ({\n role: m.isUser ? 'user' : 'assistant',\n content: m.text,\n })),\n ];\n\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${DEEPSEEK_API_KEY}`,\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: apiMessages,\n max_tokens: 1024,\n temperature: 0.7,\n }),\n });\n\n if (!response.ok) {\n const errBody = await response.text();\n console.error('DeepSeek API error:', response.status, errBody);\n return res.status(502).json({ code: 5002, message: 'AI 服务响应异常,请稍后重试' });\n }\n\n const data = await response.json();\n const reply = data.choices?.[0]?.message?.content || '抱歉,我没有理解你的问题,请换个方式描述一下~';\n console.log('[AI] DeepSeek 响应成功,回复长度:', reply.length);\n\n return res.json({ code: 0, data: { reply, safetyNote: SAFETY_NOTE } });\n } catch (error) {\n console.error('AI chat error:', error);\n return res.status(500).json({ code: 5000, message: '服务器内部错误' });\n }\n});\n\nmodule.exports = router;\n"}}}}