Files
cmroubao/docs/tasks/T-240.md
T

80 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-240
title: 缓存并鉴权提供顺运宝货运商品图片
phase: 2
deps:
- T-239
status: TODO
created: 2026-07-29
context_ref: 3bd9726
work_branch: null
write_paths:
- docs/tasks/T-240.md
- docs/api.md
- docs/current-state.md
- backend-api/migrations/00016_freight_item_images.sql
- backend-api/cmd/api/**
- backend-api/internal/domain/freight.go
- backend-api/internal/platform/shunyunbao/**
- backend-api/internal/usecase/freight_*
- backend-api/internal/repository/sqlite/freight_*
- backend-api/internal/transport/httpapi/**
- backend-api/internal/transport/webui/**
---
## 问题 / 背景
货运商品已保存来自 ERP `productThumb` 的正整数引用,但 Admin 只能看到引用文本。浏览器直接
拼接或热链 ERP 地址会泄露外部资源标识、绕过本系统鉴权,并依赖手机或浏览器是否持有 ERP
会话;把货运图片写成 `TASK_REFERENCE` 又会混淆资产所有权和用途。
图片 endpoint 已知为 `/api/p/file?id=<productThumb>`。查询参数必须取商品 `productThumb`,
不能取货运单 ID 或商品明细 ID;是否需要 Cookie/Token 必须通过与现有 ERP 查询相同的会话
客户端兼容。
## 关联需求与交互
- 单号或日期同步取得商品引用后,由 Go 后端从固定 ERP endpoint 下载图片并保存到本地。
- 货运列表和详情只使用本系统的同源鉴权 URL,不向浏览器暴露 ERP URL 或文件路径。
- 图片失败不得回滚已经成功导入的货运头和商品明细;页面显示明确占位状态并允许后续同步重试。
- 重复同步且 `productThumb` 未变化时复用本地文件,引用变化时下载新文件并清理被替换文件。
## 方案
1. 新增 `freight_item_images`,按货运商品保存 `product_thumb_ref`、`READY/MISSING/FAILED`
状态、规范化 JPEG 元数据、稳定错误码、尝试次数和更新时间。缺少记录但商品有引用视为
`PENDING`。
2. `SessionManager` 使用配置的 ERP origin、固定 `/api/p/file` 和 `url.Values` 构造请求;
复用 Cookie jar、固定请求头、HTTPS、禁止重定向及超时,只接受 2xx 图片响应。401/403
使会话失效,404 映射为 `MISSING`,其他错误映射为 `FAILED`。
3. 复用现有图片文件存储完成 20 MiB、尺寸、像素、解码格式、白底合成、最长边 2048 px 和
JPEG 规范化,不在日志输出图片字节、Cookie、查询参数或本地路径。
4. 货运事务先提交并标记同步成功,再在调用方剩余预算内执行有界 best-effort 缓存;单图失败
仅保存状态。同步重放或下一次同步重试未就绪图片,不重复下载相同引用的 `READY` 图片。
5. 增加受 Admin 会话保护的
`GET /api/v1/freight-items/{item_id}/image`,仅从本地存储返回 JPEG,带
`nosniff`、ETag、长度和私有缓存头;不存在、未完成或无权限统一返回 404。
## 验收要点
- [ ] 图片请求固定为配置 ERP origin 的 `/api/p/file?id=<productThumb>`,不接受任意 URL。
- [ ] 请求复用现有 ERP Cookie jar,禁止重定向;401/403、404、错误类型和无效图片稳定分类。
- [ ] 有效 JPEG/PNG/WebP 规范化保存为本地 JPEG,大小和像素限制不回归。
- [ ] 货运元数据先成功提交;单图失败不改变同步 `SUCCEEDED`,状态可审计并在后续同步重试。
- [ ] 相同 READY 引用不重复下载;引用变化替换关联并 best-effort 删除旧文件。
- [ ] Admin 图片接口只返回当前商品本地 READY 图片,未授权及其他状态不泄露存在性。
- [ ] 自动测试不访问真实 ERP,覆盖 Cookie、URL、重定向、状态、去重、替换和内容响应头。
- [ ] 标准 Go 测试、race、vet 和三个入口构建通过。
## 边界
- 本任务不修改货运列表和详情的视觉布局;页面引用图片 URL 和占位视觉在 T-241 完成。
- 不建立通用媒体库、不向浏览器返回 ERP URL、不持久化 ERP Cookie/Token。
- 不保证每张外部图片都成功;网络、会话和上游文件错误按商品隔离。
- 不提交或记录真实 ERP 图片、订单、商品、收件人、账号或会话数据。
## 执行记录
- 2026-07-29:创建任务。采用货运商品专属图片元数据表并复用安全文件编码管线;先提交货运
元数据,再 best-effort 缓存图片,避免单个外部文件阻塞或回滚完整订单。