Update server.js via upload script - 2026-07-29 11:19:26

This commit is contained in:
mike 2026-07-29 11:19:47 +08:00
parent 0808063a2e
commit 857b2d4378
1 changed files with 17 additions and 4 deletions

View File

@ -613,9 +613,11 @@ app.post('/api/ai/parse-catalog', requireAuth, aiLimiter, (req, res) => {
try {
tmpDir = fs.mkdtempSync(path.join(OCR_TMP_ROOT, 'catalog-ocr-'));
const imagePaths = [];
const htmlTextParts = []; // HTML文件不用OCR直接读文字内容保留表格标签结构AI能看懂rowspan这种分组关系
for (const file of req.files) {
const isPdf = (file.mimetype || '').includes('pdf') || file.originalname.toLowerCase().endsWith('.pdf');
const isImage = (file.mimetype || '').startsWith('image/');
const isHtml = (file.mimetype || '').includes('html') || /\.html?$/i.test(file.originalname);
if (isPdf) {
const pdfSubDir = fs.mkdtempSync(path.join(tmpDir, 'pdf-'));
const pages = await renderPdfToImages(file.buffer, pdfSubDir);
@ -625,13 +627,24 @@ app.post('/api/ai/parse-catalog', requireAuth, aiLimiter, (req, res) => {
const imgPath = path.join(tmpDir, `img_${imagePaths.length}${ext}`);
fs.writeFileSync(imgPath, file.buffer);
imagePaths.push(imgPath);
} else if (isHtml) {
const raw = file.buffer.toString('utf8');
// 只去掉 <style>/<script> 这种纯样式/脚本内容对AI提取参数没用、白白占token
// 保留其余全部HTML标签结构——比如 rowspan 属性能直接告诉AI"这几行同属一个分组"
// 这比OCR识别出来的一堆无结构纯文字准确得多。
const cleaned = raw
.replace(/<style[\s\S]*?<\/style>/gi, '')
.replace(/<script[\s\S]*?<\/script>/gi, '')
.trim();
if (cleaned) htmlTextParts.push(cleaned);
} else {
return res.status(400).json({ error: `不支持的文件类型:${file.originalname}只支持PDF或图片` });
return res.status(400).json({ error: `不支持的文件类型:${file.originalname}只支持PDF、图片或HTML` });
}
}
const text = await ocrImages(imagePaths);
if (!text) return res.status(400).json({ error: 'OCR没有识别到任何文字请确认文件清晰、内容完整' });
const ocrText = imagePaths.length ? await ocrImages(imagePaths) : '';
const text = [ocrText, ...htmlTextParts].filter(Boolean).join('\n\n--- 下一份文件 ---\n\n');
if (!text) return res.status(400).json({ error: '没有识别/读取到任何文字内容,请确认文件清晰、内容完整' });
// 识别出来的文本太长就截断,避免超出模型输出预算;产品目录类文档核心信息通常靠前
const MAX_CHARS = 24000;
@ -642,7 +655,7 @@ app.post('/api/ai/parse-catalog', requireAuth, aiLimiter, (req, res) => {
if (hintBrand) hintLines.push(`品牌:${hintBrand}`);
if (hintType) hintLines.push(`细分品类:${hintType}`);
const userContent = hintLines.length
? `【用户已确认以下信息,直接使用,不用自己判断】\n${hintLines.join('\n')}\n\n【以下是OCR识别出的文档内容\n${clippedText}`
? `【用户已确认以下信息,直接使用,不用自己判断】\n${hintLines.join('\n')}\n\n【以下是文档内容可能是OCR识别结果、也可能是直接提取的HTML源码——HTML里的表格标签结构比如rowspan请重点利用能帮助你判断字段的分组归属\n${clippedText}`
: clippedText;
const content = await callDeepSeekWithRetry(cfg.apiKey, [