feat(M08-B): 补联调交接报告

This commit is contained in:
Codex
2026-07-06 08:43:19 +08:00
parent 99d9d862b7
commit 464566a5e0
6 changed files with 103 additions and 8 deletions
@@ -52,6 +52,8 @@
<el-button :icon="FileDown" @click="exportSnapshot">快照</el-button>
<el-button :icon="FileUp" @click="openSnapshotImport">导入</el-button>
<el-button :icon="Download" @click="exportChecklist">导出</el-button>
<el-button :icon="Copy" @click="copyHandoffReport">复制报告</el-button>
<el-button :icon="FileDown" @click="exportHandoffReport">报告</el-button>
<el-button :icon="RotateCcw" @click="resetDraft">重置</el-button>
<input
ref="snapshotInput"
@@ -481,6 +483,83 @@ async function copyVerdict() {
}
}
async function copyHandoffReport() {
try {
await navigator.clipboard.writeText(buildHandoffReport());
ElMessage.success('现场交接报告已复制');
} catch {
ElMessage.warning('当前浏览器不允许自动复制,请使用报告导出留存');
}
}
function exportHandoffReport() {
downloadText(
`cleaning-field-handoff-report-${Date.now()}.txt`,
buildHandoffReport(),
'text/plain;charset=utf-8'
);
}
function buildHandoffReport() {
const header = [
'# 保洁现场联调交接报告',
`联调批次:${sessionMeta.batchNo || '未填写'}`,
`现场/门店:${sessionMeta.site || '未填写'}`,
`负责人:${sessionMeta.coordinator || '未填写'}`,
`执行时间:${sessionMeta.executedAt || '未填写'}`,
`最后更新:${sessionMeta.updatedAt || '未记录'}`,
`结论:${handoffReady.value ? '可进入现场验收收口' : '仍不可收口'}`,
`汇总:总项 ${checklist.length},通过 ${passedCount.value},阻断 ${blockedCount.value},待处理 ${pendingCount.value},证据 ${evidenceRecordedCount.value}/${checklist.length},待补证据 ${evidenceMissingCount.value}`
];
const progress = categoryProgress.value.map((item) => (
`- ${item.category}${item.passed}/${item.total} 通过,阻断 ${item.blocked},待处理 ${item.pending},不适用 ${item.skipped}`
));
const blockers = blockedItems.value.length
? blockedItems.value.map((item) => formatReportItem(item))
: ['- 无'];
const evidenceGaps = evidenceMissingItems.value.length
? evidenceMissingItems.value.map((item) => `- [${item.category}] ${item.title}${item.evidence}`)
: ['- 无'];
const details = checklist.map((item) => formatReportItem(item));
return [
...header,
'',
'## 分类进度',
...progress,
'',
'## 阻断项',
...blockers,
'',
'## 待补证据',
...evidenceGaps,
'',
'## 明细',
...details
].join('\n');
}
function formatReportItem(item: HandoffItem) {
const itemDraft = draft[item.id];
return [
`- [${item.category}] ${item.title}`,
` 状态:${statusText(itemDraft.status)}`,
` 负责人:${itemDraft.owner || '未分派'}`,
` 结果:${itemDraft.note || '未记录'}`,
` 应留证据:${item.evidence}`,
` 证据记录:${itemDraft.evidenceRef || '未记录'}`
].join('\n');
}
function statusText(status: FieldStatus) {
const labels: Record<FieldStatus, string> = {
PENDING: '待处理',
PASS: '通过',
BLOCKED: '阻断',
SKIP: '不适用'
};
return labels[status];
}
function exportChecklist() {
downloadCsv(`cleaning-field-handoff-${Date.now()}.csv`, [
['类别', '字段', '值', '', '', '', '', '', ''],