perf: batch creator order list data

This commit is contained in:
2026-01-09 15:12:21 +08:00
parent cf92e0bd89
commit c446dec5c6

View File

@@ -590,29 +590,92 @@ func (s *creator) ListOrders(
return nil, errorx.ErrDatabaseError.WithCause(err)
}
var data []creator_dto.Order
if len(list) == 0 {
return []creator_dto.Order{}, nil
}
// 批量加载买家、订单明细、内容,避免列表场景 N+1 查询。
orderIDs := make([]int64, 0, len(list))
userSet := make(map[int64]struct{}, len(list))
for _, o := range list {
orderIDs = append(orderIDs, o.ID)
if o.UserID > 0 {
userSet[o.UserID] = struct{}{}
}
}
userIDs := make([]int64, 0, len(userSet))
for id := range userSet {
userIDs = append(userIDs, id)
}
userMap := make(map[int64]*models.User, len(userIDs))
if len(userIDs) > 0 {
uTbl, uQ := models.UserQuery.QueryContext(ctx)
users, err := uQ.Where(uTbl.ID.In(userIDs...)).Find()
if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err)
}
for _, u := range users {
userMap[u.ID] = u
}
}
itemMap := make(map[int64]*models.OrderItem, len(orderIDs))
contentSet := make(map[int64]struct{}, len(orderIDs))
if len(orderIDs) > 0 {
itemTbl, itemQ := models.OrderItemQuery.QueryContext(ctx)
items, err := itemQ.Where(itemTbl.OrderID.In(orderIDs...)).
Order(itemTbl.OrderID.Asc(), itemTbl.ID.Asc()).
Find()
if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err)
}
for _, item := range items {
if _, exists := itemMap[item.OrderID]; exists {
continue
}
itemMap[item.OrderID] = item
if item.ContentID > 0 {
contentSet[item.ContentID] = struct{}{}
}
}
}
contentIDs := make([]int64, 0, len(contentSet))
for id := range contentSet {
contentIDs = append(contentIDs, id)
}
contentMap := make(map[int64]*models.Content, len(contentIDs))
if len(contentIDs) > 0 {
var contents []*models.Content
cTbl, cQ := models.ContentQuery.QueryContext(ctx)
err := cQ.Where(cTbl.ID.In(contentIDs...)).
UnderlyingDB().
Preload("ContentAssets").
Preload("ContentAssets.Asset").
Find(&contents).Error
if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err)
}
for _, c := range contents {
contentMap[c.ID] = c
}
}
data := make([]creator_dto.Order, 0, len(list))
for _, o := range list {
// Fetch Buyer Info
u, _ := models.UserQuery.WithContext(ctx).Where(models.UserQuery.ID.Eq(o.UserID)).First()
buyerName := "未知用户"
buyerAvatar := ""
if u != nil {
if u := userMap[o.UserID]; u != nil {
buyerName = u.Nickname
buyerAvatar = u.Avatar
}
// Fetch Content Info
var title, cover string
item, _ := models.OrderItemQuery.WithContext(ctx).Where(models.OrderItemQuery.OrderID.Eq(o.ID)).First()
if item != nil {
var c models.Content
err := models.ContentQuery.WithContext(ctx).
Where(models.ContentQuery.ID.Eq(item.ContentID)).
UnderlyingDB().
Preload("ContentAssets.Asset").
First(&c).Error
if err == nil {
if item := itemMap[o.ID]; item != nil {
if c := contentMap[item.ContentID]; c != nil {
title = c.Title
for _, ca := range c.ContentAssets {
if ca.Role == consts.ContentAssetRoleCover && ca.Asset != nil {