feat: 重构内容列表接口,使用过滤器结构体简化参数传递;更新相关服务和测试用例

This commit is contained in:
2025-12-29 15:04:55 +08:00
parent 8c4bc55f45
commit fba77afec1
14 changed files with 65 additions and 60 deletions

View File

@@ -25,17 +25,12 @@ type Content struct{}
// @Param sort query string false "Sort order" Enums(latest, hot, price_asc) // @Param sort query string false "Sort order" Enums(latest, hot, price_asc)
// @Param page query int false "Page number" // @Param page query int false "Page number"
// @Success 200 {object} requests.Pager{items=[]dto.ContentItem} // @Success 200 {object} requests.Pager{items=[]dto.ContentItem}
// @Bind keyword query // @Bind filter query
// @Bind genre query
// @Bind tenantId query
// @Bind sort query
// @Bind page query
func (c *Content) List( func (c *Content) List(
ctx fiber.Ctx, ctx fiber.Ctx,
keyword, genre, tenantId, sort string, filter *dto.ContentListFilter,
page int,
) (*requests.Pager, error) { ) (*requests.Pager, error) {
return services.Content.List(ctx.Context(), keyword, genre, tenantId, sort, page) return services.Content.List(ctx.Context(), filter)
} }
// Get content detail // Get content detail

View File

@@ -1,5 +1,15 @@
package dto package dto
import "quyun/v2/app/requests"
type ContentListFilter struct {
requests.Pagination
Keyword string `query:"keyword"`
Genre string `query:"genre"`
TenantID string `query:"tenantId"`
Sort string `query:"sort"`
}
type ContentItem struct { type ContentItem struct {
ID string `json:"id"` ID string `json:"id"`
Title string `json:"title"` Title string `json:"title"`

View File

@@ -69,13 +69,9 @@ func (r *Routes) Register(router fiber.Router) {
)) ))
// Register routes for controller: Content // Register routes for controller: Content
r.log.Debugf("Registering route: Get /v1/contents -> content.List") r.log.Debugf("Registering route: Get /v1/contents -> content.List")
router.Get("/v1/contents"[len(r.Path()):], DataFunc5( router.Get("/v1/contents"[len(r.Path()):], DataFunc1(
r.content.List, r.content.List,
QueryParam[string]("keyword"), Query[dto.ContentListFilter]("filter"),
QueryParam[string]("genre"),
QueryParam[string]("tenantId"),
QueryParam[string]("sort"),
QueryParam[int]("page"),
)) ))
r.log.Debugf("Registering route: Get /v1/contents/:id -> content.Get") r.log.Debugf("Registering route: Get /v1/contents/:id -> content.Get")
router.Get("/v1/contents/:id"[len(r.Path()):], DataFunc1( router.Get("/v1/contents/:id"[len(r.Path()):], DataFunc1(

View File

@@ -18,19 +18,19 @@ import (
// @provider // @provider
type content struct{} type content struct{}
func (s *content) List(ctx context.Context, keyword, genre, tenantId, sort string, page int) (*requests.Pager, error) { func (s *content) List(ctx context.Context, filter *content_dto.ContentListFilter) (*requests.Pager, error) {
tbl, q := models.ContentQuery.QueryContext(ctx) tbl, q := models.ContentQuery.QueryContext(ctx)
// Filters // Filters
q = q.Where(tbl.Status.Eq(consts.ContentStatusPublished)) q = q.Where(tbl.Status.Eq(consts.ContentStatusPublished))
if keyword != "" { if filter.Keyword != "" {
q = q.Where(tbl.Title.Like("%" + keyword + "%")) q = q.Where(tbl.Title.Like("%" + filter.Keyword + "%"))
} }
if genre != "" { if filter.Genre != "" {
q = q.Where(tbl.Genre.Eq(genre)) q = q.Where(tbl.Genre.Eq(filter.Genre))
} }
if tenantId != "" { if filter.TenantID != "" {
tid := cast.ToInt64(tenantId) tid := cast.ToInt64(filter.TenantID)
q = q.Where(tbl.TenantID.Eq(tid)) q = q.Where(tbl.TenantID.Eq(tid))
} }
@@ -38,7 +38,7 @@ func (s *content) List(ctx context.Context, keyword, genre, tenantId, sort strin
q = q.Preload(tbl.Author) q = q.Preload(tbl.Author)
// Sort // Sort
switch sort { switch filter.Sort {
case "hot": case "hot":
q = q.Order(tbl.Views.Desc()) q = q.Order(tbl.Views.Desc())
case "price_asc": case "price_asc":
@@ -48,13 +48,14 @@ func (s *content) List(ctx context.Context, keyword, genre, tenantId, sort strin
} }
// Pagination // Pagination
p := requests.Pagination{Page: int64(page), Limit: 10} // Use embedded pagination directly
filter.Pagination.Format()
total, err := q.Count() total, err := q.Count()
if err != nil { if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err) return nil, errorx.ErrDatabaseError.WithCause(err)
} }
list, err := q.Offset(int(p.Offset())).Limit(int(p.Limit)).Find() list, err := q.Offset(int(filter.Pagination.Offset())).Limit(int(filter.Pagination.Limit)).Find()
if err != nil { if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err) return nil, errorx.ErrDatabaseError.WithCause(err)
} }
@@ -66,10 +67,7 @@ func (s *content) List(ctx context.Context, keyword, genre, tenantId, sort strin
} }
return &requests.Pager{ return &requests.Pager{
Pagination: requests.Pagination{ Pagination: filter.Pagination,
Page: p.Page,
Limit: p.Limit,
},
Total: total, Total: total,
Items: data, Items: data,
}, nil }, nil

View File

@@ -7,6 +7,7 @@ import (
"quyun/v2/app/commands/testx" "quyun/v2/app/commands/testx"
content_dto "quyun/v2/app/http/v1/dto" content_dto "quyun/v2/app/http/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/database" "quyun/v2/database"
"quyun/v2/database/models" "quyun/v2/database/models"
"quyun/v2/pkg/consts" "quyun/v2/pkg/consts"
@@ -65,7 +66,14 @@ func (s *ContentTestSuite) Test_List() {
models.ContentQuery.WithContext(ctx).Create(c1, c2) models.ContentQuery.WithContext(ctx).Create(c1, c2)
Convey("should list only published contents", func() { Convey("should list only published contents", func() {
res, err := Content.List(ctx, "", "", "1", "", 1) filter := &content_dto.ContentListFilter{
TenantID: "1",
Pagination: requests.Pagination{
Page: 1,
Limit: 10,
},
}
res, err := Content.List(ctx, filter)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(res.Total, ShouldEqual, 1) So(res.Total, ShouldEqual, 1)
items := res.Items.([]content_dto.ContentItem) items := res.Items.([]content_dto.ContentItem)

View File

@@ -159,7 +159,6 @@ func (s *order) payWithBalance(ctx context.Context, o *models.Order) (*transacti
info, err := tx.User.WithContext(ctx). info, err := tx.User.WithContext(ctx).
Where(tx.User.ID.Eq(o.UserID), tx.User.Balance.Gte(o.AmountPaid)). Where(tx.User.ID.Eq(o.UserID), tx.User.Balance.Gte(o.AmountPaid)).
Update(tx.User.Balance, gorm.Expr("balance - ?", o.AmountPaid)) Update(tx.User.Balance, gorm.Expr("balance - ?", o.AmountPaid))
if err != nil { if err != nil {
return err return err
} }
@@ -218,7 +217,6 @@ func (s *order) payWithBalance(ctx context.Context, o *models.Order) (*transacti
return nil return nil
}) })
if err != nil { if err != nil {
if _, ok := err.(*errorx.AppError); ok { if _, ok := err.(*errorx.AppError); ok {
return nil, err return nil, err