package user import ( "context" "strings" "bindbox-game/internal/repository/mysql/model" ) // OrderWithItems 包含订单项的订单信息 type OrderWithItems struct { *model.Orders Items []*model.OrderItems `json:"items"` ActivityName string `json:"activity_name"` IssueNumber string `json:"issue_number"` IsDraw bool `json:"is_draw"` IsWinner bool `json:"is_winner"` RewardLevel int32 `json:"reward_level"` } func (s *service) ListOrders(ctx context.Context, userID int64, page, pageSize int) (items []*model.Orders, total int64, err error) { // 查询用户的所有订单,包括商城直购(1)、抽奖票据(2)和系统发放(3) q := s.readDB.Orders.WithContext(ctx).ReadDB().Where(s.readDB.Orders.UserID.Eq(userID)) total, err = q.Count() if err != nil { return nil, 0, err } if page <= 0 { page = 1 } if pageSize <= 0 { pageSize = 20 } if pageSize > 100 { pageSize = 100 } items, err = q.Order(s.readDB.Orders.ID.Desc()).Offset((page - 1) * pageSize).Limit(pageSize).Find() if err != nil { return nil, 0, err } return items, total, nil } // GetOrderWithItems 查询单个订单详情 func (s *service) GetOrderWithItems(ctx context.Context, userID int64, orderID int64) (*OrderWithItems, error) { order, err := s.readDB.Orders.WithContext(ctx).ReadDB().Where(s.readDB.Orders.ID.Eq(orderID), s.readDB.Orders.UserID.Eq(userID)).First() if err != nil { return nil, err } if order == nil { return nil, nil } res := &OrderWithItems{ Orders: order, } items, err := s.readDB.OrderItems.WithContext(ctx).ReadDB().Where(s.readDB.OrderItems.OrderID.Eq(order.ID)).Find() if err != nil { return nil, err } if len(items) > 0 { ids := make(map[int64]struct{}) for _, it := range items { if strings.TrimSpace(it.Title) == "" || strings.TrimSpace(it.Title) == "系统发放奖励" || it.ProductImages == "" || it.ProductImages == "[]" { ids[it.ProductID] = struct{}{} } } if len(ids) > 0 { pidList := make([]int64, 0, len(ids)) for id := range ids { pidList = append(pidList, id) } pros, err2 := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.ID.In(pidList...)).Find() if err2 != nil { return nil, err2 } pm := make(map[int64]*model.Products, len(pros)) for _, p := range pros { pm[p.ID] = p } for _, it := range items { p := pm[it.ProductID] if p == nil { continue } if strings.TrimSpace(it.Title) == "" || strings.TrimSpace(it.Title) == "系统发放奖励" { it.Title = p.Name } if it.ProductImages == "" || it.ProductImages == "[]" { it.ProductImages = p.ImagesJSON } } } res.Items = items } // 补充开奖信息 log, _ := s.readDB.ActivityDrawLogs.WithContext(ctx).ReadDB().Where(s.readDB.ActivityDrawLogs.OrderID.Eq(order.ID)).First() if log != nil { res.IsDraw = true res.IsWinner = log.IsWinner == 1 res.RewardLevel = log.Level issue, _ := s.readDB.ActivityIssues.WithContext(ctx).ReadDB().Where(s.readDB.ActivityIssues.ID.Eq(log.IssueID)).First() if issue != nil { res.IssueNumber = issue.IssueNumber act, _ := s.readDB.Activities.WithContext(ctx).ReadDB().Where(s.readDB.Activities.ID.Eq(issue.ActivityID)).First() if act != nil { res.ActivityName = act.Name } } } return res, nil } // ListOrdersWithItems 查询用户的订单列表,包含订单项详情 func (s *service) ListOrdersWithItems(ctx context.Context, userID int64, status int32, page, pageSize int) (items []*OrderWithItems, total int64, err error) { // 查询用户的所有订单,包括商城直购(1)、抽奖票据(2)和系统发放(3) q := s.readDB.Orders.WithContext(ctx).ReadDB().Where(s.readDB.Orders.UserID.Eq(userID)) if status > 0 { q = q.Where(s.readDB.Orders.Status.Eq(status)) } total, err = q.Count() if err != nil { return nil, 0, err } if page <= 0 { page = 1 } if pageSize <= 0 { pageSize = 20 } if pageSize > 100 { pageSize = 100 } // 查询订单列表 orders, err := q.Order(s.readDB.Orders.ID.Desc()).Offset((page - 1) * pageSize).Limit(pageSize).Find() if err != nil { return nil, 0, err } // 构建订单ID列表 orderIDs := make([]int64, len(orders)) for i, order := range orders { orderIDs[i] = order.ID } var allItems []*model.OrderItems if len(orderIDs) > 0 { allItems, err = s.readDB.OrderItems.WithContext(ctx).ReadDB().Where(s.readDB.OrderItems.OrderID.In(orderIDs...)).Find() if err != nil { return nil, 0, err } ids := make(map[int64]struct{}) for _, it := range allItems { if strings.TrimSpace(it.Title) == "" || strings.TrimSpace(it.Title) == "系统发放奖励" || it.ProductImages == "" || it.ProductImages == "[]" { ids[it.ProductID] = struct{}{} } } if len(ids) > 0 { pidList := make([]int64, 0, len(ids)) for id := range ids { pidList = append(pidList, id) } pros, err2 := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.ID.In(pidList...)).Find() if err2 != nil { return nil, 0, err2 } pm := make(map[int64]*model.Products, len(pros)) for _, p := range pros { pm[p.ID] = p } for _, it := range allItems { p := pm[it.ProductID] if p == nil { continue } if strings.TrimSpace(it.Title) == "" || strings.TrimSpace(it.Title) == "系统发放奖励" { it.Title = p.Name } if it.ProductImages == "" || it.ProductImages == "[]" { it.ProductImages = p.ImagesJSON } } } } // 构建订单ID到订单项的映射 itemsMap := make(map[int64][]*model.OrderItems) for _, item := range allItems { itemsMap[item.OrderID] = append(itemsMap[item.OrderID], item) } // 批量查询活动开奖信息 drawLogsMap := make(map[int64]*model.ActivityDrawLogs) activityMap := make(map[int64]*model.Activities) issueMap := make(map[int64]*model.ActivityIssues) if len(orderIDs) > 0 { logs, _ := s.readDB.ActivityDrawLogs.WithContext(ctx).ReadDB().Where(s.readDB.ActivityDrawLogs.OrderID.In(orderIDs...)).Find() var issueIDs []int64 for _, log := range logs { drawLogsMap[log.OrderID] = log issueIDs = append(issueIDs, log.IssueID) } if len(issueIDs) > 0 { issues, _ := s.readDB.ActivityIssues.WithContext(ctx).ReadDB().Where(s.readDB.ActivityIssues.ID.In(issueIDs...)).Find() var activityIDs []int64 for _, issue := range issues { issueMap[issue.ID] = issue activityIDs = append(activityIDs, issue.ActivityID) } if len(activityIDs) > 0 { activities, _ := s.readDB.Activities.WithContext(ctx).ReadDB().Where(s.readDB.Activities.ID.In(activityIDs...)).Find() for _, act := range activities { activityMap[act.ID] = act } } } } // 构建返回结果 items = make([]*OrderWithItems, len(orders)) for i, order := range orders { items[i] = &OrderWithItems{ Orders: order, Items: itemsMap[order.ID], } if log, ok := drawLogsMap[order.ID]; ok { items[i].IsDraw = true items[i].IsWinner = log.IsWinner == 1 items[i].RewardLevel = log.Level if issue, ok := issueMap[log.IssueID]; ok { items[i].IssueNumber = issue.IssueNumber if act, ok := activityMap[issue.ActivityID]; ok { items[i].ActivityName = act.Name } } } } return items, total, nil }