Skip to content

fix(approvals+storage): 审批决策附件在时间线里没名字、点击无反应、下载名是乱码 token (objectui #2820) #3504

Description

@baozhoutao

审批通过 / 拒绝时可上传附件。在记录 / 审批中心的「审批动态」时间线里,这个附件本应以 📎 文件名 胶囊呈现、点击打开。实测发现三处坏:

  1. 胶囊没有文件名,只显示通用「附件」。
  2. 点击胶囊无反应,也无任何报错。
  3. 即便文件下载下来,文件名是一长串签名 token 乱码(如 eyJrIjoiYXR0YWNo…),content-type 还是 application/octet-stream

根因一 —— 审批读取路径把描述符 String() 烂了

sys_approval_action.attachmentsField.file,存的是富描述符对象 { id, name, url, mimeType, size }(fileId 在写入时被解析成完整描述符),不是 fileId 字符串。但 plugin-approvalsrowFromAction 用了 row.attachments.map(String),把每个对象 String() 成字面量 "[object Object]"listActions 的消费方(审批时间线)拿到的就是这坨垃圾 → chip 无名字、openAttachment("[object Object]") 404 被前端吞掉。

实测证据:修复前 GET /approvals/requests/{id}/actions 返回 attachments: ["[object Object]"]

根因二 —— 存储下载接口不带文件名 / 类型

预签名下载把字节以 application/octet-stream + Content-Disposition 发出,浏览器只能拿 URL 末段(签名 token)当文件名保存。签名 token 里也没带原始文件名。

方案

approvals(@objectstack/spec + @objectstack/plugin-approvals)

  • 新增 ApprovalActionAttachment,ApprovalActionRow.attachmentsstring[] 改为 ApprovalActionAttachment[];rowFromAction 透传描述符({id,name,url,...}),兼容裸字符串 fileId。决策写入 input 仍是 string[],不变。消费方从此不再需要对系统对象 sys_file 的读权限即可拿到名字 + URL。

storage(@objectstack/spec + @objectstack/service-storage)

  • IStorageService.getSignedUrl / getPresignedDownload 增加可选 PresignedDownloadOptions {filename, contentType, disposition}
  • REST 下载路由(GET /storage/files/:id/url/:id)传入 sys_filename + mime_type
  • 本地适配器把它们编进签名 token,_local/raw 路由发 Content-Type + RFC 5987 Content-Disposition(ASCII 回退 + filename*=UTF-8''…);S3 适配器用 ResponseContentType / ResponseContentDisposition 烤进签名 URL。默认 inline,可预览类型仍在浏览器打开,保存时名字正确。

已用 framework app-showcase(审批+存储链路)真机 UI 实测:chip 显示 signed-contract.pdf、点击打开真 PDF、下载响应头 content-type: application/pdf + content-disposition: inline; filename="signed-contract.pdf"

前端配套:objectstack-ai/objectui#2820

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions