UNPKG

ai-knowledge

Version:

ai-knowledge

150 lines (140 loc) 4.79 kB
const fs = require('fs'); const path = require('path'); const config = require('../config'); const { ensureDir } = require('../utils/fileUtils'); /** * 生成HTML搜索结果报告 */ function generateHtmlReport(results, query, options = {}) { const { loaderHistory = {}, title = 'Search Results', reportsDir = config.reports.path } = options; // 确保报告目录存在 ensureDir(reportsDir); const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); // 直接使用results作为结果数组,而不是假设它是一个包含结果的对象 const resultsArray = Array.isArray(results) ? results : []; const html = ` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>${title} - ${query}</title> <style> body { font-family: Arial, sans-serif; line-height: 1.6; max-width: 1200px; margin: 0 auto; padding: 20px; background: #f5f5f5; } .search-info { background: #fff; padding: 20px; border-radius: 5px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .result { background: #fff; padding: 20px; margin-bottom: 20px; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .metadata { font-size: 0.9em; color: #666; margin: 10px 0; padding: 10px; background: #f8f8f8; border-radius: 3px; } .score { font-weight: bold; color: #2a9d8f; } .source { color: #0066cc; text-decoration: none; } .content { margin-top: 10px; padding: 15px; background: #f9f9f9; border-radius: 3px; border-left: 4px solid #2a9d8f; } .source-tag { display: inline-block; padding: 3px 8px; border-radius: 12px; font-size: 0.8em; font-weight: bold; margin-right: 8px; } .url-tag { background: #2a9d8f; color: white; } .file-tag { background: #e76f51; color: white; } .dir-tag { background: #457b9d; color: white; } .content-text { white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word; } </style> </head> <body> <div class="search-info"> <h1>${title}</h1> <p><strong>查询:</strong> ${query}</p> <p><strong>时间:</strong> ${new Date().toLocaleString()}</p> <p><strong>结果数量:</strong> ${resultsArray.length}</p> </div> <div class="results"> ${resultsArray.map((result, index) => { // 确定来源类型 let sourceType = 'unknown'; let sourceTag = ''; if (result.metadata && result.metadata.source) { if (result.metadata.source.startsWith('http')) { sourceType = 'url'; sourceTag = '<span class="source-tag url-tag">URL</span>'; } else if (result.metadata.type === 'file') { sourceType = 'file'; sourceTag = '<span class="source-tag file-tag">文件</span>'; } else if (result.metadata.type === 'directory') { sourceType = 'directory'; sourceTag = '<span class="source-tag dir-tag">目录</span>'; } } return ` <div class="result"> <h2>${sourceTag}结果 ${index + 1}</h2> <div class="metadata"> <p><span class="score">相关度: ${result.score.toFixed(4) || '未知'}</span></p> <p>来源: ${sourceType === 'url' && result.metadata && result.metadata.source ? `<a class="source" href="${result.metadata.source}" target="_blank">${result.metadata.source}</a>` : (result.metadata && result.metadata.source ? result.metadata.source : '未知') }</p> ${result.metadata && result.metadata.filename ? `<p>文件名: ${result.metadata.filename}</p>` : ''} ${result.metadata && result.metadata.type ? `<p>类型: ${result.metadata.type}</p>` : ''} </div> <div class="content"> <pre class="content-text">${result.text || result.content || '无内容'}</pre> </div> </div> `; }).join('')} </div> </body> </html> `; const filename = `search-results-${timestamp}.html`; const filepath = path.join(reportsDir, filename); fs.writeFileSync(filepath, html); return filepath; } module.exports = { generateHtmlReport };