73 lines
4.0 KiB
Markdown
73 lines
4.0 KiB
Markdown
---
|
||
name: 收藏单条状态查询接口
|
||
overview: 参照点赞的 GET /like/:targetUUID,为收藏新增 GET /collect/:targetUUID 单条收藏状态查询接口(返回 is_collected + collect_count),补齐前端进入穿搭详情时的收藏状态初始化能力。
|
||
todos:
|
||
- id: add-collect-status-api
|
||
content: 新增收藏单条状态查询 DTO、Service、Handler 与路由注册
|
||
status: completed
|
||
- id: sync-collect-docs
|
||
content: 同步 README 与接口文档,补充 GET /collect/:targetUUID 说明
|
||
status: completed
|
||
dependencies:
|
||
- add-collect-status-api
|
||
- id: verify-collect-build
|
||
content: 执行 go build ./... 验证编译通过
|
||
status: completed
|
||
dependencies:
|
||
- add-collect-status-api
|
||
---
|
||
|
||
## 用户需求
|
||
|
||
收藏状态无法正确初始化——后端缺少「单条收藏状态」查询接口。点赞已有 `GET /like/:targetUUID`(返回 `is_liked` + `like_count`),收藏仅有 `POST /collect`(收藏/取消)和 `GET /collect`(我的收藏列表),前端进入穿搭详情时无法获知当前用户是否已收藏该穿搭。
|
||
|
||
## 核心功能
|
||
|
||
参照点赞接口,为收藏补齐 `GET /collect/:targetUUID` 单条状态查询:
|
||
|
||
- 返回当前用户是否已收藏(`is_collected`)与该穿搭收藏总数(`collect_count`)
|
||
- Redis 优先、异常回落 MySQL,与点赞查询策略严格对称
|
||
- 校验穿搭存在性与可见性(非本人仅可查询公开可见穿搭)
|
||
|
||
## 技术栈
|
||
|
||
- Go 1.27 + Gin + GORM + go-redis,沿用现有分层(handler → service → dao / redisdao)
|
||
- 复用现有收藏底层能力,不新增 DAO/Redis 方法
|
||
|
||
## 实现方式
|
||
|
||
严格对齐点赞 `GET /like/:targetUUID` 的实现模式,新增收藏单条状态查询链路。
|
||
|
||
### 关键决策
|
||
|
||
- **字段命名对称**:点赞 `is_liked`/`like_count`,收藏用 `is_collected`/`collect_count`。
|
||
- **路径参数命名对齐**:`targetUUID`(驼峰,与点赞一致),避免前端两套传参方式不一致。
|
||
- **回落策略一致**:是否已收藏与收藏总数均 Redis 优先;Redis 出错或计数为 0 时回落 MySQL 兜底,保证缓存冷启动/漂移时数据正确。
|
||
- **仅新增不改旧**:收藏的收藏/取消与列表逻辑保持不动,降低回归风险。
|
||
|
||
### 数据流
|
||
|
||
`GET /collect/:targetUUID` → handler 取 `targetUUID` → service 校验穿搭(存在 + 可见性)→ Redis 查收藏状态/计数 → 异常回落 MySQL → 返回 `{is_collected, collect_count}`
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
zt-closet-backend/
|
||
├── internal/
|
||
│ ├── dto/
|
||
│ │ └── collect.go # [MODIFY] 新增 CollectGetByTargetRequest/Response
|
||
│ ├── service/
|
||
│ │ └── collect.go # [MODIFY] 新增 GetByTarget 方法
|
||
│ └── routers/
|
||
│ ├── router.go # [MODIFY] 注册 GET /collect/:targetUUID
|
||
│ └── api/v1/
|
||
│ └── collect.go # [MODIFY] 新增 GetByTarget handler
|
||
├── README.md # [MODIFY] API 概览收藏小节新增接口行
|
||
└── 接口文档.md # [MODIFY] 接口总表与 5.8 节新增接口说明
|
||
```
|
||
|
||
## 实现细节
|
||
|
||
- DTO 定义与点赞完全对应:`CollectGetByTargetRequest{ TargetUUID string json:"target_uuid" binding:"required" }`、`CollectGetByTargetResponse{ UserIsCollected bool json:"is_collected"; CollectCount int64 json:"collect_count" }`。
|
||
- Service `GetByTarget` 内部逻辑:先 `OutfitGetByUUID`(不存在返回 `TargetNotFound`、非本人且未公开返回 `OutfitNoPermission`),再取 `targetID`,随后 `CollectIsMember`(Redis 优先,err 回落 `CollectGetByTargetAndUser` 判断 `Status == InteractStatusOn`),最后 `CollectCount`(Redis 优先,`err != nil || count == 0` 回落 `CollectCountByTarget`)。
|
||
- Handler 与路由均对齐点赞:path 参数 `targetUUID`,空值返回 `InvalidParams`;路由注册在鉴权组内,`/collect`(精确路径)与 `/collect/:targetUUID`(参数路径)在 Gin 路由树中可共存。 |