完成审计报告生成功能页面

This commit is contained in:
2026-03-10 22:51:53 +08:00
parent 92a6a32868
commit 65235ec961
11 changed files with 2732 additions and 283 deletions

View File

@@ -1,4 +1,4 @@
<!-- 用户编辑弹窗 -->
<!-- User编辑弹窗 -->
<template>
<a-drawer
:width="`70%`"
@@ -37,24 +37,30 @@
<a-card style="margin-bottom: 20px; text-align: center; background: transparent" :bordered="false">
<a-space>
<a-button size="large" type="primary" @click="handleGenerateAll" :loading="generatingAll" class="generate-all-button">
<template #icon>
<UngroupOutlined/>
</template>
生成全部方案
</a-button>
<a-button size="large">
<template #icon>
<DownloadOutlined/>
</template>
保存草稿
</a-button>
<a-button size="large">
<template #icon>
<RedoOutlined/>
</template>
加载草稿
</a-button>
<a-tooltip title="并行生成所有 9 个章节的内容(包含各小节)">
<a-button size="large" type="primary" @click="handleGenerateAll" :loading="generatingAll" class="generate-all-button">
<template #icon>
<UngroupOutlined/>
</template>
生成全部方案
</a-button>
</a-tooltip>
<a-tooltip title="依次保存所有章节到数据库(每个章节独立保存)">
<a-button size="large" @click="saveAllDrafts">
<template #icon>
<DownloadOutlined/>
</template>
保存草稿
</a-button>
</a-tooltip>
<a-tooltip title="从数据库加载所有已保存的章节内容">
<a-button size="large" @click="loadDrafts">
<template #icon>
<RedoOutlined/>
</template>
加载草稿
</a-button>
</a-tooltip>
<a-button size="large" type="danger" class="export-button" @click="handleExport">
<template #icon>
<UploadOutlined/>
@@ -120,16 +126,44 @@
:bordered="false"
>
<template #extra>
<a-button
type="primary"
@click="generateContent(index)"
:loading="item.generating"
>
<template #icon>
<RobotOutlined/>
</template>
AI生成
</a-button>
<a-space>
<a-button
type="primary"
size="small"
@click="reloadSectionData(index)"
:loading="sectionReloading[index]"
class="section-action-button reload-button"
>
<template #icon>
<ReloadOutlined />
</template>
重载数据
</a-button>
<a-button
type="primary"
size="small"
@click="saveSectionContent(index)"
:loading="sectionSaving[index]"
class="section-action-button save-button"
>
<template #icon>
<SaveOutlined />
</template>
保存
</a-button>
<a-button
type="primary"
size="small"
@click="generateContent(index)"
:loading="item.generating"
class="section-action-button ai-generate-button"
>
<template #icon>
<RobotOutlined/>
</template>
AI 生成
</a-button>
</a-space>
</template>
<!-- <div v-if="item.description" class="section-description">-->
<!-- {{ item.description }}-->
@@ -172,21 +206,47 @@
<!-- 多内容部分 -->
<template v-else>
<div v-for="(child, childIndex) in item.children" :key="childIndex" class="child-section">
<div class="child-title">
{{ child.name }}
<a-button
type="text"
size="small"
@click.stop="generateContent(index, childIndex)"
:loading="child.generating"
style="margin-left: 12px"
>
<template #icon>
<RobotOutlined/>
</template>
AI生成
</a-button>
<div v-for="(child, childIndex) in item.children" :key="childIndex" class="child-section" style="border-left: 3px solid #1890ff; padding-left: 16px; margin-bottom: 20px;">
<div class="child-title" style="display: flex; align-items: center; justify-content: space-between;">
<span style="font-weight: bold;">{{ child.name }}</span>
<a-space>
<a-button
type="primary"
size="small"
@click="saveChildContent(index, childIndex)"
:loading="child.saving"
class="child-action-button save-button"
>
<template #icon>
<SaveOutlined />
</template>
保存
</a-button>
<a-button
type="default"
size="small"
@click="reloadChildContent(index, childIndex)"
:loading="child.reloading"
class="child-action-button reload-button"
>
<template #icon>
<ReloadOutlined />
</template>
重载
</a-button>
<a-button
type="primary"
size="small"
@click.stop="generateContent(index, childIndex)"
:loading="child.generating"
class="child-action-button ai-generate-button"
>
<template #icon>
<RobotOutlined/>
</template>
AI 生成
</a-button>
</a-space>
</div>
<a-textarea
v-model:value="child.content"
@@ -244,9 +304,11 @@ import {
UploadOutlined,
RedoOutlined,
RobotOutlined,
QuestionCircleOutlined
QuestionCircleOutlined,
ReloadOutlined,
SaveOutlined
} from '@ant-design/icons-vue';
import {generateAuditReport, downloadAuditReport} from "@/api/ai/auditReport";
import {generateAuditReport, downloadAuditReport, queryAuditReport, saveAuditReport} from "@/api/ai/auditReport";
import {getPwlProjectLibraryByIds} from '@/api/pwl/pwlProjectLibrary';
const useForm = Form.useForm;
@@ -264,6 +326,10 @@ const maxAble = ref(true);
const generatingAll = ref(false);
// 当前选中的章节
const currentSection = ref(0);
// 每个章节的重载状态
const sectionReloading = reactive<Record<number, boolean>>({});
// 每个章节的保存状态
const sectionSaving = reactive<Record<number, boolean>>({});
// 存储拼接后的 kbIds
const combinedKbIds = ref('');
@@ -373,7 +439,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 51,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
},
{
name: '(二)公司发展战略规划的制定、执行和效果情况以及年度责任目标完成情况',
@@ -381,7 +450,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 52,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
},
{
name: '(三)重大经济事项的决策、执行和效果情况',
@@ -389,7 +461,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 53,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
},
{
name: '(四)公司法人治理结构的建立、健全和运行情况,内部控制制度的制定和执行情况',
@@ -397,7 +472,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 54,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
},
{
name: '(五)公司财务的真实合法效益情况,风险管控情况,境外资产管理情况',
@@ -405,7 +483,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 55,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
},
{
name: '(六)在经济活动中落实有关党风廉政建设责任和遵守廉洁从业规定情况',
@@ -413,7 +494,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 56,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
},
{
name: '(七)对以往审计中发现问题的整改情况',
@@ -421,7 +505,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 57,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
},
{
name: '(八)其他需要审计的事项',
@@ -429,7 +516,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 58,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
}
]
},
@@ -437,7 +527,7 @@ const navigationItems = ref([
number: '六',
name: '重要风险的识别及应对',
title: '6、重要风险的识别及应对',
description: '点击"AI生成"按钮让AI为您生成该部分内容或直接在下方编辑',
description: '点击"AI 生成"按钮让 AI 为您生成该部分内容,或直接在下方编辑',
generating: false,
children: [
{
@@ -446,7 +536,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 61,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
},
{
name: '(二)风险的应对策略',
@@ -454,7 +547,10 @@ const navigationItems = ref([
content: '',
suggestion: '',
formCommit: 62,
rows: 6
rows: 6,
generating: false,
saving: false,
reloading: false
}
]
},
@@ -625,13 +721,24 @@ const getScrollContainer = () => {
return document.querySelector('.ant-modal-body');
};
/* 批量生成全部内容 */
const handleGenerateAll2 = async () => {
/* 批量生成全部内容 - 清空后并行生成 */
const handleGenerateAll = async () => {
generatingAll.value = true;
try {
// 使用Promise.all进行并行生成
// 先清空所有内容
navigationItems.value.forEach(item => {
if (item.children) {
item.children.forEach(child => {
child.content = '';
});
} else {
item.content = '';
}
});
// 使用 Promise.all 并行生成所有 9 个方案
const promises: Promise<void>[] = [];
navigationItems.value.forEach((item, index) => {
if (item.children) {
// 有子项的章节,为每个子项生成内容
@@ -643,7 +750,7 @@ const handleGenerateAll2 = async () => {
promises.push(generateContent(index));
}
});
await Promise.all(promises);
message.success('全部内容生成完成');
} catch (error) {
@@ -654,39 +761,6 @@ const handleGenerateAll2 = async () => {
}
};
/* 批量生成全部内容 */
const handleGenerateAll = async () => {
generatingAll.value = true;
try {
// 改为顺序生成
for (const [index, item] of navigationItems.value.entries()) {
// 跳过未完成的依赖项
if (index === 4 && !hasContent(3)) {
message.warning('请先生成第四项「被审计单位基本情况」');
continue;
}
if (index === 5 && !hasContent(4)) {
message.warning('请先生成第五项「审计内容和重点及审计方法」');
continue;
}
if (item.children) {
for (const [childIndex] of item.children.entries()) {
await generateContent(index, childIndex);
}
} else {
await generateContent(index);
}
}
message.success('全部内容生成完成');
} catch (error) {
console.error('批量生成失败:', error);
message.error('部分内容生成失败,请检查');
} finally {
generatingAll.value = false;
}
};
// 新增内容检查方法
const hasContent = (index: number) => {
const section = navigationItems.value[index];
@@ -698,6 +772,541 @@ const hasContent = (index: number) => {
return !!section.content?.trim();
};
/**
* 保存所有方案到数据库(保存草稿)- 按章节分别保存
*/
const saveAllDrafts = async () => {
if (!form.id) {
message.warning('无项目信息');
return;
}
try {
// 按章节顺序依次保存
let savedCount = 0;
for (const navItem of navigationItems.value) {
// 如果章节有子项,为每个子项单独保存一条记录
if (navItem.children && navItem.children.length > 0) {
// 有子项,为每个小节单独保存
for (const child of navItem.children) {
const currentChildData = {
number: navItem.number,
name: navItem.name,
title: navItem.title,
tableType: 'audit_report',
content: '', // 主章节内容为空
formCommit: navItem.formCommit,
records: [{
name: child.name,
content: child.content || '',
formCommit: child.formCommit
}]
};
// 构建当前小节的预览 HTML
let previewHtml = '<div class="audit-report">';
previewHtml += `<h3>${currentChildData.number}${currentChildData.name}${currentChildData.title ? ' - ' + currentChildData.title : ''}</h3>`;
previewHtml += `<div><strong>${child.name}:</strong> ${child.content || ''}</div>`;
previewHtml += '</div>';
await saveAuditReport({
projectId: form.id,
projectName: form.name || '',
caseIndex: form.caseIndex || '',
auditedTarget: form.name || '',
reportContent: JSON.stringify({
sections: [currentChildData]
}),
previewHtml: previewHtml,
sectionCount: 1,
formCommit: child.formCommit || 1
});
savedCount++;
console.log(`[保存草稿] 已保存:${navItem.number}${navItem.name} - ${child.name}, formCommit: ${child.formCommit}`);
}
} else {
// 无子项,直接保存主章节
const currentSectionData = {
number: navItem.number,
name: navItem.name,
title: navItem.title,
tableType: 'audit_report',
content: navItem.content || '',
formCommit: navItem.formCommit,
records: []
};
// 构建当前章节的预览 HTML
let previewHtml = '<div class="audit-report">';
previewHtml += `<h3>${currentSectionData.number}${currentSectionData.name}${currentSectionData.title ? ' - ' + currentSectionData.title : ''}</h3>`;
if (currentSectionData.content) {
previewHtml += `<div>${currentSectionData.content}</div>`;
}
previewHtml += '</div>';
await saveAuditReport({
projectId: form.id,
projectName: form.name || '',
caseIndex: form.caseIndex || '',
auditedTarget: form.name || '',
reportContent: JSON.stringify({
sections: [currentSectionData]
}),
previewHtml: previewHtml,
sectionCount: 1,
formCommit: navItem.formCommit || 1
});
savedCount++;
console.log(`[保存草稿] 已保存:${navItem.number}${navItem.name}, formCommit: ${navItem.formCommit}`);
}
}
message.success(`草稿已保存到数据库(共 ${savedCount} 条记录)`);
} catch (e: any) {
console.error('[保存草稿] 失败:', e);
message.error('保存草稿失败:' + (e?.message || '未知错误'));
}
};
/**
* 从数据库加载草稿(根据每个方案的 formCommit 并行加载)
*/
const loadDrafts = async () => {
if (!form.id) {
message.warning('无项目信息');
return;
}
try {
console.log('[加载草稿] 开始加载projectId:', form.id);
// 收集所有的 formCommit 值(包括主章节和所有小节)
const formCommits: number[] = [];
navigationItems.value.forEach(item => {
if (item.formCommit) {
// 主章节有 formCommit直接使用
formCommits.push(item.formCommit);
} else if (item.children && item.children.length > 0) {
// 有子项的章节,收集所有小节的 formCommit
item.children.forEach(child => {
if (child.formCommit) {
formCommits.push(child.formCommit);
}
});
}
});
console.log('[加载草稿] 收集到的 formCommits:', formCommits);
// 并行查询所有 formCommit 的数据
const promises = formCommits.map(async (fc) => {
try {
console.log('[加载草稿] 查询 formCommit:', fc);
const res: any = await queryAuditReport({
projectId: form.id,
formCommit: fc
});
return { formCommit: fc, data: res?.data || null };
} catch (e) {
console.warn(`[加载草稿] 查询 formCommit=${fc} 失败:`, e);
return { formCommit: fc, data: null };
}
});
const results = await Promise.all(promises);
console.log('[加载草稿] 查询结果:', results);
// 解析并填充数据
let hasData = false;
results.forEach(result => {
if (result.data) {
hasData = true;
const reportContent = JSON.parse(result.data.reportContent || '{}');
if (reportContent.sections && Array.isArray(reportContent.sections)) {
const section = reportContent.sections[0];
if (section) {
// 找到对应的 navigationItem通过匹配任意一个 formCommit
const navItemIndex = navigationItems.value.findIndex(item =>
item.formCommit === result.formCommit ||
(item.children && item.children.some(child => child.formCommit === result.formCommit))
);
if (navItemIndex >= 0) {
const navItem = navigationItems.value[navItemIndex];
console.log(`[加载草稿] 恢复章节:${navItem.number}${navItem.name}, formCommit: ${result.formCommit}`);
// 恢复内容
if (navItem.children && section.records && Array.isArray(section.records)) {
// 有子项,根据 formCommit 匹配每个小节
section.records.forEach((rec: any) => {
const childIndex = navItem.children.findIndex(child => child.formCommit === rec.formCommit);
if (childIndex >= 0) {
navItem.children[childIndex].content = rec.content || '';
console.log(` - 恢复小节:${navItem.children[childIndex].name}, content length: ${rec.content?.length || 0}`);
}
});
} else if (!navItem.children && section.content) {
// 无子项,直接恢复主章节内容
navItem.content = section.content || '';
}
} else {
console.warn('[加载草稿] 未找到匹配的章节formCommit:', result.formCommit);
}
}
}
}
});
if (hasData) {
message.success('草稿已加载');
} else {
message.info('暂无保存的草稿');
}
} catch (e: any) {
console.error('[加载草稿] 失败:', e);
message.error('加载草稿失败:' + (e?.message || '未知错误'));
}
};
/**
* 保存单个章节的内容到数据库
*/
const saveSectionContent = async (sectionIndex: number) => {
if (!form.id) {
message.warning('无项目信息');
return;
}
const section = navigationItems.value[sectionIndex];
if (!section) return;
sectionSaving[sectionIndex] = true;
try {
// 如果章节有子项,为每个子项单独保存一条记录
if (section.children && section.children.length > 0) {
// 有子项,为每个小节单独保存
let savedChildrenCount = 0;
for (const child of section.children) {
// 检查内容是否为空,为空则跳过不保存
if (!child.content || !child.content.trim()) {
console.log(`[保存整章] 跳过空内容:${section.number}${section.name} - ${child.name}`);
continue;
}
const currentChildData = {
number: section.number,
name: section.name,
title: section.title,
tableType: 'audit_report',
content: '', // 主章节内容为空
formCommit: section.formCommit,
records: [{
name: child.name,
content: child.content || '',
formCommit: child.formCommit
}]
};
// 构建当前小节的预览 HTML
let previewHtml = '<div class="audit-report">';
previewHtml += `<h3>${currentChildData.number}${currentChildData.name}${currentChildData.title ? ' - ' + currentChildData.title : ''}</h3>`;
previewHtml += `<div><strong>${child.name}:</strong> ${child.content || ''}</div>`;
previewHtml += '</div>';
await saveAuditReport({
projectId: form.id,
projectName: form.name || '',
caseIndex: form.caseIndex || '',
auditedTarget: form.name || '',
reportContent: JSON.stringify({
sections: [currentChildData]
}),
previewHtml: previewHtml,
sectionCount: 1,
formCommit: child.formCommit || 1
});
savedChildrenCount++;
console.log(`[保存整章] 已保存:${section.number}${section.name} - ${child.name}, formCommit: ${child.formCommit}`);
}
if (savedChildrenCount === 0) {
message.info('该章节没有需要保存的内容(所有小节均为空)');
} else {
message.success(`${section.number}${section.name} 已保存(共 ${savedChildrenCount}/${section.children.length} 个小节)`);
}
} else {
// 无子项,直接保存主章节
// 检查内容是否为空,为空则跳过不保存
if (!section.content || !section.content.trim()) {
console.log(`[保存整章] 跳过空内容:${section.number}${section.name}`);
message.info('该章节没有需要保存的内容');
sectionSaving[sectionIndex] = false;
return;
}
const currentSectionData = {
number: section.number,
name: section.name,
title: section.title,
tableType: 'audit_report',
content: section.content || '',
formCommit: section.formCommit,
records: []
};
// 只构建当前章节的预览 HTML
let previewHtml = '<div class="audit-report">';
previewHtml += `<h3>${currentSectionData.number}${currentSectionData.name}${currentSectionData.title ? ' - ' + currentSectionData.title : ''}</h3>`;
if (currentSectionData.content) {
previewHtml += `<div>${currentSectionData.content}</div>`;
}
previewHtml += '</div>';
// 调用保存接口(使用当前章节的 formCommit
await saveAuditReport({
projectId: form.id,
projectName: form.name || '',
caseIndex: form.caseIndex || '',
auditedTarget: form.name || '',
reportContent: JSON.stringify({
sections: [currentSectionData] // 只保存当前章节
}),
previewHtml: previewHtml, // 只包含当前章节的 HTML
sectionCount: 1, // 只有 1 个章节
formCommit: section.formCommit || 1
});
message.success(`${section.number}${section.name} 已保存`);
}
} catch (e: any) {
console.error('保存失败:', e);
message.error('保存失败:' + (e?.message || '未知错误'));
} finally {
sectionSaving[sectionIndex] = false;
}
};
/**
* 保存单个小节的内容到数据库
*/
const saveChildContent = async (sectionIndex: number, childIndex: number) => {
if (!form.id) {
message.warning('无项目信息');
return;
}
const section = navigationItems.value[sectionIndex];
if (!section || !section.children || !section.children[childIndex]) return;
const child = section.children[childIndex];
// 检查内容是否为空,为空则不保存
if (!child.content || !child.content.trim()) {
message.info('该小节内容为空,无需保存');
return;
}
child.saving = true;
try {
// 构建只包含当前小节的数据结构
const currentChildData = {
number: section.number,
name: section.name,
title: section.title,
tableType: 'audit_report',
content: '', // 主章节内容为空
formCommit: section.formCommit,
records: [{
name: child.name,
content: child.content || '',
formCommit: child.formCommit
}]
};
// 构建当前小节的预览 HTML
let previewHtml = '<div class="audit-report">';
previewHtml += `<h3>${currentChildData.number}${currentChildData.name}${currentChildData.title ? ' - ' + currentChildData.title : ''}</h3>`;
previewHtml += `<div><strong>${child.name}:</strong> ${child.content || ''}</div>`;
previewHtml += '</div>';
// 调用保存接口(使用当前小节的 formCommit
await saveAuditReport({
projectId: form.id,
projectName: form.name || '',
caseIndex: form.caseIndex || '',
auditedTarget: form.name || '',
reportContent: JSON.stringify({
sections: [currentChildData]
}),
previewHtml: previewHtml,
sectionCount: 1,
formCommit: child.formCommit || 1
});
message.success(`${child.name} 已保存`);
} catch (e: any) {
console.error('保存小节失败:', e);
message.error('保存失败:' + (e?.message || '未知错误'));
} finally {
child.saving = false;
}
};
/**
* 重载单个章节的数据(包括所有子小节)
*/
const reloadSectionData = async (sectionIndex: number) => {
if (!form.id) {
message.warning('无项目信息');
return;
}
const section = navigationItems.value[sectionIndex];
if (!section) return;
sectionReloading[sectionIndex] = true;
try {
// 如果章节有子项,需要查询所有子项的数据
if (section.children && section.children.length > 0) {
console.log(`[重载章节数据] 开始重载有子项的章节:${section.number}${section.name}`);
// 收集所有子项的 formCommit
const childFormCommits = section.children.map(child => child.formCommit).filter(fc => fc);
console.log(`[重载章节数据] 子项 formCommits:`, childFormCommits);
// 并行查询所有子项的数据
const promises = childFormCommits.map(async (fc) => {
try {
const res: any = await queryAuditReport({
projectId: form.id,
formCommit: fc
});
return { formCommit: fc, data: res?.data || null };
} catch (e) {
console.warn(`[重载章节数据] 查询 formCommit=${fc} 失败:`, e);
return { formCommit: fc, data: null };
}
});
const results = await Promise.all(promises);
console.log(`[重载章节数据] 查询结果:`, results);
// 解析并填充每个子项的数据
let loadedCount = 0;
results.forEach(result => {
if (result.data) {
const reportContent = JSON.parse(result.data.reportContent || '{}');
if (reportContent.sections && Array.isArray(reportContent.sections)) {
const sectionData = reportContent.sections[0];
if (sectionData && sectionData.records && Array.isArray(sectionData.records)) {
// 找到对应的子项并填充数据
sectionData.records.forEach((rec: any) => {
const childIndex = section.children.findIndex(child => child.formCommit === rec.formCommit);
if (childIndex >= 0) {
section.children[childIndex].content = rec.content || '';
loadedCount++;
}
});
}
}
}
});
console.log(`[重载章节数据] 已加载 ${loadedCount}/${section.children.length} 个小节的数据`);
if (loadedCount === 0) {
message.info('该章节暂无保存的数据');
} else {
message.success(`${section.number}${section.name} 数据已重新加载(共 ${loadedCount}/${section.children.length} 个小节)`);
}
} else {
// 无子项,直接加载主章节
const formCommitToUse = section.formCommit || 1;
console.log(`[重载章节数据] 开始重载主章节sectionIndex: ${sectionIndex}, formCommit: ${formCommitToUse}`);
const res: any = await queryAuditReport({
projectId: form.id,
formCommit: formCommitToUse
});
if (res.data) {
const reportContent = JSON.parse(res.data.reportContent || '{}');
if (reportContent.sections && Array.isArray(reportContent.sections)) {
const sectionData = reportContent.sections[0];
if (sectionData) {
section.content = sectionData.content || '';
console.log(`[重载章节数据] 已加载主章节内容,长度:${section.content?.length || 0}`);
message.success(`${section.number}${section.name} 数据已重新加载`);
}
}
}
// 没有数据时不提示
}
} catch (e: any) {
console.error('重载章节数据失败:', e);
message.error('重载失败:' + (e?.message || '未知错误'));
} finally {
sectionReloading[sectionIndex] = false;
}
};
/**
* 重载单个小节的数据
*/
const reloadChildContent = async (sectionIndex: number, childIndex: number) => {
if (!form.id) {
message.warning('无项目信息');
return;
}
const section = navigationItems.value[sectionIndex];
if (!section || !section.children || !section.children[childIndex]) return;
const child = section.children[childIndex];
child.reloading = true;
try {
const res: any = await queryAuditReport({
projectId: form.id,
formCommit: child.formCommit
});
if (res.data) {
const reportContent = JSON.parse(res.data.reportContent || '{}');
if (reportContent.sections && Array.isArray(reportContent.sections)) {
const sectionData = reportContent.sections[0]; // 取第一个章节
if (sectionData && sectionData.records && Array.isArray(sectionData.records)) {
// 找到对应的小节记录
const record = sectionData.records.find((r: any) => r.formCommit === child.formCommit);
if (record) {
child.content = record.content || '';
message.success(`${child.name} 数据已重新加载`);
}
}
}
}
// 没有数据时不提示
} catch (e: any) {
console.error('重载小节数据失败:', e);
message.error('重载失败:' + (e?.message || '未知错误'));
} finally {
child.reloading = false;
}
};
/* 新增:构建导出数据的公共方法 */
const buildExportData = () => {
const exportData: any = {
@@ -914,6 +1523,9 @@ watch(
// 重置到第一个章节
currentSection.value = 0;
// 自动从数据库加载审计报告
await loadAuditReportFromDB();
}
} else {
resetFields();
@@ -1067,6 +1679,53 @@ export default {
}
}
/* 章节操作按钮统一样式 */
.section-action-button {
border-radius: 20px !important;
transition: all 0.3s ease;
&:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
}
/* 重载数据按钮 - 蓝色 */
:deep(.reload-button) {
background-color: #1890ff !important;
border-color: #1890ff !important;
&:hover {
background-color: #40a9ff !important;
border-color: #40a9ff !important;
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.4) !important;
}
}
/* 保存按钮 - 绿色 */
:deep(.save-button) {
background-color: #52c41a !important;
border-color: #52c41a !important;
&:hover {
background-color: #73d13d !important;
border-color: #73d13d !important;
box-shadow: 0 4px 12px rgba(82, 196, 26, 0.4) !important;
}
}
/* AI 生成按钮 - 紫色 */
:deep(.ai-generate-button) {
background-color: #722ed1 !important;
border-color: #722ed1 !important;
&:hover {
background-color: #9254de !important;
border-color: #9254de !important;
box-shadow: 0 4px 12px rgba(114, 46, 209, 0.4) !important;
}
}
.navigation-container {
.nav-grid {
display: grid;