package user import ( "context" "bindbox-game/internal/repository/mysql/model" ) type InventoryWithProduct struct { *model.UserInventory ProductName string `json:"product_name"` ProductImages string `json:"product_images"` HasShipment bool `json:"has_shipment"` ShippingStatus int32 `json:"shipping_status"` } func (s *service) ListInventoryWithProduct(ctx context.Context, userID int64, page, pageSize int) (items []*InventoryWithProduct, total int64, err error) { q := s.readDB.UserInventory.WithContext(ctx).ReadDB().Where(s.readDB.UserInventory.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 } rows, err := q.Order(s.readDB.UserInventory.ID.Desc()).Offset((page - 1) * pageSize).Limit(pageSize).Find() if err != nil { return nil, 0, err } pidMap := make(map[int64]struct{}) invIDs := make([]int64, 0, len(rows)) for _, r := range rows { invIDs = append(invIDs, r.ID) if r.ProductID > 0 { pidMap[r.ProductID] = struct{}{} } } products := map[int64]*model.Products{} if len(pidMap) > 0 { ids := make([]int64, 0, len(pidMap)) for id := range pidMap { ids = append(ids, id) } pros, err := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.ID.In(ids...)).Find() if err != nil { return nil, 0, err } for _, p := range pros { products[p.ID] = p } } // 查询发货记录,按 inventory 维度取最新状态 shipMap := map[int64]*model.ShippingRecords{} if len(invIDs) > 0 { ships, _ := s.readDB.ShippingRecords.WithContext(ctx).ReadDB().Where(s.readDB.ShippingRecords.InventoryID.In(invIDs...)).Order(s.readDB.ShippingRecords.UpdatedAt.Desc(), s.readDB.ShippingRecords.ID.Desc()).Find() for _, sh := range ships { if _, ok := shipMap[sh.InventoryID]; !ok { shipMap[sh.InventoryID] = sh } } } items = make([]*InventoryWithProduct, len(rows)) for i, r := range rows { p := products[r.ProductID] name := "" images := "" if p != nil { name = p.Name images = p.ImagesJSON } sh := shipMap[r.ID] has := sh != nil && sh.Status != 5 var st int32 if sh != nil { st = sh.Status } items[i] = &InventoryWithProduct{UserInventory: r, ProductName: name, ProductImages: images, HasShipment: has, ShippingStatus: st} } return items, total, nil } func (s *service) ListInventoryWithProductActive(ctx context.Context, userID int64, page, pageSize int) (items []*InventoryWithProduct, total int64, err error) { q := s.readDB.UserInventory.WithContext(ctx).ReadDB().Where( s.readDB.UserInventory.UserID.Eq(userID), s.readDB.UserInventory.Status.Neq(2), ) 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 } rows, err := q.Order(s.readDB.UserInventory.ID.Desc()).Offset((page - 1) * pageSize).Limit(pageSize).Find() if err != nil { return nil, 0, err } pidMap := make(map[int64]struct{}) invIDs := make([]int64, 0, len(rows)) for _, r := range rows { invIDs = append(invIDs, r.ID) if r.ProductID > 0 { pidMap[r.ProductID] = struct{}{} } } products := map[int64]*model.Products{} if len(pidMap) > 0 { ids := make([]int64, 0, len(pidMap)) for id := range pidMap { ids = append(ids, id) } pros, err := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.ID.In(ids...)).Find() if err != nil { return nil, 0, err } for _, p := range pros { products[p.ID] = p } } shipMap := map[int64]*model.ShippingRecords{} if len(invIDs) > 0 { ships, _ := s.readDB.ShippingRecords.WithContext(ctx).ReadDB().Where(s.readDB.ShippingRecords.InventoryID.In(invIDs...)).Order(s.readDB.ShippingRecords.UpdatedAt.Desc(), s.readDB.ShippingRecords.ID.Desc()).Find() for _, sh := range ships { if _, ok := shipMap[sh.InventoryID]; !ok { shipMap[sh.InventoryID] = sh } } } items = make([]*InventoryWithProduct, len(rows)) for i, r := range rows { p := products[r.ProductID] name := "" images := "" if p != nil { name = p.Name images = p.ImagesJSON } sh := shipMap[r.ID] has := sh != nil && sh.Status != 5 var st int32 if sh != nil { st = sh.Status } items[i] = &InventoryWithProduct{UserInventory: r, ProductName: name, ProductImages: images, HasShipment: has, ShippingStatus: st} } return items, total, nil }