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:
@@ -1,4 +1,20 @@
|
||||
// client/ai/pub/jjxDoReview.js
|
||||
|
||||
// Word 报告生成器(依赖 docx,未安装时降级跳过,不影响审查)
|
||||
let buildDocx = null;
|
||||
let extractReportData = null;
|
||||
let extractDocxLink = null;
|
||||
let isDocxConvertible = null;
|
||||
try {
|
||||
const docxMod = require('./buildDocx.js');
|
||||
buildDocx = docxMod.buildDocx;
|
||||
extractReportData = docxMod.extractReportData;
|
||||
extractDocxLink = docxMod.extractDocxLink;
|
||||
isDocxConvertible = docxMod.isDocxConvertible;
|
||||
} catch (e) {
|
||||
console.log('[Docx] docx 依赖未安装,跳过 Word 生成:', e.message);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
main: async (event) => {
|
||||
let { data = {}, userInfo } = event;
|
||||
@@ -171,11 +187,50 @@ module.exports = {
|
||||
if (jsonMatch) contractInfo = JSON.parse(jsonMatch[1].trim());
|
||||
} catch (e) {}
|
||||
|
||||
// 生成 Word 报告:优先用智能体插件生成的链接,否则本地结构化重建
|
||||
let docxUrl = extractDocxLink ? extractDocxLink(answer) : '';
|
||||
let docxFileId = '';
|
||||
if (docxUrl) {
|
||||
console.log('[Docx] 采用智能体插件生成的 Word 链接:', docxUrl);
|
||||
} else if (isDocxConvertible && !isDocxConvertible(answer)) {
|
||||
// 智能体没返回完整报告(道歉/澄清文本,或 HTML 被截断),不生成残缺 Word
|
||||
console.log('[Docx] 无完整 HTML 报告,跳过 Word 生成');
|
||||
} else if (buildDocx && extractReportData) {
|
||||
try {
|
||||
const reportData = extractReportData(answer);
|
||||
if (reportData) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('[Docx] 既无插件链接也无结构化数据,跳过 Word 生成');
|
||||
}
|
||||
} 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,
|
||||
contract_info: contractInfo,
|
||||
points_used: pointsUsed,
|
||||
conversation_id: conversationId || '',
|
||||
|
||||
Reference in New Issue
Block a user