feat: 添加点赞和收藏功能,优化内容详情视图和评论交互

This commit is contained in:
2026-01-07 14:43:52 +08:00
parent f355b26920
commit 1298192157
6 changed files with 316 additions and 57 deletions

View File

@@ -47,7 +47,7 @@ func (c *Content) List(
// @Success 200 {object} dto.ContentDetail
// @Bind id path
func (c *Content) Get(ctx fiber.Ctx, id string) (*dto.ContentDetail, error) {
uid := cast.ToInt64(ctx.Locals(consts.CtxKeyUser))
uid := getUserID(ctx)
return services.Content.Get(ctx, uid, id)
}
@@ -65,7 +65,7 @@ func (c *Content) Get(ctx fiber.Ctx, id string) (*dto.ContentDetail, error) {
// @Bind id path
// @Bind page query
func (c *Content) ListComments(ctx fiber.Ctx, id string, page int) (*requests.Pager, error) {
uid := cast.ToInt64(ctx.Locals(consts.CtxKeyUser))
uid := getUserID(ctx)
return services.Content.ListComments(ctx, uid, id, page)
}
@@ -83,7 +83,7 @@ func (c *Content) ListComments(ctx fiber.Ctx, id string, page int) (*requests.Pa
// @Bind id path
// @Bind form body
func (c *Content) CreateComment(ctx fiber.Ctx, id string, form *dto.CommentCreateForm) error {
uid := cast.ToInt64(ctx.Locals(consts.CtxKeyUser))
uid := getUserID(ctx)
return services.Content.CreateComment(ctx, uid, id, form)
}
@@ -99,10 +99,62 @@ func (c *Content) CreateComment(ctx fiber.Ctx, id string, form *dto.CommentCreat
// @Success 200 {string} string "Liked"
// @Bind id path
func (c *Content) LikeComment(ctx fiber.Ctx, id string) error {
uid := cast.ToInt64(ctx.Locals(consts.CtxKeyUser))
uid := getUserID(ctx)
return services.Content.LikeComment(ctx, uid, id)
}
// Add like
//
// @Router /v1/contents/:id/like [post]
// @Summary Add like
// @Tags Content
// @Param id path string true "Content ID"
// @Success 200 {string} string "Liked"
// @Bind id path
func (c *Content) AddLike(ctx fiber.Ctx, id string) error {
uid := getUserID(ctx)
return services.Content.AddLike(ctx, uid, id)
}
// Remove like
//
// @Router /v1/contents/:id/like [delete]
// @Summary Remove like
// @Tags Content
// @Param id path string true "Content ID"
// @Success 200 {string} string "Unliked"
// @Bind id path
func (c *Content) RemoveLike(ctx fiber.Ctx, id string) error {
uid := getUserID(ctx)
return services.Content.RemoveLike(ctx, uid, id)
}
// Add favorite
//
// @Router /v1/contents/:id/favorite [post]
// @Summary Add favorite
// @Tags Content
// @Param id path string true "Content ID"
// @Success 200 {string} string "Favorited"
// @Bind id path
func (c *Content) AddFavorite(ctx fiber.Ctx, id string) error {
uid := getUserID(ctx)
return services.Content.AddFavorite(ctx, uid, id)
}
// Remove favorite
//
// @Router /v1/contents/:id/favorite [delete]
// @Summary Remove favorite
// @Tags Content
// @Param id path string true "Content ID"
// @Success 200 {string} string "Unfavorited"
// @Bind id path
func (c *Content) RemoveFavorite(ctx fiber.Ctx, id string) error {
uid := getUserID(ctx)
return services.Content.RemoveFavorite(ctx, uid, id)
}
// List curated topics
//
// @Router /v1/topics [get]
@@ -115,3 +167,12 @@ func (c *Content) LikeComment(ctx fiber.Ctx, id string) error {
func (c *Content) ListTopics(ctx fiber.Ctx) ([]dto.Topic, error) {
return services.Content.ListTopics(ctx)
}
func getUserID(ctx fiber.Ctx) int64 {
if u := ctx.Locals(consts.CtxKeyUser); u != nil {
if user, ok := u.(*models.User); ok {
return user.ID
}
}
return 0
}

View File

@@ -12,19 +12,20 @@ type ContentListFilter struct {
}
type ContentItem struct {
ID string `json:"id"`
Title string `json:"title"`
Cover string `json:"cover"`
Genre string `json:"genre"`
Type string `json:"type"` // video, audio, article
Price float64 `json:"price"`
AuthorID string `json:"author_id"`
AuthorName string `json:"author_name"`
AuthorAvatar string `json:"author_avatar"`
Views int `json:"views"`
Likes int `json:"likes"`
CreatedAt string `json:"created_at"`
IsPurchased bool `json:"is_purchased"`
ID string `json:"id"`
Title string `json:"title"`
Cover string `json:"cover"`
Genre string `json:"genre"`
Type string `json:"type"` // video, audio, article
Price float64 `json:"price"`
AuthorID string `json:"author_id"`
AuthorName string `json:"author_name"`
AuthorAvatar string `json:"author_avatar"`
AuthorIsFollowing bool `json:"author_is_following"`
Views int `json:"views"`
Likes int `json:"likes"`
CreatedAt string `json:"created_at"`
IsPurchased bool `json:"is_purchased"`
}
type ContentDetail struct {

View File

@@ -99,6 +99,16 @@ func (r *Routes) Register(router fiber.Router) {
Body[dto.UploadPartForm]("form"),
))
// Register routes for controller: Content
r.log.Debugf("Registering route: Delete /v1/contents/:id/favorite -> content.RemoveFavorite")
router.Delete("/v1/contents/:id/favorite"[len(r.Path()):], Func1(
r.content.RemoveFavorite,
PathParam[string]("id"),
))
r.log.Debugf("Registering route: Delete /v1/contents/:id/like -> content.RemoveLike")
router.Delete("/v1/contents/:id/like"[len(r.Path()):], Func1(
r.content.RemoveLike,
PathParam[string]("id"),
))
r.log.Debugf("Registering route: Get /v1/contents -> content.List")
router.Get("/v1/contents"[len(r.Path()):], DataFunc1(
r.content.List,
@@ -130,6 +140,16 @@ func (r *Routes) Register(router fiber.Router) {
PathParam[string]("id"),
Body[dto.CommentCreateForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/contents/:id/favorite -> content.AddFavorite")
router.Post("/v1/contents/:id/favorite"[len(r.Path()):], Func1(
r.content.AddFavorite,
PathParam[string]("id"),
))
r.log.Debugf("Registering route: Post /v1/contents/:id/like -> content.AddLike")
router.Post("/v1/contents/:id/like"[len(r.Path()):], Func1(
r.content.AddLike,
PathParam[string]("id"),
))
// Register routes for controller: Creator
r.log.Debugf("Registering route: Delete /v1/creator/contents/:id -> creator.DeleteContent")
router.Delete("/v1/creator/contents/:id"[len(r.Path()):], Func2(