package dao import ( "context" "fmt" "time" "order/consts" "order/model/entity" "gitea.com/red-future/common/mongo" "go.mongodb.org/mongo-driver/v2/bson" ) // OrderStatisticsBaseDAO 订单统计基础DAO type OrderStatisticsBaseDAO struct { } var OrderStatisticsBaseDAOInstance = &OrderStatisticsBaseDAO{} // OrderStats 订单统计结果 type OrderStats struct { TotalOrders int64 TotalAmount int64 TotalItems int64 UniqueUsers map[int64]bool UniqueAssets map[string]bool AssetCounts map[string]int64 } // GetOrderStats 获取订单统计信息 func (dao *OrderStatisticsBaseDAO) GetOrderStats(ctx context.Context, tenantID int64, startDate, endDate time.Time) (*OrderStats, error) { stats := &OrderStats{ UniqueUsers: make(map[int64]bool), UniqueAssets: make(map[string]bool), AssetCounts: make(map[string]int64), } // 查询所有状态的订单数据 filter := bson.M{ "tenantId": tenantID, "createdAt": bson.M{ "$gte": startDate, "$lt": endDate, }, } // 查询待支付订单 var pendingOrders []*entity.OrderPending err := mongo.DB().Find(ctx, filter, &pendingOrders, consts.OrderPendingCollection) if err != nil { return nil, fmt.Errorf("查询待支付订单数据失败: %v", err) } // 查询已支付订单 var paidOrders []*entity.OrderPaid err = mongo.DB().Find(ctx, filter, &paidOrders, consts.OrderPaidCollection) if err != nil { return nil, fmt.Errorf("查询已支付订单数据失败: %v", err) } // 查询已发货订单 var shippedOrders []*entity.OrderShipped err = mongo.DB().Find(ctx, filter, &shippedOrders, consts.OrderShippedCollection) if err != nil { return nil, fmt.Errorf("查询已发货订单数据失败: %v", err) } // 查询已完成订单 var completedOrders []*entity.OrderCompleted err = mongo.DB().Find(ctx, filter, &completedOrders, consts.OrderCompletedCollection) if err != nil { return nil, fmt.Errorf("查询已完成订单数据失败: %v", err) } // 统计待支付订单 for _, order := range pendingOrders { stats.TotalOrders++ stats.TotalAmount += order.TotalAmount stats.UniqueUsers[order.UserID] = true if order.OrderItems != nil { stats.TotalItems += int64(len(order.OrderItems)) for _, item := range order.OrderItems { stats.UniqueAssets[item.AssetID] = true stats.AssetCounts[item.AssetID]++ } } } // 统计已支付订单 for _, order := range paidOrders { stats.TotalOrders++ stats.TotalAmount += order.TotalAmount stats.UniqueUsers[order.UserID] = true if order.OrderItems != nil { stats.TotalItems += int64(len(order.OrderItems)) for _, item := range order.OrderItems { stats.UniqueAssets[item.AssetID] = true stats.AssetCounts[item.AssetID]++ } } } // 统计已发货订单 for _, order := range shippedOrders { stats.TotalOrders++ stats.TotalAmount += order.TotalAmount stats.UniqueUsers[order.UserID] = true if order.OrderItems != nil { stats.TotalItems += int64(len(order.OrderItems)) for _, item := range order.OrderItems { stats.UniqueAssets[item.AssetID] = true stats.AssetCounts[item.AssetID]++ } } } // 统计已完成订单 for _, order := range completedOrders { stats.TotalOrders++ stats.TotalAmount += order.TotalAmount stats.UniqueUsers[order.UserID] = true if order.OrderItems != nil { stats.TotalItems += int64(len(order.OrderItems)) for _, item := range order.OrderItems { stats.UniqueAssets[item.AssetID] = true stats.AssetCounts[item.AssetID]++ } } } return stats, nil } // FindTopAsset 找出热门资产 func (dao *OrderStatisticsBaseDAO) FindTopAsset(assetCounts map[string]int64, orders []interface{}) (string, string, int64) { if len(assetCounts) == 0 { return "", "", 0 } var topAssetID string var maxCount int64 for assetID, count := range assetCounts { if count > maxCount { maxCount = count topAssetID = assetID } } // 查找资产名称 var topAssetName string for _, order := range orders { switch o := order.(type) { case *entity.OrderPending: if o.OrderItems != nil { for _, item := range o.OrderItems { if item.AssetID == topAssetID { topAssetName = item.AssetName break } } } case *entity.OrderPaid: if o.OrderItems != nil { for _, item := range o.OrderItems { if item.AssetID == topAssetID { topAssetName = item.AssetName break } } } case *entity.OrderShipped: if o.OrderItems != nil { for _, item := range o.OrderItems { if item.AssetID == topAssetID { topAssetName = item.AssetName break } } } case *entity.OrderCompleted: if o.OrderItems != nil { for _, item := range o.OrderItems { if item.AssetID == topAssetID { topAssetName = item.AssetName break } } } } if topAssetName != "" { break } } return topAssetID, topAssetName, maxCount }