--- name: 修复管理后台衣物图片与头像URL overview: 管理后台衣物列表/详情与穿搭明细返回的 processed_image 是 COS 相对 key、用户头像 avatar 同理,导致前端无法访问图片。参照业务服务 upload.GetCosUrl 逻辑,为管理后台补齐 COS 下载域名/鉴权密钥配置与 CDN 签名 URL 转换,使图片可正常展示。 todos: - id: add-cos-config content: 新增 Cos 配置段:pkg/setting/section.go、global/setting.go、main.go 与 configs/config.example.yaml status: completed - id: add-cos-url-helper content: 新增 pkg/cos/cosurl.go 实现 GetCosUrl(复刻业务 MD5 CDN 签名,含空值与未配置兜底) status: completed dependencies: - add-cos-config - id: convert-clothes-images content: 修改 service/content.go:衣物列表/详情与穿搭详情衣物图片转可访问 URL status: completed dependencies: - add-cos-url-helper - id: convert-user-avatar content: 修改 service/user.go:用户头像做 http(s) 透传兼容并转 URL status: completed dependencies: - add-cos-url-helper - id: finalize-verify content: 更新 README 配置与安全说明,执行 go build 与 go vet 验证 status: completed dependencies: - convert-clothes-images - convert-user-avatar --- ## 用户需求 管理后台前端无法展示用户上传的衣物图片,需要修复图片地址生成逻辑。 ## 根因 衣物图片上传 COS 后,数据库 `clothes.processed_image` 存的是相对 COS key(如 `{userUUID}/{userID}/{uuid}.png`),业务服务返回前会调用 `upload.GetCosUrl()` 生成带 CDN 鉴权签名的完整 URL。管理后台目前直接返回相对 key,导致前端拿到的地址无法访问。 用户头像存在同类问题:`users.avatar` 存的也是 COS key 或历史完整 URL,管理后台同样直接返回未转换的原始值。 ## 修复范围 1. 管理后台新增 COS 下载配置(CDN 下载域名 + 下载鉴权密钥),与业务服务 Cos 段保持一致。 2. 新增 `GetCosUrl` 工具函数,复刻业务服务 MD5 CDN 签名逻辑。 3. 衣物列表/详情、穿搭详情中的衣物图片地址转为可访问 URL。 4. 用户列表/详情中的头像地址做兼容转换(`http(s)` 完整 URL 透传,COS key 转 URL)。 5. 补充配置说明与 README,确保配置为机密项、不落库、不硬编码。 ## 技术方案 ### 实现策略 完全复刻业务服务的图片 URL 生成逻辑,保持两服务共用同一 COS 时签名结果一致。仅改管理后台,不改业务服务。 ### 关键改动 1. **配置层新增 Cos 段(仅下载所需字段)** - `pkg/setting/section.go`:新增 `CosSettingS{CosDownloadDomain string; CdnDownloadSecretKey string}`。 - `global/setting.go`:新增 `CosSetting *setting.CosSettingS`。 - `main.go`:`setupSetting` 中读取 `Cos` 段。 - `configs/config.example.yaml`:新增 `Cos:` 段,注释说明须与业务服务 Cos 段一致、属机密项。 2. **新增 URL 生成工具 `pkg/cos/cosurl.go`** 复刻业务 `upload.GetCosUrl`: - `ts := time.Now().Unix()` - `raw := CdnDownloadSecretKey + "/" + fileName + ts` - `sign := md5(raw)` - 返回 `https://{CosDownloadDomain}/{fileName}?sign={sign}&t={ts}` - 增加保护:`fileName == ""` 或 Cos 配置缺失/下载域名为空时,原样返回 fileName,避免未配置时 panic 或生成无效 URL。 3. **接入图片转换** - `internal/service/content.go`: - `buildClothesItem` 中 `ProcessedImage` 改为 `cos.GetCosUrl(c.ProcessedImage)`。 - `OutfitDetail` 中衣物明细 `ProcessedImage` 改为 `cos.GetCosUrl(cl.ProcessedImage)`。 - `internal/service/user.go`: - `buildUserListItem` 中 `Avatar` 增加兼容转换:以 `http://`/`https://` 开头则透传,否则 `cos.GetCosUrl(u.Avatar)`;建议提取内部辅助函数 `toImageURL(key string) string` 供 avatar 复用。 4. **文档与验证** - `README.md`:配置段说明新增 `Cos`;安全注意事项注明 `CdnDownloadSecretKey` 为机密,仅存 `configs/config.yaml`(已 gitignore),与业务服务保持一致。 - `go build ./...` 与 `go vet ./...` 必须通过。 ### 目录结构 ``` /root/zt-closet-manage-backend/ ├── configs/config.example.yaml # [MODIFY] 新增 Cos 段 ├── global/setting.go # [MODIFY] 新增 CosSetting ├── pkg/setting/section.go # [MODIFY] 新增 CosSettingS ├── pkg/cos/cosurl.go # [NEW] GetCosUrl 工具 ├── internal/service/content.go # [MODIFY] 衣物/穿搭图片转 URL ├── internal/service/user.go # [MODIFY] 头像转 URL ├── main.go # [MODIFY] setupSetting 读取 Cos 段 └── README.md # [MODIFY] 配置与安全说明 ``` ### 注意事项 - 管理后台与业务服务共用同一 COS,`Cos.CosDownloadDomain` 与 `Cos.CdnDownloadSecretKey` 必须与业务服务 `configs/config.yaml` 中的 `Cos` 段一致,否则签名校验失败。 - 仅做 URL 转换,不改动数据库存储的相对 key;对空值、未配置做安全兜底。 - 不引入 COS SDK,仅需 `crypto/md5`、`fmt`、`strconv`、`time` 标准库,避免额外依赖。