Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/bigcathakimi_kuankuantjblog.github.io.json

1 line
52 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "bigcathakimi/kuankuantjblog.github.io", "files": {"server/routes/ai-advanced.js": {"0a378508f768e8a0462a6cfeff024834597c6bef": {"t": 1785746008.423938, "n": 21660, "h": "e86d21c0257b8fcf", "c": "/**\n * AI大模型深度集成路由\n * 第六轮创新性功能 - AI Large Model Integration\n * \n * 功能模块:\n * 2.1 智能客服机器人\n * 2.2 内容自动生成\n * 2.3 智能代码审查\n * 2.4 多模态AI理解\n */\n\nconst express = require('express');\nconst router = express.Router();\nconst { body, validationResult } = require('express-validator');\nconst rateLimit = require('express-rate-limit');\n\n// AI服务提供商配置\nconst AI_PROVIDERS = {\n openai: {\n baseUrl: 'https://api.openai.com/v1',\n models: ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo', 'dall-e-3', 'whisper-1']\n },\n anthropic: {\n baseUrl: 'https://api.anthropic.com/v1',\n models: ['claude-3-opus', 'claude-3-sonnet', 'claude-3-haiku']\n },\n gemini: {\n baseUrl: 'https://generativelanguage.googleapis.com/v1',\n models: ['gemini-pro', 'gemini-pro-vision', 'gemini-ultra']\n },\n deepseek: {\n baseUrl: 'https://api.deepseek.com/v1',\n models: ['deepseek-chat', 'deepseek-coder']\n },\n siliconflow: {\n baseUrl: 'https://api.siliconflow.cn/v1',\n models: ['Qwen/Qwen2.5-72B-Instruct', 'deepseek-ai/DeepSeek-R1', 'Pro/deepseek-ai/DeepSeek-R1']\n }\n};\n\n// AI请求限流\nconst aiLimiter = rateLimit({\n windowMs: 1 * 60 * 1000, // 1分钟\n max: 20, // 每用户最多20次请求\n message: { error: 'AI服务调用过于频繁,请稍后再试' }\n});\n\n// 中间件:验证请求\nconst validateRequest = (req, res, next) => {\n const errors = validationResult(req);\n if (!errors.isEmpty()) {\n return res.status(400).json({ errors: errors.array() });\n }\n next();\n};\n\n// ==================== 2.1 智能客服机器人 ====================\n\n/**\n * 智能客服对话\n * POST /api/ai/chat\n */\nrouter.post('/chat', aiLimiter, [\n body('message').trim().isLength({ min: 1, max: 2000 }).withMessage('消息长度1-2000字符'),\n body('sessionId').optional().isString(),\n body('context').optional().isArray(),\n validateRequest\n], async (req, res) => {\n try {\n const { message, sessionId = `session_${Date.now()}`, context = [], provider = 'siliconflow' } = req.body;\n \n // 构建系统提示词\n const systemPrompt = `你是 \"Hakimi 的猫爬架\" 博客平台的AI助手,一个友好、专业的智能客服。\n\n平台功能:\n- 博客文章发布、阅读、评论\n- 用户等级系统和积分奖励\n- NFT铸造和代币经济\n- 实时协作编辑\n- 游戏化社交功能\n\n回复原则:\n1. 使用中文回复,语气友好亲切\n2. 回答要简洁明了,避免冗长\n3. 遇到技术问题提供具体解决步骤\n4. 不清楚的问题诚实告知,不要编造\n5. 适当使用emoji增加亲和力\n\n当前时间:${new Date().toLocaleString('zh-CN')}`;\n\n // 构建消息历史\n const messages = [\n { role: 'system', content: systemPrompt },\n ...context.slice(-10), // 保留最近10条上下文\n { role: 'user', content: message }\n ];\n\n // 调用AI模型\n const response = await callAIProvider(provider, messages, {\n temperature: 0.7,\n max_tokens: 2000\n });\n\n res.json({\n success: true,\n data: {\n reply: response.content,\n sessionId,\n suggestions: generateSuggestions(message, response.content),\n usedTokens: response.usage?.total_tokens || 0\n }\n });\n } catch (error) {\n console.error('AI Chat Error:', error);\n res.status(500).json({ error: 'AI服务暂时不可用', details: error.message });\n }\n});\n\n/**\n * 流式对话 (SSE)\n * GET /api/ai/chat/stream\n */\nrouter.get('/chat/stream', async (req, res) => {\n const { message, sessionId, provider = 'siliconflow' } = req.query;\n \n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n try {\n const systemPrompt = `你是博客平台的AI助手,请简洁友好地回答用户问题。`;\n const messages = [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: message }\n ];\n\n // 模拟流式响应\n const response = await callAIProvider(provider, messages, { stream: true });\n \n // 分批发送\n const chunks = response.content.split('');\n for (const chunk of chunks) {\n res.write(`data: ${JSON.stringify({ chunk, done: false })}\\n\\n`);\n await new Promise(r => setTimeout(r, 20));\n }\n \n res.write(`data: ${JSON.stringify({ done: true, sessionId })}\\n\\n`);\n res.end();\n } catch (error) {\n res.write(`data: ${JSON.stringify({ error: error.message })}\\n\\n`);\n res.end();\n }\n});\n\n/**\n * 常见问题智能回复\n * POST /api/ai/faq\n */\nrouter.post('/faq', async (req, res) => {\n const { question } = req.body;\n \n // 预设FAQ知识库\n const faqDatabase = {\n '如何发布文章': {\n answer: '点击顶部导航栏的\"写文章\"按钮,进入编辑器即可创作。支持Markdown格式和富文本编辑。',\n link: '/editor.html'\n },\n '如何获得积分': {\n answer: '每日签到、发布文章、获得点赞评论都可以赚取积分。连续签到还有额外奖励哦!',\n link: '/coins.html'\n },\n 'NFT是什么': {\n answer: 'NFT(非同质化代币)是区块链上的独特数字资产。您可以将文章铸造为NFT,获得永久数字所有权证明。',\n link: '/nft-guide.html'\n },\n '如何连接钱包': {\n answer: '在个人设置页面点击\"连接钱包\",支持MetaMask等主流钱包。连接后可进行NFT铸造和代币交易。',\n link: '/profile.html'\n }\n };\n\n // 语义匹配\n const matched = Object.entries(faqDatabase).find(([q]) => \n question.includes(q) || similarity(question, q) > 0.6\n );\n\n if (matched) {\n res.json({ success: true, data: matched[1], matched: true });\n } else {\n // 未匹配到,走AI生成\n const aiResponse = await callAIProvider('siliconflow', [\n { role: 'system', content: '回答用户关于博客平台的问题' },\n { role: 'user', content: question }\n ]);\n res.json({ success: true, data: { answer: aiResponse.content }, matched: false });\n }\n});\n\n// ==================== 2.2 内容自动生成 ====================\n\n/**\n * 文章标题生成\n * POST /api/ai/generate/title\n */\nrouter.post('/generate/title', aiLimiter, [\n body('content').trim().isLength({ min: 10 }).withMessage('内容至少需要10个字符'),\n validateRequest\n], async (req, res) => {\n try {\n const { content, count = 5 } = req.body;\n \n const prompt = `根据以下内容生成${count}个吸引人的文章标题:\n\n内容摘要:${content.substring(0, 1000)}\n\n要求:\n1. 标题要简洁有力,不超过20字\n2. 要有吸引力,能引起读者兴趣\n3. 符合中文阅读习惯\n4. 提供多种风格:专业型、趣味型、悬念型\n\n请直接返回标题列表,每行一个:`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ], { temperature: 0.8 });\n\n const titles = response.content.split('\\n')\n .map(t => t.replace(/^\\d+\\.\\s*/, '').trim())\n .filter(t => t.length > 0);\n\n res.json({ success: true, data: { titles: titles.slice(0, count) } });\n } catch (error) {\n res.status(500).json({ error: '生成失败', details: error.message });\n }\n});\n\n/**\n * 文章摘要生成\n * POST /api/ai/generate/summary\n */\nrouter.post('/generate/summary', aiLimiter, [\n body('content').trim().isLength({ min: 100 }).withMessage('内容至少需要100个字符'),\n validateRequest\n], async (req, res) => {\n try {\n const { content, maxLength = 200 } = req.body;\n \n const prompt = `请为以下文章生成摘要,限制在${maxLength}字以内:\n\n${content.substring(0, 3000)}\n\n要求:\n1. 突出核心观点和关键信息\n2. 语言流畅,逻辑清晰\n3. 不包含\"本文\"、\"作者\"等词,直接陈述要点`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ], { max_tokens: 500 });\n\n res.json({ success: true, data: { summary: response.content.trim() } });\n } catch (error) {\n res.status(500).json({ error: '生成失败', details: error.message });\n }\n});\n\n/**\n * 文章内容续写\n * POST /api/ai/generate/continue\n */\nrouter.post('/generate/continue', aiLimiter, [\n body('content').trim().isLength({ min: 50 }).withMessage('内容至少需要50个字符'),\n body('tone').optional().isIn(['professional', 'casual', 'humorous', 'academic']),\n validateRequest\n], async (req, res) => {\n try {\n const { content, tone = 'professional', wordCount = 300 } = req.body;\n \n const toneMap = {\n professional: '专业严谨',\n casual: '轻松随意',\n humorous: '幽默风趣',\n academic: '学术规范'\n };\n\n const prompt = `请根据以下内容续写文章,续写约${wordCount}字:\n\n已写内容:\n${content.substring(-500)}\n\n要求:\n1. 语气风格:${toneMap[tone]}\n2. 保持与上文的一致性\n3. 自然过渡,不生硬\n4. 丰富内容,添加具体细节或例子\n\n续写内容:`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ], { temperature: 0.7, max_tokens: 2000 });\n\n res.json({ success: true, data: { continuation: response.content.trim() } });\n } catch (error) {\n res.status(500).json({ error: '续写失败', details: error.message });\n }\n});\n\n/**\n * SEO优化建议\n * POST /api/ai/generate/seo\n */\nrouter.post('/generate/seo', aiLimiter, [\n body('title').trim().isLength({ min: 1 }),\n body('content').optional().isString(),\n validateRequest\n], async (req, res) => {\n try {\n const { title, content = '' } = req.body;\n \n const prompt = `请为以下文章提供SEO优化建议:\n\n标题:${title}\n内容预览:${content.substring(0, 500)}\n\n请提供以下建议:\n1. 优化后的标题(3个备选)\n2. 推荐的关键词(5-8个)\n3. Meta描述建议(150字以内)\n4. 内容结构优化建议\n5. 内链/外链建议`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n res.json({ success: true, data: { suggestions: response.content.trim() } });\n } catch (error) {\n res.status(500).json({ error: '分析失败', details: error.message });\n }\n});\n\n/**\n * 智能标签推荐\n * POST /api/ai/generate/tags\n */\nrouter.post('/generate/tags', aiLimiter, [\n body('content').trim().isLength({ min: 50 }),\n validateRequest\n], async (req, res) => {\n try {\n const { content, existingTags = [] } = req.body;\n \n const prompt = `请为以下内容推荐合适的标签:\n\n内容:${content.substring(0, 1500)}\n\n已有标签:${existingTags.join(', ')}\n\n要求:\n1. 推荐5-10个相关标签\n2. 包含热门标签和长尾标签\n3. 格式:#标签名\n4. 返回标签列表即可`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n const tags = response.content.match(/#[\\u4e00-\\u9fa5\\w]+/g) || [];\n \n res.json({ success: true, data: { \n tags: tags.map(t => t.replace('#', '')),\n categories: suggestCategories(content)\n }});\n } catch (error) {\n res.status(500).json({ error: '推荐失败', details: error.message });\n }\n});\n\n// ==================== 2.3 智能代码审查 ====================\n\n/**\n * 代码审查\n * POST /api/ai/code/review\n */\nrouter.post('/code/review', aiLimiter, [\n body('code').trim().isLength({ min: 10 }),\n body('language').optional().isString(),\n validateRequest\n], async (req, res) => {\n try {\n const { code, language = 'auto' } = req.body;\n \n const prompt = `请对以下代码进行专业审查:\n\n${language !== 'auto' ? `语言:${language}` : ''}\n\\`\\`\\`\n${code}\n\\`\\`\\`\n\n请从以下方面分析:\n1. 代码质量(可读性、可维护性)\n2. 潜在Bug和安全问题\n3. 性能优化建议\n4. 最佳实践建议\n5. 重构建议\n\n请以结构化格式返回:`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'system', content: '你是一位资深代码审查专家,擅长发现代码问题和提供改进建议。' },\n { role: 'user', content: prompt }\n ]);\n\n // 解析审查结果\n const review = parseCodeReview(response.content);\n\n res.json({ success: true, data: review });\n } catch (error) {\n res.status(500).json({ error: '审查失败', details: error.message });\n }\n});\n\n/**\n * 代码解释\n * POST /api/ai/code/explain\n */\nrouter.post('/code/explain', aiLimiter, [\n body('code').trim().isLength({ min: 1 }),\n validateRequest\n], async (req, res) => {\n try {\n const { code, detail = 'normal' } = req.body;\n \n const detailMap = {\n simple: '用简单语言解释这段代码的功能',\n normal: '详细解释代码逻辑和执行流程',\n deep: '深入分析代码原理,包括算法复杂度和设计模式'\n };\n\n const prompt = `${detailMap[detail]}:\n\n\\`\\`\\`\n${code}\n\\`\\`\\`\n\n要求:\n1. 逐行或分块解释\n2. 解释关键函数和变量\n3. 说明输入输出\n4. 添加注释示例`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n res.json({ success: true, data: { explanation: response.content.trim() } });\n } catch (error) {\n res.status(500).json({ error: '解释失败', details: error.message });\n }\n});\n\n/**\n * 代码转换\n * POST /api/ai/code/convert\n */\nrouter.post('/code/convert', aiLimiter, [\n body('code').trim().isLength({ min: 1 }),\n body('from').isString(),\n body('to').isString(),\n validateRequest\n], async (req, res) => {\n try {\n const { code, from, to } = req.body;\n \n const prompt = `请将以下${from}代码转换为${to}代码:\n\n${from}代码:\n\\`\\`\\`\n${code}\n\\`\\`\\`\n\n要求:\n1. 保持功能一致\n2. 使用目标语言的最佳实践\n3. 添加必要的注释\n4. 处理语言差异(如语法特性)\n\n转换后的${to}代码:`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n // 提取代码块\n const codeMatch = response.content.match(/```[\\w]*\\n?([\\s\\S]*?)```/);\n const convertedCode = codeMatch ? codeMatch[1].trim() : response.content.trim();\n\n res.json({ success: true, data: { \n convertedCode,\n from,\n to,\n notes: extractConversionNotes(response.content)\n }});\n } catch (error) {\n res.status(500).json({ error: '转换失败', details: error.message });\n }\n});\n\n/**\n * 代码优化\n * POST /api/ai/code/optimize\n */\nrouter.post('/code/optimize', aiLimiter, [\n body('code').trim().isLength({ min: 1 }),\n body('goal').optional().isIn(['performance', 'readability', 'memory', 'all']),\n validateRequest\n], async (req, res) => {\n try {\n const { code, goal = 'all' } = req.body;\n \n const goalMap = {\n performance: '优化执行性能',\n readability: '提高可读性',\n memory: '优化内存使用',\n all: '全面优化(性能、可读性、内存)'\n };\n\n const prompt = `请对以下代码进行${goalMap[goal]}:\n\n\\`\\`\\`\n${code}\n\\`\\`\\`\n\n要求:\n1. 提供优化后的完整代码\n2. 列出具体优化点\n3. 预估性能提升\n4. 说明适用场景`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n res.json({ success: true, data: { \n optimizedCode: extractCodeBlock(response.content),\n explanation: response.content\n }});\n } catch (error) {\n res.status(500).json({ error: '优化失败', details: error.message });\n }\n});\n\n// ==================== 2.4 多模态AI理解 ====================\n\n/**\n * 图像描述生成\n * POST /api/ai/vision/describe\n */\nrouter.post('/vision/describe', aiLimiter, [\n body('imageUrl').isURL(),\n validateRequest\n], async (req, res) => {\n try {\n const { imageUrl, detail = 'normal' } = req.body;\n \n // 这里集成多模态模型(如GPT-4V、Gemini Pro Vision)\n const response = await callMultimodalAI('vision', {\n image: imageUrl,\n prompt: detail === 'detailed' \n ? '详细描述这张图片的所有细节,包括主体、背景、色彩、氛围等'\n : '简要描述这张图片的内容'\n });\n\n res.json({ success: true, data: {\n description: response.description,\n tags: response.tags || [],\n colors: response.colors || [],\n objects: response.objects || []\n }});\n } catch (error) {\n res.status(500).json({ error: '图像分析失败', details: error.message });\n }\n});\n\n/**\n * OCR文字识别\n * POST /api/ai/vision/ocr\n */\nrouter.post('/vision/ocr', aiLimiter, [\n body('imageUrl').isURL(),\n validateRequest\n], async (req, res) => {\n try {\n const { imageUrl } = req.body;\n \n // 模拟OCR功能\n const response = await callMultimodalAI('ocr', { image: imageUrl });\n\n res.json({ success: true, data: {\n text: response.text,\n blocks: response.blocks || [], // 分块识别结果\n confidence: response.confidence || 0\n }});\n } catch (error) {\n res.status(500).json({ error: 'OCR识别失败', details: error.message });\n }\n});\n\n/**\n * 图像生成 (Text to Image)\n * POST /api/ai/image/generate\n */\nrouter.post('/image/generate', aiLimiter, [\n body('prompt').trim().isLength({ min: 1, max: 1000 }),\n validateRequest\n], async (req, res) => {\n try {\n const { prompt, size = '1024x1024', style = 'vivid' } = req.body;\n \n // 优化提示词\n const enhancedPrompt = await enhanceImagePrompt(prompt);\n \n // 调用图像生成API\n const imageUrl = await generateImage(enhancedPrompt, { size, style });\n\n res.json({ success: true, data: {\n imageUrl,\n prompt: enhancedPrompt,\n originalPrompt: prompt,\n size,\n style\n }});\n } catch (error) {\n res.status(500).json({ error: '图像生成失败', details: error.message });\n }\n});\n\n/**\n * 语音转文字\n * POST /api/ai/audio/transcribe\n */\nrouter.post('/audio/transcribe', aiLimiter, async (req, res) => {\n try {\n // 处理音频文件上传和转录\n const { audioUrl, language = 'zh' } = req.body;\n \n const transcript = await transcribeAudio(audioUrl, language);\n\n res.json({ success: true, data: {\n text: transcript.text,\n segments: transcript.segments || [],\n language: transcript.language\n }});\n } catch (error) {\n res.status(500).json({ error: '转录失败', details: error.message });\n }\n});\n\n/**\n * 文字转语音\n * POST /api/ai/audio/synthesize\n */\nrouter.post('/audio/synthesize', aiLimiter, [\n body('text').trim().isLength({ min: 1, max: 5000 }),\n validateRequest\n], async (req, res) => {\n try {\n const { text, voice = 'alloy', speed = 1.0 } = req.body;\n \n const audioUrl = await synthesizeSpeech(text, { voice, speed });\n\n res.json({ success: true, data: { audioUrl, duration: text.length * 0.3 } });\n } catch (error) {\n res.status(500).json({ error: '语音合成失败', details: error.message });\n }\n});\n\n// ==================== 辅助函数 ====================\n\n/**\n * 调用AI服务提供商\n */\nasync function callAIProvider(provider, messages, options = {}) {\n const config = AI_PROVIDERS[provider];\n if (!config) throw new Error(`Unknown provider: ${provider}`);\n\n const apiKey = process.env[`${provider.toUpperCase()}_API_KEY`];\n if (!apiKey) throw new Error(`API key not configured for ${provider}`);\n\n const model = options.model || config.models[0];\n \n // 构建请求体\n const requestBody = {\n model,\n messages,\n temperature: options.temperature ?? 0.7,\n max_tokens: options.max_tokens ?? 2000,\n stream: options.stream ?? false\n };\n\n // 发送请求\n const response = await fetch(`${config.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`\n },\n body: JSON.stringify(requestBody)\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`AI API Error: ${error}`);\n }\n\n const data = await response.json();\n return {\n content: data.choices[0].message.content,\n usage: data.usage\n };\n}\n\n/**\n * 调用多模态AI\n */\nasync function callMultimodalAI(task, params) {\n // 这里集成实际的多模态API\n // 返回模拟数据\n const mockResponses = {\n vision: {\n description: '这是一张美丽的自然风景照片,展示了一片青山绿水...',\n tags: ['自然', '风景', '山水', '旅游'],\n colors: ['#2E7D32', '#1976D2', '#FFFFFF'],\n objects: ['mountain', 'water', 'sky']\n },\n ocr: {\n text: '识别的文字内容...',\n blocks: [],\n confidence: 0.95\n }\n };\n \n return mockResponses[task] || {};\n}\n\n/**\n * 生成图像\n */\nasync function generateImage(prompt, options) {\n // 集成DALL-E、Midjourney API或Stable Diffusion\n // 返回模拟URL\n return `https://picsum.photos/seed/${Date.now()}/${options.size.replace('x', '/')}`;\n}\n\n/**\n * 音频转录\n */\nasync function transcribeAudio(audioUrl, language) {\n // 集成Whisper API\n return { text: '转录的文本内容...', segments: [], language };\n}\n\n/**\n * 语音合成\n */\nasync function synthesizeSpeech(text, options) {\n // 集成TTS API\n return `https://example.com/audio/${Date.now()}.mp3`;\n}\n\n/**\n * 优化图像生成提示词\n */\nasync function enhanceImagePrompt(prompt) {\n const enhancePrompt = `优化以下图像生成提示词,使其更具体、更有画面感:\n\n原提示词:${prompt}\n\n优化要求:\n1. 添加风格描述(写实、动漫、油画等)\n2. 添加光影效果描述\n3. 添加质量修饰词(4K、 masterpiece等)\n4. 保持原意的同时丰富细节\n\n优化后的提示词:`;\n\n try {\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: enhancePrompt }\n ], { max_tokens: 500 });\n return response.content.trim();\n } catch {\n return prompt;\n }\n}\n\n/**\n * 生成智能建议\n */\nfunction generateSuggestions(userMessage, aiReply) {\n // 基于对话内容生成后续问题建议\n const commonSuggestions = [\n '能详细说明一下吗?',\n '还有其他相关功能吗?',\n '如何开始使用这个功能?'\n ];\n return commonSuggestions.slice(0, 3);\n}\n\n/**\n * 计算文本相似度\n */\nfunction similarity(s1, s2) {\n // 简单的Jaccard相似度\n const set1 = new Set(s1.split(''));\n const set2 = new Set(s2.split(''));\n const intersection = new Set([...set1].filter(x => set2.has(x)));\n const union = new Set([...set1, ...set2]);\n return intersection.size / union.size;\n}\n\n/**\n * 建议文章分类\n */\nfunction suggestCategories(content) {\n const categories = [];\n const keywords = {\n '技术': ['代码', '编程', '开发', '算法', '框架'],\n '生活': ['日常', '心情', '旅行', '美食'],\n '学习': ['教程', '笔记', '知识', '学习'],\n '创作': ['小说', '故事', '诗歌', '散文']\n };\n \n for (const [cat, words] of Object.entries(keywords)) {\n if (words.some(w => content.includes(w))) {\n categories.push(cat);\n }\n }\n \n return categories;\n}\n\n/**\n * 解析代码审查结果\n */\nfunction parseCodeReview(content) {\n return {\n overall: content,\n score: Math.floor(Math.random() * 30) + 70, // 模拟评分\n issues: [],\n suggestions: []\n };\n}\n\n/**\n * 提取代码块\n */\nfunction extractCodeBlock(content) {\n const match = content.match(/```[\\w]*\\n?([\\s\\S]*?)```/);\n return match ? match[1].trim() : content;\n}\n\n/**\n * 提取转换说明\n */\nfunction extractConversionNotes(content) {\n const notes = content.replace(/```[\\w]*\\n?[\\s\\S]*?```/g, '').trim();\n return notes;\n}\n\nmodule.exports = router;\n"}, "57718ba2ac81745e8379c25bfd0ca7f87d0e99e9": {"t": 1785758739.875812, "n": 21660, "h": "e86d21c0257b8fcf", "c": "/**\n * AI大模型深度集成路由\n * 第六轮创新性功能 - AI Large Model Integration\n * \n * 功能模块:\n * 2.1 智能客服机器人\n * 2.2 内容自动生成\n * 2.3 智能代码审查\n * 2.4 多模态AI理解\n */\n\nconst express = require('express');\nconst router = express.Router();\nconst { body, validationResult } = require('express-validator');\nconst rateLimit = require('express-rate-limit');\n\n// AI服务提供商配置\nconst AI_PROVIDERS = {\n openai: {\n baseUrl: 'https://api.openai.com/v1',\n models: ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo', 'dall-e-3', 'whisper-1']\n },\n anthropic: {\n baseUrl: 'https://api.anthropic.com/v1',\n models: ['claude-3-opus', 'claude-3-sonnet', 'claude-3-haiku']\n },\n gemini: {\n baseUrl: 'https://generativelanguage.googleapis.com/v1',\n models: ['gemini-pro', 'gemini-pro-vision', 'gemini-ultra']\n },\n deepseek: {\n baseUrl: 'https://api.deepseek.com/v1',\n models: ['deepseek-chat', 'deepseek-coder']\n },\n siliconflow: {\n baseUrl: 'https://api.siliconflow.cn/v1',\n models: ['Qwen/Qwen2.5-72B-Instruct', 'deepseek-ai/DeepSeek-R1', 'Pro/deepseek-ai/DeepSeek-R1']\n }\n};\n\n// AI请求限流\nconst aiLimiter = rateLimit({\n windowMs: 1 * 60 * 1000, // 1分钟\n max: 20, // 每用户最多20次请求\n message: { error: 'AI服务调用过于频繁,请稍后再试' }\n});\n\n// 中间件:验证请求\nconst validateRequest = (req, res, next) => {\n const errors = validationResult(req);\n if (!errors.isEmpty()) {\n return res.status(400).json({ errors: errors.array() });\n }\n next();\n};\n\n// ==================== 2.1 智能客服机器人 ====================\n\n/**\n * 智能客服对话\n * POST /api/ai/chat\n */\nrouter.post('/chat', aiLimiter, [\n body('message').trim().isLength({ min: 1, max: 2000 }).withMessage('消息长度1-2000字符'),\n body('sessionId').optional().isString(),\n body('context').optional().isArray(),\n validateRequest\n], async (req, res) => {\n try {\n const { message, sessionId = `session_${Date.now()}`, context = [], provider = 'siliconflow' } = req.body;\n \n // 构建系统提示词\n const systemPrompt = `你是 \"Hakimi 的猫爬架\" 博客平台的AI助手,一个友好、专业的智能客服。\n\n平台功能:\n- 博客文章发布、阅读、评论\n- 用户等级系统和积分奖励\n- NFT铸造和代币经济\n- 实时协作编辑\n- 游戏化社交功能\n\n回复原则:\n1. 使用中文回复,语气友好亲切\n2. 回答要简洁明了,避免冗长\n3. 遇到技术问题提供具体解决步骤\n4. 不清楚的问题诚实告知,不要编造\n5. 适当使用emoji增加亲和力\n\n当前时间:${new Date().toLocaleString('zh-CN')}`;\n\n // 构建消息历史\n const messages = [\n { role: 'system', content: systemPrompt },\n ...context.slice(-10), // 保留最近10条上下文\n { role: 'user', content: message }\n ];\n\n // 调用AI模型\n const response = await callAIProvider(provider, messages, {\n temperature: 0.7,\n max_tokens: 2000\n });\n\n res.json({\n success: true,\n data: {\n reply: response.content,\n sessionId,\n suggestions: generateSuggestions(message, response.content),\n usedTokens: response.usage?.total_tokens || 0\n }\n });\n } catch (error) {\n console.error('AI Chat Error:', error);\n res.status(500).json({ error: 'AI服务暂时不可用', details: error.message });\n }\n});\n\n/**\n * 流式对话 (SSE)\n * GET /api/ai/chat/stream\n */\nrouter.get('/chat/stream', async (req, res) => {\n const { message, sessionId, provider = 'siliconflow' } = req.query;\n \n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n try {\n const systemPrompt = `你是博客平台的AI助手,请简洁友好地回答用户问题。`;\n const messages = [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: message }\n ];\n\n // 模拟流式响应\n const response = await callAIProvider(provider, messages, { stream: true });\n \n // 分批发送\n const chunks = response.content.split('');\n for (const chunk of chunks) {\n res.write(`data: ${JSON.stringify({ chunk, done: false })}\\n\\n`);\n await new Promise(r => setTimeout(r, 20));\n }\n \n res.write(`data: ${JSON.stringify({ done: true, sessionId })}\\n\\n`);\n res.end();\n } catch (error) {\n res.write(`data: ${JSON.stringify({ error: error.message })}\\n\\n`);\n res.end();\n }\n});\n\n/**\n * 常见问题智能回复\n * POST /api/ai/faq\n */\nrouter.post('/faq', async (req, res) => {\n const { question } = req.body;\n \n // 预设FAQ知识库\n const faqDatabase = {\n '如何发布文章': {\n answer: '点击顶部导航栏的\"写文章\"按钮,进入编辑器即可创作。支持Markdown格式和富文本编辑。',\n link: '/editor.html'\n },\n '如何获得积分': {\n answer: '每日签到、发布文章、获得点赞评论都可以赚取积分。连续签到还有额外奖励哦!',\n link: '/coins.html'\n },\n 'NFT是什么': {\n answer: 'NFT(非同质化代币)是区块链上的独特数字资产。您可以将文章铸造为NFT,获得永久数字所有权证明。',\n link: '/nft-guide.html'\n },\n '如何连接钱包': {\n answer: '在个人设置页面点击\"连接钱包\",支持MetaMask等主流钱包。连接后可进行NFT铸造和代币交易。',\n link: '/profile.html'\n }\n };\n\n // 语义匹配\n const matched = Object.entries(faqDatabase).find(([q]) => \n question.includes(q) || similarity(question, q) > 0.6\n );\n\n if (matched) {\n res.json({ success: true, data: matched[1], matched: true });\n } else {\n // 未匹配到,走AI生成\n const aiResponse = await callAIProvider('siliconflow', [\n { role: 'system', content: '回答用户关于博客平台的问题' },\n { role: 'user', content: question }\n ]);\n res.json({ success: true, data: { answer: aiResponse.content }, matched: false });\n }\n});\n\n// ==================== 2.2 内容自动生成 ====================\n\n/**\n * 文章标题生成\n * POST /api/ai/generate/title\n */\nrouter.post('/generate/title', aiLimiter, [\n body('content').trim().isLength({ min: 10 }).withMessage('内容至少需要10个字符'),\n validateRequest\n], async (req, res) => {\n try {\n const { content, count = 5 } = req.body;\n \n const prompt = `根据以下内容生成${count}个吸引人的文章标题:\n\n内容摘要:${content.substring(0, 1000)}\n\n要求:\n1. 标题要简洁有力,不超过20字\n2. 要有吸引力,能引起读者兴趣\n3. 符合中文阅读习惯\n4. 提供多种风格:专业型、趣味型、悬念型\n\n请直接返回标题列表,每行一个:`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ], { temperature: 0.8 });\n\n const titles = response.content.split('\\n')\n .map(t => t.replace(/^\\d+\\.\\s*/, '').trim())\n .filter(t => t.length > 0);\n\n res.json({ success: true, data: { titles: titles.slice(0, count) } });\n } catch (error) {\n res.status(500).json({ error: '生成失败', details: error.message });\n }\n});\n\n/**\n * 文章摘要生成\n * POST /api/ai/generate/summary\n */\nrouter.post('/generate/summary', aiLimiter, [\n body('content').trim().isLength({ min: 100 }).withMessage('内容至少需要100个字符'),\n validateRequest\n], async (req, res) => {\n try {\n const { content, maxLength = 200 } = req.body;\n \n const prompt = `请为以下文章生成摘要,限制在${maxLength}字以内:\n\n${content.substring(0, 3000)}\n\n要求:\n1. 突出核心观点和关键信息\n2. 语言流畅,逻辑清晰\n3. 不包含\"本文\"、\"作者\"等词,直接陈述要点`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ], { max_tokens: 500 });\n\n res.json({ success: true, data: { summary: response.content.trim() } });\n } catch (error) {\n res.status(500).json({ error: '生成失败', details: error.message });\n }\n});\n\n/**\n * 文章内容续写\n * POST /api/ai/generate/continue\n */\nrouter.post('/generate/continue', aiLimiter, [\n body('content').trim().isLength({ min: 50 }).withMessage('内容至少需要50个字符'),\n body('tone').optional().isIn(['professional', 'casual', 'humorous', 'academic']),\n validateRequest\n], async (req, res) => {\n try {\n const { content, tone = 'professional', wordCount = 300 } = req.body;\n \n const toneMap = {\n professional: '专业严谨',\n casual: '轻松随意',\n humorous: '幽默风趣',\n academic: '学术规范'\n };\n\n const prompt = `请根据以下内容续写文章,续写约${wordCount}字:\n\n已写内容:\n${content.substring(-500)}\n\n要求:\n1. 语气风格:${toneMap[tone]}\n2. 保持与上文的一致性\n3. 自然过渡,不生硬\n4. 丰富内容,添加具体细节或例子\n\n续写内容:`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ], { temperature: 0.7, max_tokens: 2000 });\n\n res.json({ success: true, data: { continuation: response.content.trim() } });\n } catch (error) {\n res.status(500).json({ error: '续写失败', details: error.message });\n }\n});\n\n/**\n * SEO优化建议\n * POST /api/ai/generate/seo\n */\nrouter.post('/generate/seo', aiLimiter, [\n body('title').trim().isLength({ min: 1 }),\n body('content').optional().isString(),\n validateRequest\n], async (req, res) => {\n try {\n const { title, content = '' } = req.body;\n \n const prompt = `请为以下文章提供SEO优化建议:\n\n标题:${title}\n内容预览:${content.substring(0, 500)}\n\n请提供以下建议:\n1. 优化后的标题(3个备选)\n2. 推荐的关键词(5-8个)\n3. Meta描述建议(150字以内)\n4. 内容结构优化建议\n5. 内链/外链建议`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n res.json({ success: true, data: { suggestions: response.content.trim() } });\n } catch (error) {\n res.status(500).json({ error: '分析失败', details: error.message });\n }\n});\n\n/**\n * 智能标签推荐\n * POST /api/ai/generate/tags\n */\nrouter.post('/generate/tags', aiLimiter, [\n body('content').trim().isLength({ min: 50 }),\n validateRequest\n], async (req, res) => {\n try {\n const { content, existingTags = [] } = req.body;\n \n const prompt = `请为以下内容推荐合适的标签:\n\n内容:${content.substring(0, 1500)}\n\n已有标签:${existingTags.join(', ')}\n\n要求:\n1. 推荐5-10个相关标签\n2. 包含热门标签和长尾标签\n3. 格式:#标签名\n4. 返回标签列表即可`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n const tags = response.content.match(/#[\\u4e00-\\u9fa5\\w]+/g) || [];\n \n res.json({ success: true, data: { \n tags: tags.map(t => t.replace('#', '')),\n categories: suggestCategories(content)\n }});\n } catch (error) {\n res.status(500).json({ error: '推荐失败', details: error.message });\n }\n});\n\n// ==================== 2.3 智能代码审查 ====================\n\n/**\n * 代码审查\n * POST /api/ai/code/review\n */\nrouter.post('/code/review', aiLimiter, [\n body('code').trim().isLength({ min: 10 }),\n body('language').optional().isString(),\n validateRequest\n], async (req, res) => {\n try {\n const { code, language = 'auto' } = req.body;\n \n const prompt = `请对以下代码进行专业审查:\n\n${language !== 'auto' ? `语言:${language}` : ''}\n\\`\\`\\`\n${code}\n\\`\\`\\`\n\n请从以下方面分析:\n1. 代码质量(可读性、可维护性)\n2. 潜在Bug和安全问题\n3. 性能优化建议\n4. 最佳实践建议\n5. 重构建议\n\n请以结构化格式返回:`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'system', content: '你是一位资深代码审查专家,擅长发现代码问题和提供改进建议。' },\n { role: 'user', content: prompt }\n ]);\n\n // 解析审查结果\n const review = parseCodeReview(response.content);\n\n res.json({ success: true, data: review });\n } catch (error) {\n res.status(500).json({ error: '审查失败', details: error.message });\n }\n});\n\n/**\n * 代码解释\n * POST /api/ai/code/explain\n */\nrouter.post('/code/explain', aiLimiter, [\n body('code').trim().isLength({ min: 1 }),\n validateRequest\n], async (req, res) => {\n try {\n const { code, detail = 'normal' } = req.body;\n \n const detailMap = {\n simple: '用简单语言解释这段代码的功能',\n normal: '详细解释代码逻辑和执行流程',\n deep: '深入分析代码原理,包括算法复杂度和设计模式'\n };\n\n const prompt = `${detailMap[detail]}:\n\n\\`\\`\\`\n${code}\n\\`\\`\\`\n\n要求:\n1. 逐行或分块解释\n2. 解释关键函数和变量\n3. 说明输入输出\n4. 添加注释示例`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n res.json({ success: true, data: { explanation: response.content.trim() } });\n } catch (error) {\n res.status(500).json({ error: '解释失败', details: error.message });\n }\n});\n\n/**\n * 代码转换\n * POST /api/ai/code/convert\n */\nrouter.post('/code/convert', aiLimiter, [\n body('code').trim().isLength({ min: 1 }),\n body('from').isString(),\n body('to').isString(),\n validateRequest\n], async (req, res) => {\n try {\n const { code, from, to } = req.body;\n \n const prompt = `请将以下${from}代码转换为${to}代码:\n\n${from}代码:\n\\`\\`\\`\n${code}\n\\`\\`\\`\n\n要求:\n1. 保持功能一致\n2. 使用目标语言的最佳实践\n3. 添加必要的注释\n4. 处理语言差异(如语法特性)\n\n转换后的${to}代码:`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n // 提取代码块\n const codeMatch = response.content.match(/```[\\w]*\\n?([\\s\\S]*?)```/);\n const convertedCode = codeMatch ? codeMatch[1].trim() : response.content.trim();\n\n res.json({ success: true, data: { \n convertedCode,\n from,\n to,\n notes: extractConversionNotes(response.content)\n }});\n } catch (error) {\n res.status(500).json({ error: '转换失败', details: error.message });\n }\n});\n\n/**\n * 代码优化\n * POST /api/ai/code/optimize\n */\nrouter.post('/code/optimize', aiLimiter, [\n body('code').trim().isLength({ min: 1 }),\n body('goal').optional().isIn(['performance', 'readability', 'memory', 'all']),\n validateRequest\n], async (req, res) => {\n try {\n const { code, goal = 'all' } = req.body;\n \n const goalMap = {\n performance: '优化执行性能',\n readability: '提高可读性',\n memory: '优化内存使用',\n all: '全面优化(性能、可读性、内存)'\n };\n\n const prompt = `请对以下代码进行${goalMap[goal]}:\n\n\\`\\`\\`\n${code}\n\\`\\`\\`\n\n要求:\n1. 提供优化后的完整代码\n2. 列出具体优化点\n3. 预估性能提升\n4. 说明适用场景`;\n\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: prompt }\n ]);\n\n res.json({ success: true, data: { \n optimizedCode: extractCodeBlock(response.content),\n explanation: response.content\n }});\n } catch (error) {\n res.status(500).json({ error: '优化失败', details: error.message });\n }\n});\n\n// ==================== 2.4 多模态AI理解 ====================\n\n/**\n * 图像描述生成\n * POST /api/ai/vision/describe\n */\nrouter.post('/vision/describe', aiLimiter, [\n body('imageUrl').isURL(),\n validateRequest\n], async (req, res) => {\n try {\n const { imageUrl, detail = 'normal' } = req.body;\n \n // 这里集成多模态模型(如GPT-4V、Gemini Pro Vision)\n const response = await callMultimodalAI('vision', {\n image: imageUrl,\n prompt: detail === 'detailed' \n ? '详细描述这张图片的所有细节,包括主体、背景、色彩、氛围等'\n : '简要描述这张图片的内容'\n });\n\n res.json({ success: true, data: {\n description: response.description,\n tags: response.tags || [],\n colors: response.colors || [],\n objects: response.objects || []\n }});\n } catch (error) {\n res.status(500).json({ error: '图像分析失败', details: error.message });\n }\n});\n\n/**\n * OCR文字识别\n * POST /api/ai/vision/ocr\n */\nrouter.post('/vision/ocr', aiLimiter, [\n body('imageUrl').isURL(),\n validateRequest\n], async (req, res) => {\n try {\n const { imageUrl } = req.body;\n \n // 模拟OCR功能\n const response = await callMultimodalAI('ocr', { image: imageUrl });\n\n res.json({ success: true, data: {\n text: response.text,\n blocks: response.blocks || [], // 分块识别结果\n confidence: response.confidence || 0\n }});\n } catch (error) {\n res.status(500).json({ error: 'OCR识别失败', details: error.message });\n }\n});\n\n/**\n * 图像生成 (Text to Image)\n * POST /api/ai/image/generate\n */\nrouter.post('/image/generate', aiLimiter, [\n body('prompt').trim().isLength({ min: 1, max: 1000 }),\n validateRequest\n], async (req, res) => {\n try {\n const { prompt, size = '1024x1024', style = 'vivid' } = req.body;\n \n // 优化提示词\n const enhancedPrompt = await enhanceImagePrompt(prompt);\n \n // 调用图像生成API\n const imageUrl = await generateImage(enhancedPrompt, { size, style });\n\n res.json({ success: true, data: {\n imageUrl,\n prompt: enhancedPrompt,\n originalPrompt: prompt,\n size,\n style\n }});\n } catch (error) {\n res.status(500).json({ error: '图像生成失败', details: error.message });\n }\n});\n\n/**\n * 语音转文字\n * POST /api/ai/audio/transcribe\n */\nrouter.post('/audio/transcribe', aiLimiter, async (req, res) => {\n try {\n // 处理音频文件上传和转录\n const { audioUrl, language = 'zh' } = req.body;\n \n const transcript = await transcribeAudio(audioUrl, language);\n\n res.json({ success: true, data: {\n text: transcript.text,\n segments: transcript.segments || [],\n language: transcript.language\n }});\n } catch (error) {\n res.status(500).json({ error: '转录失败', details: error.message });\n }\n});\n\n/**\n * 文字转语音\n * POST /api/ai/audio/synthesize\n */\nrouter.post('/audio/synthesize', aiLimiter, [\n body('text').trim().isLength({ min: 1, max: 5000 }),\n validateRequest\n], async (req, res) => {\n try {\n const { text, voice = 'alloy', speed = 1.0 } = req.body;\n \n const audioUrl = await synthesizeSpeech(text, { voice, speed });\n\n res.json({ success: true, data: { audioUrl, duration: text.length * 0.3 } });\n } catch (error) {\n res.status(500).json({ error: '语音合成失败', details: error.message });\n }\n});\n\n// ==================== 辅助函数 ====================\n\n/**\n * 调用AI服务提供商\n */\nasync function callAIProvider(provider, messages, options = {}) {\n const config = AI_PROVIDERS[provider];\n if (!config) throw new Error(`Unknown provider: ${provider}`);\n\n const apiKey = process.env[`${provider.toUpperCase()}_API_KEY`];\n if (!apiKey) throw new Error(`API key not configured for ${provider}`);\n\n const model = options.model || config.models[0];\n \n // 构建请求体\n const requestBody = {\n model,\n messages,\n temperature: options.temperature ?? 0.7,\n max_tokens: options.max_tokens ?? 2000,\n stream: options.stream ?? false\n };\n\n // 发送请求\n const response = await fetch(`${config.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`\n },\n body: JSON.stringify(requestBody)\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`AI API Error: ${error}`);\n }\n\n const data = await response.json();\n return {\n content: data.choices[0].message.content,\n usage: data.usage\n };\n}\n\n/**\n * 调用多模态AI\n */\nasync function callMultimodalAI(task, params) {\n // 这里集成实际的多模态API\n // 返回模拟数据\n const mockResponses = {\n vision: {\n description: '这是一张美丽的自然风景照片,展示了一片青山绿水...',\n tags: ['自然', '风景', '山水', '旅游'],\n colors: ['#2E7D32', '#1976D2', '#FFFFFF'],\n objects: ['mountain', 'water', 'sky']\n },\n ocr: {\n text: '识别的文字内容...',\n blocks: [],\n confidence: 0.95\n }\n };\n \n return mockResponses[task] || {};\n}\n\n/**\n * 生成图像\n */\nasync function generateImage(prompt, options) {\n // 集成DALL-E、Midjourney API或Stable Diffusion\n // 返回模拟URL\n return `https://picsum.photos/seed/${Date.now()}/${options.size.replace('x', '/')}`;\n}\n\n/**\n * 音频转录\n */\nasync function transcribeAudio(audioUrl, language) {\n // 集成Whisper API\n return { text: '转录的文本内容...', segments: [], language };\n}\n\n/**\n * 语音合成\n */\nasync function synthesizeSpeech(text, options) {\n // 集成TTS API\n return `https://example.com/audio/${Date.now()}.mp3`;\n}\n\n/**\n * 优化图像生成提示词\n */\nasync function enhanceImagePrompt(prompt) {\n const enhancePrompt = `优化以下图像生成提示词,使其更具体、更有画面感:\n\n原提示词:${prompt}\n\n优化要求:\n1. 添加风格描述(写实、动漫、油画等)\n2. 添加光影效果描述\n3. 添加质量修饰词(4K、 masterpiece等)\n4. 保持原意的同时丰富细节\n\n优化后的提示词:`;\n\n try {\n const response = await callAIProvider('siliconflow', [\n { role: 'user', content: enhancePrompt }\n ], { max_tokens: 500 });\n return response.content.trim();\n } catch {\n return prompt;\n }\n}\n\n/**\n * 生成智能建议\n */\nfunction generateSuggestions(userMessage, aiReply) {\n // 基于对话内容生成后续问题建议\n const commonSuggestions = [\n '能详细说明一下吗?',\n '还有其他相关功能吗?',\n '如何开始使用这个功能?'\n ];\n return commonSuggestions.slice(0, 3);\n}\n\n/**\n * 计算文本相似度\n */\nfunction similarity(s1, s2) {\n // 简单的Jaccard相似度\n const set1 = new Set(s1.split(''));\n const set2 = new Set(s2.split(''));\n const intersection = new Set([...set1].filter(x => set2.has(x)));\n const union = new Set([...set1, ...set2]);\n return intersection.size / union.size;\n}\n\n/**\n * 建议文章分类\n */\nfunction suggestCategories(content) {\n const categories = [];\n const keywords = {\n '技术': ['代码', '编程', '开发', '算法', '框架'],\n '生活': ['日常', '心情', '旅行', '美食'],\n '学习': ['教程', '笔记', '知识', '学习'],\n '创作': ['小说', '故事', '诗歌', '散文']\n };\n \n for (const [cat, words] of Object.entries(keywords)) {\n if (words.some(w => content.includes(w))) {\n categories.push(cat);\n }\n }\n \n return categories;\n}\n\n/**\n * 解析代码审查结果\n */\nfunction parseCodeReview(content) {\n return {\n overall: content,\n score: Math.floor(Math.random() * 30) + 70, // 模拟评分\n issues: [],\n suggestions: []\n };\n}\n\n/**\n * 提取代码块\n */\nfunction extractCodeBlock(content) {\n const match = content.match(/```[\\w]*\\n?([\\s\\S]*?)```/);\n return match ? match[1].trim() : content;\n}\n\n/**\n * 提取转换说明\n */\nfunction extractConversionNotes(content) {\n const notes = content.replace(/```[\\w]*\\n?[\\s\\S]*?```/g, '').trim();\n return notes;\n}\n\nmodule.exports = router;\n"}}}}