feat: map super content list

This commit is contained in:
2026-01-08 11:05:37 +08:00
parent 87b32063f6
commit 8c8e712cbb

View File

@@ -7,7 +7,7 @@ import (
"quyun/v2/app/errorx" "quyun/v2/app/errorx"
super_dto "quyun/v2/app/http/super/v1/dto" super_dto "quyun/v2/app/http/super/v1/dto"
creator_dto "quyun/v2/app/http/v1/dto" v1_dto "quyun/v2/app/http/v1/dto"
"quyun/v2/app/requests" "quyun/v2/app/requests"
"quyun/v2/database/models" "quyun/v2/database/models"
"quyun/v2/pkg/consts" "quyun/v2/pkg/consts"
@@ -279,14 +279,24 @@ func (s *super) ListContents(ctx context.Context, filter *super_dto.SuperContent
if err != nil { if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err) return nil, errorx.ErrDatabaseError.WithCause(err)
} }
list, err := q.Offset(int(filter.Pagination.Offset())).Limit(int(filter.Pagination.Limit)).Order(tbl.ID.Desc()).Find() var list []*models.Content
err = q.Offset(int(filter.Pagination.Offset())).Limit(int(filter.Pagination.Limit)).Order(tbl.ID.Desc()).
UnderlyingDB().
Preload("Author").
Preload("ContentAssets.Asset").
Find(&list).Error
if err != nil { if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err) return nil, errorx.ErrDatabaseError.WithCause(err)
} }
// Simplified DTO for list
var data []any priceMap, err := s.contentPriceMap(ctx, list)
if err != nil {
return nil, err
}
data := make([]super_dto.AdminContentItem, 0, len(list))
for _, c := range list { for _, c := range list {
data = append(data, c) // TODO: Map to DTO data = append(data, s.toSuperContentItem(c, priceMap[c.ID]))
} }
return &requests.Pager{ return &requests.Pager{
Pagination: filter.Pagination, Pagination: filter.Pagination,
@@ -382,7 +392,7 @@ func (s *super) RefundOrder(ctx context.Context, id int64, form *super_dto.Super
return errorx.ErrRecordNotFound.WithMsg("租户不存在") return errorx.ErrRecordNotFound.WithMsg("租户不存在")
} }
return Creator.ProcessRefund(ctx, t.UserID, id, &creator_dto.RefundForm{ return Creator.ProcessRefund(ctx, t.UserID, id, &v1_dto.RefundForm{
Action: "accept", Action: "accept",
Reason: form.Reason, Reason: form.Reason,
}) })
@@ -580,6 +590,138 @@ func (s *super) toSuperOrderItem(o *models.Order, tenant *models.Tenant, buyer *
return item return item
} }
func (s *super) contentPriceMap(ctx context.Context, list []*models.Content) (map[int64]*models.ContentPrice, error) {
if len(list) == 0 {
return map[int64]*models.ContentPrice{}, nil
}
ids := make([]int64, 0, len(list))
for _, item := range list {
ids = append(ids, item.ID)
}
tbl, q := models.ContentPriceQuery.QueryContext(ctx)
prices, err := q.Where(tbl.ContentID.In(ids...)).Find()
if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err)
}
priceMap := make(map[int64]*models.ContentPrice, len(prices))
for _, price := range prices {
priceMap[price.ContentID] = price
}
return priceMap, nil
}
func (s *super) toSuperContentItem(item *models.Content, price *models.ContentPrice) super_dto.AdminContentItem {
return super_dto.AdminContentItem{
Content: s.toSuperContentDTO(item, price),
Owner: s.toSuperContentOwner(item.Author),
Price: s.toSuperContentPrice(price),
StatusDescription: item.Status.Description(),
VisibilityDescription: item.Visibility.Description(),
}
}
func (s *super) toSuperContentOwner(author *models.User) *super_dto.AdminContentOwnerLite {
if author == nil {
return nil
}
return &super_dto.AdminContentOwnerLite{
ID: author.ID,
Username: author.Username,
Roles: author.Roles,
Status: author.Status,
}
}
func (s *super) toSuperContentDTO(item *models.Content, price *models.ContentPrice) *v1_dto.ContentItem {
dto := &v1_dto.ContentItem{
ID: item.ID,
Title: item.Title,
Genre: item.Genre,
AuthorID: item.UserID,
Views: int(item.Views),
Likes: int(item.Likes),
CreatedAt: item.CreatedAt.Format("2006-01-02"),
IsPurchased: false,
}
if price != nil {
dto.Price = float64(price.PriceAmount) / 100.0
}
if item.Author != nil {
dto.AuthorName = item.Author.Nickname
if dto.AuthorName == "" {
dto.AuthorName = item.Author.Username
}
dto.AuthorAvatar = item.Author.Avatar
}
var hasVideo, hasAudio bool
for _, asset := range item.ContentAssets {
if asset.Asset == nil {
continue
}
if asset.Role == consts.ContentAssetRoleCover {
dto.Cover = Common.GetAssetURL(asset.Asset.ObjectKey)
}
switch asset.Asset.Type {
case consts.MediaAssetTypeVideo:
hasVideo = true
case consts.MediaAssetTypeAudio:
hasAudio = true
}
}
if dto.Cover == "" && len(item.ContentAssets) > 0 {
for _, asset := range item.ContentAssets {
if asset.Asset != nil && asset.Asset.Type == consts.MediaAssetTypeImage {
dto.Cover = Common.GetAssetURL(asset.Asset.ObjectKey)
break
}
}
}
if hasVideo {
dto.Type = "video"
} else if hasAudio {
dto.Type = "audio"
} else {
dto.Type = "article"
}
return dto
}
func (s *super) toSuperContentPrice(price *models.ContentPrice) *v1_dto.ContentPrice {
if price == nil {
return nil
}
dto := &v1_dto.ContentPrice{
Currency: string(price.Currency),
PriceAmount: float64(price.PriceAmount) / 100.0,
DiscountType: string(price.DiscountType),
DiscountValue: s.toSuperDiscountValue(price),
}
if !price.DiscountStartAt.IsZero() {
dto.DiscountStartAt = price.DiscountStartAt.Format(time.RFC3339)
}
if !price.DiscountEndAt.IsZero() {
dto.DiscountEndAt = price.DiscountEndAt.Format(time.RFC3339)
}
return dto
}
func (s *super) toSuperDiscountValue(price *models.ContentPrice) float64 {
if price == nil {
return 0
}
if price.DiscountType == consts.DiscountTypeAmount {
return float64(price.DiscountValue) / 100.0
}
return float64(price.DiscountValue)
}
func (s *super) ListWithdrawals(ctx context.Context, filter *super_dto.SuperOrderListFilter) (*requests.Pager, error) { func (s *super) ListWithdrawals(ctx context.Context, filter *super_dto.SuperOrderListFilter) (*requests.Pager, error) {
tbl, q := models.OrderQuery.QueryContext(ctx) tbl, q := models.OrderQuery.QueryContext(ctx)
q = q.Where(tbl.Type.Eq(consts.OrderTypeWithdrawal)) q = q.Where(tbl.Type.Eq(consts.OrderTypeWithdrawal))