日期:2026-07-01
状态:待实现
范围:web-admin【质检工单】【我的质检任务】
已确认:方案 A — 纯前端 JSZip 打包下载
已确认:导出过程需可见进度反馈(任务较慢)
用户在【质检工单】或【我的质检任务】中勾选一条或多条质检工单,将该工单下所有检测批次、所有质检任务的附件打包为 ZIP 下载。
目录结构:
{工单}/
{批次}/
{任务}/
附件文件…
btn-ghost + Download 图标)。| 步骤 | 说明 |
|---|---|
| 1 | 收集已选 workOrderId[] |
| 2 | POST /web/admin/qc-work-orders/inspection-batches/batch 获取批次及内嵌 tasks[].attachmentFiles |
| 3 | 扁平化附件清单,计算 ZIP 内路径 |
| 4 | 逐个 fetchAttachmentBlob(预签名 URL)写入 JSZip |
| 5 | zip.generateAsync({ type: 'blob' }, onUpdate) 生成压缩包 |
| 6 | FileSaver.saveAs 下载 |
依赖:jszip、file-saver(已存在于 package.json)。
biz_qc_task.third_party_attachments(逗号分隔 URL)attachmentFiles(含 fileUrl、fileName)| 层级 | 规则 |
|---|---|
| 工单 | {workOrderNo};若重名追加 _样本{sampleCode} 等短标识 |
| 批次 | {batchNo}_{batchName};无 batchNo 时用 批次{orderNum} |
| 任务 | {taskNo}_{itemName} |
| 文件 | 优先 fileName;同目录重名用 (2) 后缀 |
无附件的任务/批次不创建空目录。所选工单均无附件时提示「所选工单暂无附件」。
QC_TASK_READONLY_MENU_CODES 与租户隔离约束。环境检测页的「批量下载附件」仅按钮 loading,无细粒度进度。本功能附件量大、耗时长,必须使用独立进度弹窗。
新建:web-admin/src/components/business/attachment-zip-progress-dialog/index.vue
el-dialog,append-to-body,modal-class="protocol-dialog-mask"(无背景模糊)close-on-click-modal="false",show-close="false"(进行中不可点遮罩关闭)480px,单栏居中整体进度条 0–100%,按阶段加权:
| 阶段 | 权重 | 说明 |
|---|---|---|
preparing |
0–5% | 请求批次/任务元数据 |
downloading |
5–85% | 逐个拉取附件 blob 并 zip.file() |
zipping |
85–100% | generateAsync 压缩(使用 JSZip metadata.percent) |
展示文案示例:
报告.pdf副文案:当前工单 ZJGD… / 批次 首批检测(可选,简短一行 text-muted)。
el-progress:stroke-width="8",:percentage="overallPercent",:status 完成时 success| 结果 | 行为 |
|---|---|
| 全部成功 | 进度 100%,状态 success,1s 后自动关闭弹窗;ElMessage.success('已打包下载 N 个附件') |
| 部分失败 | 仍生成 ZIP(跳过失败项);关闭后 ElMessage.warning('已下载 N 个,M 个失败') |
| 全部失败 | 不下载;ElMessage.error('附件下载失败,请稍后重试') |
| 无附件 | 不打开进度弹窗;ElMessage.warning('所选工单暂无附件') |
Close 图标 + 文案)AbortController 中断进行中的 fetch;设置 cancelled 标志跳过后续文件ElMessage.info('已取消导出')saveAsElMessageBox.confirm 二次确认在 QcWorkOrderSingleCard 卡片头部左侧增加 el-checkbox:
QcWorkOrderProtocolGroup / QcWorkOrderSampleGroup 内每张工单卡片各自可勾选QcWorkOrderTabPanel 持有:selectedWorkOrderIds: Set<string>QcWorkOrderTabPanel.vue 在卡片列表上方增加(manage / mine 均显示):
已选 N 项 | [导出附件](btn-ghost,N=0 时 disabled)
| 文件 | 职责 |
|---|---|
@/utils/attachment-zip.ts |
从 env-detect-record 抽出 fetchAttachmentBlob、ensureUniqueZipEntryName、sanitizeZipPathSegment |
@/utils/qc-work-order-attachment-export.ts |
构建导出清单、ZIP 路径、runQcWorkOrderAttachmentExport() |
attachment-zip-progress-dialog |
进度 UI |
useQcWorkOrderAttachmentExport.ts |
组合 API + 进度回调 + 弹窗显隐 |
一期不新增后端接口,复用:
POST /web/admin/qc-work-orders/inspection-batches/batchPOST /web/admin/attachment/download-url| # | 场景 | 预期 |
|---|---|---|
| 1 | 勾选 1 个工单,含多批次多任务附件 | ZIP 目录三层正确,文件可打开 |
| 2 | 勾选多个工单 | 根目录下多个工单文件夹 |
| 3 | 工单无附件 | 提示暂无附件,不弹进度窗 |
| 4 | 导出中取消 | 中断下载,无文件落盘 |
| 5 | 单个文件 404 | 其余正常打包,warning 提示失败数 |
| 6 | 【我的质检任务】与【质检工单】 | 行为一致 |
| 7 | 协议组 / 样本组 | 各工单独立勾选、导出 |
若生产反馈单次导出经常超过 500 文件或超时,再评估方案 B(后端 StreamingResponse ZIP)并保留相同目录规范与进度语义(改为轮询任务状态)。