This commit is contained in:
toom1996
2026-09-02 21:51:35 +08:00
parent 2562fc4aaa
commit 1fd9c48f58
22 changed files with 908 additions and 30 deletions

View File

@ -0,0 +1,119 @@
package handler
import (
"net/http"
"strconv"
"fashionapi/internal/dto"
"fashionapi/internal/middleware"
"fashionapi/internal/pkg/response"
"fashionapi/internal/service"
"github.com/gin-gonic/gin"
)
// FavoriteHandler 收藏接口(需 Bearer 鉴权,挂在 /api/v1/auth 下)。
type FavoriteHandler struct {
favs service.FavoriteService
}
// NewFavoriteHandler 创建收藏 handler。
func NewFavoriteHandler(favs service.FavoriteService) *FavoriteHandler {
return &FavoriteHandler{favs: favs}
}
// List 当前用户收藏(服务端分页)。
//
// GET /api/v1/auth/favorites?page=1&per_page=24(per_page 上限 100)
// 成功:200 { data: { items:[...], total, last_page } }
func (h *FavoriteHandler) List(c *gin.Context) {
userID, ok := middleware.UserIDFrom(c)
if !ok {
response.Error(c, http.StatusUnauthorized, "unauthorized")
return
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
perPage, _ := strconv.Atoi(c.DefaultQuery("per_page", "24"))
if page < 1 {
page = 1
}
if perPage < 1 || perPage > 100 {
perPage = 24
}
items, total, err := h.favs.ListPaged(c.Request.Context(), userID, page, perPage)
if err != nil {
fail(c, err)
return
}
response.Data(c, http.StatusOK, gin.H{
"items": items,
"total": total,
"last_page": response.LastPage(total, perPage),
})
}
// Add 新增收藏(幂等:重复添加不报错)。
//
// POST /api/v1/auth/favorites
// body: { target_type, target_uid, title?, cover?, brand? }
// 成功:200 { data: <FavoriteItem> }
func (h *FavoriteHandler) Add(c *gin.Context) {
userID, ok := middleware.UserIDFrom(c)
if !ok {
response.Error(c, http.StatusUnauthorized, "unauthorized")
return
}
var req dto.FavoriteAdd
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, http.StatusBadRequest, "invalid request")
return
}
item, err := h.favs.Add(c.Request.Context(), userID, req)
if err != nil {
fail(c, err)
return
}
response.Data(c, http.StatusOK, item)
}
// Remove 删除收藏。
//
// DELETE /api/v1/auth/favorites/:target_uid
// 成功:200 { data: { ok: true } }
func (h *FavoriteHandler) Remove(c *gin.Context) {
userID, ok := middleware.UserIDFrom(c)
if !ok {
response.Error(c, http.StatusUnauthorized, "unauthorized")
return
}
uid := c.Param("target_uid")
if err := h.favs.Remove(c.Request.Context(), userID, uid); err != nil {
fail(c, err)
return
}
response.Data(c, http.StatusOK, gin.H{"ok": true})
}
// Check 批量查询给定 ids 中哪些已收藏(列表页打勾用,与收藏总量解耦)。
//
// POST /api/v1/auth/favorites/check
// body: { ids: ["r=...","s=..."] }
// 成功:200 { data: ["r=..."] }(仅返回已收藏的 id)
func (h *FavoriteHandler) Check(c *gin.Context) {
userID, ok := middleware.UserIDFrom(c)
if !ok {
response.Error(c, http.StatusUnauthorized, "unauthorized")
return
}
var req dto.FavoriteCheck
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, http.StatusBadRequest, "invalid request")
return
}
ids, err := h.favs.Check(c.Request.Context(), userID, req.IDs)
if err != nil {
fail(c, err)
return
}
response.Data(c, http.StatusOK, ids)
}