From b1062a5aed3e6600689364b8c596bc60621dd678 Mon Sep 17 00:00:00 2001 From: imbytecat Date: Thu, 5 Mar 2026 16:58:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor(api):=20signAndPackReport=20=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E8=BF=94=E5=9B=9E=E7=AD=BE=E5=90=8D=20ZIP=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/server/api/contracts/crypto.contract.ts | 9 ++------- apps/server/src/server/api/routers/crypto.router.ts | 6 +++--- docs/UX-授权端接口说明.md | 2 +- .../工具箱端-报告加密与签名生成指南.md | 2 +- docs/第三方-OpenAPI-对接指南.md | 11 +++-------- 5 files changed, 10 insertions(+), 20 deletions(-) diff --git a/apps/server/src/server/api/contracts/crypto.contract.ts b/apps/server/src/server/api/contracts/crypto.contract.ts index 80fece0..1cb7d26 100644 --- a/apps/server/src/server/api/contracts/crypto.contract.ts +++ b/apps/server/src/server/api/contracts/crypto.contract.ts @@ -80,7 +80,7 @@ export const signAndPackReport = oc operationId: 'signAndPackReport', summary: '签名并打包报告 ZIP', description: - '接收原始 ZIP(multipart/form-data 文件字段 rawZip),由 UX 生成 summary.json、manifest.json、signature.asc,并返回 signedZipBase64。', + '接收原始 ZIP(multipart/form-data 文件字段 rawZip),由 UX 生成 summary.json、manifest.json、signature.asc,并直接返回签名后 ZIP 二进制文件。', tags: ['Crypto', 'Report'], }) .input( @@ -96,9 +96,4 @@ export const signAndPackReport = oc .describe('原始报告 ZIP 文件(multipart/form-data 字段)'), }), ) - .output( - z.object({ - deviceSignature: z.string().describe('设备签名(HMAC-SHA256 Base64)'), - signedZipBase64: z.string().describe('签名后 ZIP 的 Base64 编码'), - }), - ) + .output(z.file().describe('签名后报告 ZIP 文件(二进制响应)')) diff --git a/apps/server/src/server/api/routers/crypto.router.ts b/apps/server/src/server/api/routers/crypto.router.ts index ee3cf6c..551a94c 100644 --- a/apps/server/src/server/api/routers/crypto.router.ts +++ b/apps/server/src/server/api/routers/crypto.router.ts @@ -301,7 +301,7 @@ export const signAndPackReport = os.crypto.signAndPackReport.use(db).handler(asy compressionOptions: { level: 9 }, }) - const signedZipBase64 = Buffer.from(signedZipBytes).toString('base64') - - return { deviceSignature, signedZipBase64 } + return new File([Buffer.from(signedZipBytes)], `${input.taskId}-signed-report.zip`, { + type: 'application/zip', + }) }) diff --git a/docs/UX-授权端接口说明.md b/docs/UX-授权端接口说明.md index 199b18f..30746e0 100644 --- a/docs/UX-授权端接口说明.md +++ b/docs/UX-授权端接口说明.md @@ -58,7 +58,7 @@ 5. 生成 `META-INF/manifest.json` 6. OpenPGP 分离签名生成 `META-INF/signature.asc` 7. 重新打包为 signed ZIP -- 输出:`signedZipBase64` 与 `deviceSignature` +- 输出:签名后 ZIP 文件(二进制响应,`application/zip`) ## 4. 安全约束(签名打包) diff --git a/docs/工具箱端-授权对接指南/工具箱端-报告加密与签名生成指南.md b/docs/工具箱端-授权对接指南/工具箱端-报告加密与签名生成指南.md index 0a337b7..83fd7af 100644 --- a/docs/工具箱端-授权对接指南/工具箱端-报告加密与签名生成指南.md +++ b/docs/工具箱端-授权对接指南/工具箱端-报告加密与签名生成指南.md @@ -12,7 +12,7 @@ > > 1. UX 校验 ZIP 并提取必需文件; > 2. UX 生成 `deviceSignature`、`summary.json`、`META-INF/manifest.json`、`META-INF/signature.asc`; -> 3. UX 重新打包并返回签名后的 ZIP(Base64),工具箱再用于离线介质回传平台。 +> 3. UX 重新打包并返回签名后的 ZIP(二进制文件响应),工具箱再用于离线介质回传平台。 ## 一、ZIP 文件结构要求 diff --git a/docs/第三方-OpenAPI-对接指南.md b/docs/第三方-OpenAPI-对接指南.md index 3ff0c4b..841ce31 100644 --- a/docs/第三方-OpenAPI-对接指南.md +++ b/docs/第三方-OpenAPI-对接指南.md @@ -74,7 +74,7 @@ OpenAPI 中已按 `tags` 分组: - 文件类型:`application/zip` 或 `application/x-zip-compressed` - 其他业务字段(如 `deviceId`、`taskId`)与文件一起提交 -- 接口响应为 JSON,其中 `signedZipBase64` 为签名后 ZIP 的 Base64 编码 +- 接口响应为签名后 ZIP 文件(`application/zip`) 示例(curl): @@ -85,13 +85,8 @@ curl -X POST "http://localhost:3000/api/crypto/sign-and-pack-report" \ -F "enterpriseId=1173040813421105152" \ -F "inspectionId=702286470691215417" \ -F "summary=检查摘要信息" \ - -F "rawZip=@./report-raw.zip;type=application/zip" -``` - -响应中的 `signedZipBase64` 可按以下方式还原为 ZIP: - -```bash -# jq -r '.signedZipBase64' response.json | base64 -d > signed-report.zip + -F "rawZip=@./report-raw.zip;type=application/zip" \ + --output signed-report.zip ``` ## 6. 推荐接入方式