package logic import ( "context" "fmt" "muyu-apiserver/pkg/tenantctx" "muyu-apiserver/rpc/purchase/internal/svc" "muyu-apiserver/rpc/purchase/pb" "github.com/zeromicro/go-zero/core/logx" ) type GetPurchaseStatsByProductLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewGetPurchaseStatsByProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseStatsByProductLogic { return &GetPurchaseStatsByProductLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} } func (l *GetPurchaseStatsByProductLogic) GetPurchaseStatsByProduct(in *pb.PurchaseStatsSummaryReq) (*pb.PurchaseStatsByProductResp, error) { tenantId := tenantctx.ExtractTenantId(l.ctx) orders, _, err := l.svcCtx.OrderModel.FindList(l.ctx, tenantId, 1, 10000, "", -1, in.StartDate, in.EndDate) if err != nil { return nil, err } type productKey struct { productId string } type productStats struct { productName string spec string color string totalQty float64 totalAmount float64 orderCount int64 } statsMap := map[string]*productStats{} for _, o := range orders { if o.Status == 2 { continue } details, err := l.svcCtx.OrderDetailModel.FindByOrderId(l.ctx, o.OrderId) if err != nil { continue } for _, d := range details { s := statsMap[d.ProductId] if s == nil { s = &productStats{ productName: d.ProductName, spec: d.Spec, color: d.Color, } statsMap[d.ProductId] = s } s.totalQty += d.Quantity s.totalAmount += d.Amount s.orderCount++ } } items := make([]*pb.PurchaseStatsByProductItem, 0, len(statsMap)) for productId, s := range statsMap { avgPrice := 0.0 if s.totalQty > 0 { avgPrice = s.totalAmount / s.totalQty } items = append(items, &pb.PurchaseStatsByProductItem{ ProductId: productId, ProductName: s.productName, Spec: s.spec, Color: s.color, TotalQty: fmt.Sprintf("%.2f", s.totalQty), AvgUnitPrice: fmt.Sprintf("%.2f", avgPrice), TotalAmount: fmt.Sprintf("%.2f", s.totalAmount), }) } return &pb.PurchaseStatsByProductResp{List: items}, nil }