diff --git a/backend/app/services/creator.go b/backend/app/services/creator.go index 65d6fde..f4d3827 100644 --- a/backend/app/services/creator.go +++ b/backend/app/services/creator.go @@ -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 {