feat: AI审查报告支持下载Word + 我的报告支持重新审查

- 云函数jjxReviewTimer完成审查后自动将HTML报告转换为Word文档并上传
- 新增buildDocx.js纯正则解析HTML报告生成A4公文版式docx(三级数据提取兼容结构漂移)
- 兼容智能体插件直接返回docx链接(jjx-docx-link标记协议)
- router/jjxDoReview同步支持Word生成(try降级不影响主流程)
- 前端报告列表新增下载Word/重新审查按钮
- 修复上传/查询取真实uid(vk.getVuex而非页面本地data)
- login.js清理调试日志、.gitignore忽略node_modules与lock文件
This commit is contained in:
2026-10-23 19:07:05 +08:00
parent d0fb8802e7
commit 95024bb2a6
9 changed files with 2341 additions and 4 deletions
@@ -11,6 +11,8 @@ const _ = db.command;
const COZE_TOKEN = 'sat_OiXlI4Da5Q99fxmul6pNfExmA6hR898UbxBDwrvjZ638APxRSlFnXbz6zyFedKNG';
const BOT_ID = '7689821072762011698';
const { buildDocx, extractReportData, extractDocxLink, isDocxConvertible } = require('./buildDocx.js');
async function doReview(record) {
const { _id: record_id, file_id, user_id, file_name, file_size } = record;
@@ -156,11 +158,52 @@ async function doReview(record) {
console.log('HTML报告上传失败:', e.message);
}
// 生成 Word 报告:优先用智能体插件生成的链接,否则本地结构化重建
let docxUrl = extractDocxLink(answer);
let docxFileId = '';
if (docxUrl) {
console.log('[Docx] 采用智能体插件生成的 Word 链接:', docxUrl);
} else if (!isDocxConvertible(answer)) {
// 智能体没返回完整报告(如「文件解析失败」的道歉文本,或 HTML 被截断),
// 不生成 Word,避免产出一份残缺文档
console.log('[Docx] 无完整 HTML 报告,跳过 Word 生成');
} else {
try {
const reportData = extractReportData(answer);
if (!reportData) {
console.log('[Docx] 既无插件链接也无结构化数据,跳过 Word 生成');
} else {
const docxBuffer = await buildDocx({
data: reportData,
fileName: file_name || '合同审查报告'
});
const baseName = (file_name || 'report').replace(/\.[^.]+$/, '');
const docxPath = 'review-reports/' + Date.now() + '_' + baseName + '_审查报告.docx';
const docxRes = await uniCloud.uploadFile({
cloudPath: docxPath,
fileContent: docxBuffer
});
if (docxRes.fileID) {
docxFileId = docxRes.fileID;
const docxUrlRes = await uniCloud.getTempFileURL({ fileList: [docxRes.fileID] });
if (docxUrlRes.fileList && docxUrlRes.fileList[0]) {
docxUrl = docxUrlRes.fileList[0].tempFileURL;
}
console.log('[Docx] 本地 Word 报告生成成功:', docxFileId);
}
}
} catch (e) {
console.log('[Docx] Word 报告生成失败(不影响审查结果):', e.message);
}
}
// 更新记录为完成
await db.collection('jjx-review-records').doc(record_id).update({
status: 'completed',
result: answer,
html_url: htmlUrl,
docx_url: docxUrl,
docx_file_id: docxFileId,
token_count: tokenCount,
points_used: pointsUsed,
conversation_id: conversationId || '',