feat: 重构内容和订单列表接口,使用过滤器结构体简化参数传递;更新相关服务和测试用例
This commit is contained in:
@@ -23,14 +23,14 @@ func (s *content) List(ctx context.Context, filter *content_dto.ContentListFilte
|
||||
|
||||
// Filters
|
||||
q = q.Where(tbl.Status.Eq(consts.ContentStatusPublished))
|
||||
if filter.Keyword != "" {
|
||||
q = q.Where(tbl.Title.Like("%" + filter.Keyword + "%"))
|
||||
if filter.Keyword != nil && *filter.Keyword != "" {
|
||||
q = q.Where(tbl.Title.Like("%" + *filter.Keyword + "%"))
|
||||
}
|
||||
if filter.Genre != "" {
|
||||
q = q.Where(tbl.Genre.Eq(filter.Genre))
|
||||
if filter.Genre != nil && *filter.Genre != "" {
|
||||
q = q.Where(tbl.Genre.Eq(*filter.Genre))
|
||||
}
|
||||
if filter.TenantID != "" {
|
||||
tid := cast.ToInt64(filter.TenantID)
|
||||
if filter.TenantID != nil && *filter.TenantID != "" {
|
||||
tid := cast.ToInt64(*filter.TenantID)
|
||||
q = q.Where(tbl.TenantID.Eq(tid))
|
||||
}
|
||||
|
||||
@@ -38,7 +38,12 @@ func (s *content) List(ctx context.Context, filter *content_dto.ContentListFilte
|
||||
q = q.Preload(tbl.Author)
|
||||
|
||||
// Sort
|
||||
switch filter.Sort {
|
||||
sort := "latest"
|
||||
if filter.Sort != nil && *filter.Sort != "" {
|
||||
sort = *filter.Sort
|
||||
}
|
||||
|
||||
switch sort {
|
||||
case "hot":
|
||||
q = q.Order(tbl.Views.Desc())
|
||||
case "price_asc":
|
||||
@@ -48,7 +53,6 @@ func (s *content) List(ctx context.Context, filter *content_dto.ContentListFilte
|
||||
}
|
||||
|
||||
// Pagination
|
||||
// Use embedded pagination directly
|
||||
filter.Pagination.Format()
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
|
||||
@@ -66,8 +66,9 @@ func (s *ContentTestSuite) Test_List() {
|
||||
models.ContentQuery.WithContext(ctx).Create(c1, c2)
|
||||
|
||||
Convey("should list only published contents", func() {
|
||||
tid := "1"
|
||||
filter := &content_dto.ContentListFilter{
|
||||
TenantID: "1",
|
||||
TenantID: &tid,
|
||||
Pagination: requests.Pagination{
|
||||
Page: 1,
|
||||
Limit: 10,
|
||||
|
||||
@@ -80,7 +80,7 @@ func (s *creator) Dashboard(ctx context.Context) (*creator_dto.DashboardStats, e
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
func (s *creator) ListContents(ctx context.Context, status, genre, keyword string) ([]creator_dto.ContentItem, error) {
|
||||
func (s *creator) ListContents(ctx context.Context, filter *creator_dto.CreatorContentListFilter) ([]creator_dto.ContentItem, error) {
|
||||
tid, err := s.getTenantID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -89,14 +89,14 @@ func (s *creator) ListContents(ctx context.Context, status, genre, keyword strin
|
||||
tbl, q := models.ContentQuery.QueryContext(ctx)
|
||||
q = q.Where(tbl.TenantID.Eq(tid))
|
||||
|
||||
if status != "" {
|
||||
q = q.Where(tbl.Status.Eq(consts.ContentStatus(status)))
|
||||
if filter.Status != nil && *filter.Status != "" {
|
||||
q = q.Where(tbl.Status.Eq(consts.ContentStatus(*filter.Status)))
|
||||
}
|
||||
if genre != "" {
|
||||
q = q.Where(tbl.Genre.Eq(genre))
|
||||
if filter.Genre != nil && *filter.Genre != "" {
|
||||
q = q.Where(tbl.Genre.Eq(*filter.Genre))
|
||||
}
|
||||
if keyword != "" {
|
||||
q = q.Where(tbl.Title.Like("%" + keyword + "%"))
|
||||
if filter.Keyword != nil && *filter.Keyword != "" {
|
||||
q = q.Where(tbl.Title.Like("%" + *filter.Keyword + "%"))
|
||||
}
|
||||
|
||||
list, err := q.Order(tbl.CreatedAt.Desc()).Find()
|
||||
@@ -190,7 +190,7 @@ func (s *creator) DeleteContent(ctx context.Context, id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *creator) ListOrders(ctx context.Context, status, keyword string) ([]creator_dto.Order, error) {
|
||||
func (s *creator) ListOrders(ctx context.Context, filter *creator_dto.CreatorOrderListFilter) ([]creator_dto.Order, error) {
|
||||
tid, err := s.getTenantID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -198,7 +198,12 @@ func (s *creator) ListOrders(ctx context.Context, status, keyword string) ([]cre
|
||||
|
||||
tbl, q := models.OrderQuery.QueryContext(ctx)
|
||||
q = q.Where(tbl.TenantID.Eq(tid))
|
||||
// Filters...
|
||||
|
||||
if filter.Status != nil && *filter.Status != "" {
|
||||
q = q.Where(tbl.Status.Eq(consts.OrderStatus(*filter.Status)))
|
||||
}
|
||||
// Keyword could match ID or other fields if needed
|
||||
|
||||
list, err := q.Order(tbl.CreatedAt.Desc()).Find()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
|
||||
@@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"quyun/v2/app/errorx"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/cast"
|
||||
"go.ipao.vip/gen/types"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// @provider
|
||||
@@ -27,33 +29,31 @@ func (s *super) CheckToken(ctx context.Context) (*super_dto.LoginResponse, error
|
||||
return &super_dto.LoginResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *super) ListUsers(ctx context.Context, page, limit int, username string) (*requests.Pager, error) {
|
||||
func (s *super) ListUsers(ctx context.Context, filter *super_dto.UserListFilter) (*requests.Pager, error) {
|
||||
tbl, q := models.UserQuery.QueryContext(ctx)
|
||||
if username != "" {
|
||||
q = q.Where(tbl.Username.Like("%" + username + "%")).Or(tbl.Nickname.Like("%" + username + "%"))
|
||||
if filter.Username != nil && *filter.Username != "" {
|
||||
q = q.Where(tbl.Username.Like("%" + *filter.Username + "%")).Or(tbl.Nickname.Like("%" + *filter.Username + "%"))
|
||||
}
|
||||
|
||||
p := requests.Pagination{Page: int64(page), Limit: int64(limit)}
|
||||
filter.Pagination.Format()
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
|
||||
list, err := q.Offset(int(p.Offset())).Limit(int(p.Limit)).Order(tbl.ID.Desc()).Find()
|
||||
list, err := q.Offset(int(filter.Pagination.Offset())).Limit(int(filter.Pagination.Limit)).Order(tbl.ID.Desc()).Find()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
|
||||
var data []super_dto.UserItem
|
||||
for _, u := range list {
|
||||
data = append(data, super_dto.UserItem{
|
||||
SuperUserLite: super_dto.SuperUserLite{
|
||||
ID: u.ID,
|
||||
Username: u.Username,
|
||||
Roles: u.Roles,
|
||||
Status: u.Status,
|
||||
// StatusDescription: u.Status.Description(), // Status is consts.UserStatus, it has Description()
|
||||
// But u.Status might be string if gen didn't map it properly? No, it's consts.UserStatus.
|
||||
ID: u.ID,
|
||||
Username: u.Username,
|
||||
Roles: u.Roles,
|
||||
Status: u.Status,
|
||||
StatusDescription: u.Status.Description(),
|
||||
CreatedAt: u.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: u.UpdatedAt.Format(time.RFC3339),
|
||||
@@ -64,7 +64,7 @@ func (s *super) ListUsers(ctx context.Context, page, limit int, username string)
|
||||
}
|
||||
|
||||
return &requests.Pager{
|
||||
Pagination: p,
|
||||
Pagination: filter.Pagination,
|
||||
Total: total,
|
||||
Items: data,
|
||||
}, nil
|
||||
@@ -74,7 +74,10 @@ func (s *super) GetUser(ctx context.Context, id int64) (*super_dto.UserItem, err
|
||||
tbl, q := models.UserQuery.QueryContext(ctx)
|
||||
u, err := q.Where(tbl.ID.Eq(id)).First()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrRecordNotFound
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errorx.ErrRecordNotFound
|
||||
}
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
return &super_dto.UserItem{
|
||||
SuperUserLite: super_dto.SuperUserLite{
|
||||
@@ -95,7 +98,7 @@ func (s *super) UpdateUserStatus(ctx context.Context, id int64, form *super_dto.
|
||||
tbl, q := models.UserQuery.QueryContext(ctx)
|
||||
_, err := q.Where(tbl.ID.Eq(id)).Update(tbl.Status, consts.UserStatus(form.Status))
|
||||
if err != nil {
|
||||
return errorx.ErrDatabaseError
|
||||
return errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -108,26 +111,26 @@ func (s *super) UpdateUserRoles(ctx context.Context, id int64, form *super_dto.U
|
||||
tbl, q := models.UserQuery.QueryContext(ctx)
|
||||
_, err := q.Where(tbl.ID.Eq(id)).Update(tbl.Roles, roles)
|
||||
if err != nil {
|
||||
return errorx.ErrDatabaseError
|
||||
return errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *super) ListTenants(ctx context.Context, page, limit int, name string) (*requests.Pager, error) {
|
||||
func (s *super) ListTenants(ctx context.Context, filter *super_dto.TenantListFilter) (*requests.Pager, error) {
|
||||
tbl, q := models.TenantQuery.QueryContext(ctx)
|
||||
if name != "" {
|
||||
q = q.Where(tbl.Name.Like("%" + name + "%"))
|
||||
if filter.Name != nil && *filter.Name != "" {
|
||||
q = q.Where(tbl.Name.Like("%" + *filter.Name + "%"))
|
||||
}
|
||||
|
||||
p := requests.Pagination{Page: int64(page), Limit: int64(limit)}
|
||||
filter.Pagination.Format()
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
|
||||
list, err := q.Offset(int(p.Offset())).Limit(int(p.Limit)).Order(tbl.ID.Desc()).Find()
|
||||
list, err := q.Offset(int(filter.Pagination.Offset())).Limit(int(filter.Pagination.Limit)).Order(tbl.ID.Desc()).Find()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
|
||||
var data []super_dto.TenantItem
|
||||
@@ -146,7 +149,7 @@ func (s *super) ListTenants(ctx context.Context, page, limit int, name string) (
|
||||
}
|
||||
|
||||
return &requests.Pager{
|
||||
Pagination: p,
|
||||
Pagination: filter.Pagination,
|
||||
Total: total,
|
||||
Items: data,
|
||||
}, nil
|
||||
@@ -166,7 +169,7 @@ func (s *super) CreateTenant(ctx context.Context, form *super_dto.TenantCreateFo
|
||||
Status: consts.TenantStatusVerified,
|
||||
}
|
||||
if err := models.TenantQuery.WithContext(ctx).Create(t); err != nil {
|
||||
return errorx.ErrDatabaseError
|
||||
return errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -175,7 +178,10 @@ func (s *super) GetTenant(ctx context.Context, id int64) (*super_dto.TenantItem,
|
||||
tbl, q := models.TenantQuery.QueryContext(ctx)
|
||||
t, err := q.Where(tbl.ID.Eq(id)).First()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrRecordNotFound
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errorx.ErrRecordNotFound
|
||||
}
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
return &super_dto.TenantItem{
|
||||
ID: t.ID,
|
||||
@@ -194,7 +200,7 @@ func (s *super) UpdateTenantStatus(ctx context.Context, id int64, form *super_dt
|
||||
tbl, q := models.TenantQuery.QueryContext(ctx)
|
||||
_, err := q.Where(tbl.ID.Eq(id)).Update(tbl.Status, consts.TenantStatus(form.Status))
|
||||
if err != nil {
|
||||
return errorx.ErrDatabaseError
|
||||
return errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -204,21 +210,22 @@ func (s *super) UpdateTenantExpire(ctx context.Context, id int64, form *super_dt
|
||||
tbl, q := models.TenantQuery.QueryContext(ctx)
|
||||
_, err := q.Where(tbl.ID.Eq(id)).Update(tbl.ExpiredAt, expire)
|
||||
if err != nil {
|
||||
return errorx.ErrDatabaseError
|
||||
return errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *super) ListContents(ctx context.Context, page, limit int) (*requests.Pager, error) {
|
||||
func (s *super) ListContents(ctx context.Context, filter *super_dto.SuperContentListFilter) (*requests.Pager, error) {
|
||||
tbl, q := models.ContentQuery.QueryContext(ctx)
|
||||
p := requests.Pagination{Page: int64(page), Limit: int64(limit)}
|
||||
|
||||
filter.Pagination.Format()
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
list, err := q.Offset(int(p.Offset())).Limit(int(p.Limit)).Order(tbl.ID.Desc()).Find()
|
||||
list, err := q.Offset(int(filter.Pagination.Offset())).Limit(int(filter.Pagination.Limit)).Order(tbl.ID.Desc()).Find()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
// Simplified DTO for list
|
||||
var data []any
|
||||
@@ -226,7 +233,7 @@ func (s *super) ListContents(ctx context.Context, page, limit int) (*requests.Pa
|
||||
data = append(data, c) // TODO: Map to DTO
|
||||
}
|
||||
return &requests.Pager{
|
||||
Pagination: p,
|
||||
Pagination: filter.Pagination,
|
||||
Total: total,
|
||||
Items: data,
|
||||
}, nil
|
||||
@@ -236,25 +243,26 @@ func (s *super) UpdateContentStatus(ctx context.Context, tenantID, contentID int
|
||||
tbl, q := models.ContentQuery.QueryContext(ctx)
|
||||
_, err := q.Where(tbl.ID.Eq(contentID), tbl.TenantID.Eq(tenantID)).Update(tbl.Status, consts.ContentStatus(form.Status))
|
||||
if err != nil {
|
||||
return errorx.ErrDatabaseError
|
||||
return errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *super) ListOrders(ctx context.Context, page, limit int) (*requests.Pager, error) {
|
||||
func (s *super) ListOrders(ctx context.Context, filter *super_dto.SuperOrderListFilter) (*requests.Pager, error) {
|
||||
tbl, q := models.OrderQuery.QueryContext(ctx)
|
||||
p := requests.Pagination{Page: int64(page), Limit: int64(limit)}
|
||||
|
||||
filter.Pagination.Format()
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
list, err := q.Offset(int(p.Offset())).Limit(int(p.Limit)).Order(tbl.ID.Desc()).Find()
|
||||
list, err := q.Offset(int(filter.Pagination.Offset())).Limit(int(filter.Pagination.Limit)).Order(tbl.ID.Desc()).Find()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrDatabaseError
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
// TODO: Map to DTO
|
||||
return &requests.Pager{
|
||||
Pagination: p,
|
||||
Pagination: filter.Pagination,
|
||||
Total: total,
|
||||
Items: list,
|
||||
}, nil
|
||||
|
||||
@@ -6,10 +6,12 @@ import (
|
||||
|
||||
"quyun/v2/app/commands/testx"
|
||||
super_dto "quyun/v2/app/http/v1/dto"
|
||||
"quyun/v2/app/requests"
|
||||
"quyun/v2/database"
|
||||
"quyun/v2/database/models"
|
||||
"quyun/v2/pkg/consts"
|
||||
|
||||
"github.com/samber/lo"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
@@ -46,16 +48,23 @@ func (s *SuperTestSuite) Test_ListUsers() {
|
||||
models.UserQuery.WithContext(ctx).Create(u1, u2)
|
||||
|
||||
Convey("should list users", func() {
|
||||
res, err := Super.ListUsers(ctx, 1, 10, "")
|
||||
filter := &super_dto.UserListFilter{
|
||||
Pagination: requests.Pagination{Page: 1, Limit: 10},
|
||||
}
|
||||
res, err := Super.ListUsers(ctx, filter)
|
||||
So(err, ShouldBeNil)
|
||||
So(res.Total, ShouldEqual, 2)
|
||||
|
||||
|
||||
items := res.Items.([]super_dto.UserItem)
|
||||
So(items[0].Username, ShouldEqual, "user2") // Desc order
|
||||
})
|
||||
|
||||
Convey("should filter users", func() {
|
||||
res, err := Super.ListUsers(ctx, 1, 10, "Alice")
|
||||
filter := &super_dto.UserListFilter{
|
||||
Pagination: requests.Pagination{Page: 1, Limit: 10},
|
||||
Username: lo.ToPtr("Alice"),
|
||||
}
|
||||
res, err := Super.ListUsers(ctx, filter)
|
||||
So(err, ShouldBeNil)
|
||||
So(res.Total, ShouldEqual, 1)
|
||||
items := res.Items.([]super_dto.UserItem)
|
||||
@@ -88,4 +97,4 @@ func (s *SuperTestSuite) Test_CreateTenant() {
|
||||
So(t.Status, ShouldEqual, consts.TenantStatusVerified)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user