279 lines
7.3 KiB
Go
279 lines
7.3 KiB
Go
package dao
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"time"
|
||
|
||
"order/consts"
|
||
"order/model/entity"
|
||
|
||
"gitee.com/red-future---jilin-g/common/do"
|
||
"gitee.com/red-future---jilin-g/common/mongo"
|
||
|
||
"go.mongodb.org/mongo-driver/v2/bson"
|
||
)
|
||
|
||
// OrderYearlyStatisticsDAO 订单年度统计DAO
|
||
type OrderYearlyStatisticsDAO struct {
|
||
}
|
||
|
||
var OrderYearlyStatisticsDAOInstance = &OrderYearlyStatisticsDAO{}
|
||
|
||
// GenerateStatistics 使用Go代码生成年度统计数据
|
||
func (dao *OrderYearlyStatisticsDAO) GenerateStatistics(ctx context.Context, tenantID int64, year int) (*entity.OrderYearlyStatistics, error) {
|
||
// 设置时间范围
|
||
startDate := time.Date(year, 1, 1, 0, 0, 0, 0, time.Local)
|
||
endDate := startDate.AddDate(1, 0, 0)
|
||
|
||
// 查询订单数据
|
||
filter := bson.M{
|
||
"tenantId": tenantID,
|
||
"createdAt": bson.M{
|
||
"$gte": startDate,
|
||
"$lt": endDate,
|
||
},
|
||
}
|
||
|
||
var orders []*entity.OrderBase
|
||
err := mongo.DB().Find(ctx, filter, &orders, consts.OrderCollection)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("查询订单数据失败: %v", err)
|
||
}
|
||
|
||
// 如果没有数据,创建空统计
|
||
if len(orders) == 0 {
|
||
statistics := &entity.OrderYearlyStatistics{
|
||
MongoBaseDO: do.MongoBaseDO{
|
||
TenantId: tenantID,
|
||
CreatedAt: time.Now(),
|
||
UpdatedAt: time.Now(),
|
||
},
|
||
ReportDate: startDate,
|
||
Period: startDate.Format("2006"),
|
||
Year: year,
|
||
}
|
||
return statistics, nil
|
||
}
|
||
|
||
// 使用Go代码计算统计指标
|
||
totalOrders := int64(len(orders))
|
||
totalAmount := int64(0)
|
||
completedOrders := int64(0)
|
||
cancelledOrders := int64(0)
|
||
paidOrders := int64(0)
|
||
totalItems := int64(0)
|
||
|
||
uniqueUsers := make(map[int64]bool)
|
||
uniqueAssets := make(map[string]bool)
|
||
assetCounts := make(map[string]int64)
|
||
quarterlyOrders := make([]int64, 4)
|
||
quarterlyAmounts := make([]int64, 4)
|
||
monthlyOrders := make([]int64, 12)
|
||
monthlyAmounts := make([]int64, 12)
|
||
|
||
for _, order := range orders {
|
||
// 计算总金额
|
||
totalAmount += order.TotalAmount
|
||
|
||
// 注意:OrderBase结构体没有Status字段,状态统计需要通过其他方式获取
|
||
|
||
// 统计唯一用户
|
||
uniqueUsers[order.UserID] = true
|
||
|
||
// 统计商品信息
|
||
if order.OrderItems != nil {
|
||
totalItems += int64(len(order.OrderItems))
|
||
for _, item := range order.OrderItems {
|
||
uniqueAssets[item.AssetID] = true
|
||
assetCounts[item.AssetID]++
|
||
}
|
||
}
|
||
|
||
// 统计季度分布
|
||
quarter := (int(order.CreatedAt.Month())-1)/3 + 1
|
||
if quarter >= 1 && quarter <= 4 {
|
||
quarterlyOrders[quarter-1]++
|
||
quarterlyAmounts[quarter-1] += order.TotalAmount
|
||
}
|
||
|
||
// 统计月度分布
|
||
month := int(order.CreatedAt.Month())
|
||
if month >= 1 && month <= 12 {
|
||
monthlyOrders[month-1]++
|
||
monthlyAmounts[month-1] += order.TotalAmount
|
||
}
|
||
}
|
||
|
||
// 计算业务指标
|
||
var averageOrderValue int64
|
||
if totalOrders > 0 {
|
||
averageOrderValue = totalAmount / totalOrders
|
||
}
|
||
|
||
var paymentRate, completionRate float64
|
||
if totalOrders > 0 {
|
||
paymentRate = float64(paidOrders) / float64(totalOrders) * 100
|
||
completionRate = float64(completedOrders) / float64(totalOrders) * 100
|
||
}
|
||
|
||
// 获取热门资产
|
||
topAssetID, topAssetName, topAssetCount := dao.findTopAsset(assetCounts, orders)
|
||
|
||
statistics := &entity.OrderYearlyStatistics{
|
||
MongoBaseDO: do.MongoBaseDO{
|
||
TenantId: tenantID,
|
||
CreatedAt: time.Now(),
|
||
UpdatedAt: time.Now(),
|
||
},
|
||
ReportDate: startDate,
|
||
Period: startDate.Format("2006"),
|
||
Year: year,
|
||
TotalOrders: totalOrders,
|
||
CompletedOrders: completedOrders,
|
||
CancelledOrders: cancelledOrders,
|
||
PaidOrders: paidOrders,
|
||
TotalAmount: totalAmount,
|
||
PaidAmount: totalAmount,
|
||
NetAmount: totalAmount,
|
||
AverageOrderValue: averageOrderValue,
|
||
PaymentRate: paymentRate,
|
||
CompletionRate: completionRate,
|
||
UniqueUsers: int64(len(uniqueUsers)),
|
||
NewUsers: 0,
|
||
ReturningUsers: 0,
|
||
TotalItems: totalItems,
|
||
UniqueAssets: int64(len(uniqueAssets)),
|
||
TopAssetID: topAssetID,
|
||
TopAssetName: topAssetName,
|
||
TopAssetCount: topAssetCount,
|
||
QuarterlyOrders: quarterlyOrders,
|
||
QuarterlyAmounts: quarterlyAmounts,
|
||
PeakQuarter: dao.findPeakQuarter(quarterlyOrders),
|
||
MonthlyOrders: monthlyOrders,
|
||
MonthlyAmounts: monthlyAmounts,
|
||
YearOverYearGrowth: dao.calculateYearOverYearGrowth(ctx, tenantID, year, totalOrders),
|
||
}
|
||
|
||
return statistics, nil
|
||
}
|
||
|
||
// findTopAsset 找出热门资产
|
||
func (dao *OrderYearlyStatisticsDAO) findTopAsset(assetCounts map[string]int64, orders []*entity.OrderBase) (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 {
|
||
if order.OrderItems != nil {
|
||
for _, item := range order.OrderItems {
|
||
if item.AssetID == topAssetID {
|
||
topAssetName = item.AssetName
|
||
break
|
||
}
|
||
}
|
||
}
|
||
if topAssetName != "" {
|
||
break
|
||
}
|
||
}
|
||
|
||
return topAssetID, topAssetName, maxCount
|
||
}
|
||
|
||
// findPeakQuarter 找出高峰季度
|
||
func (dao *OrderYearlyStatisticsDAO) findPeakQuarter(quarterlyOrders []int64) int {
|
||
maxQuarter := 1
|
||
maxCount := int64(0)
|
||
|
||
for i, count := range quarterlyOrders {
|
||
if count > maxCount {
|
||
maxCount = count
|
||
maxQuarter = i + 1
|
||
}
|
||
}
|
||
|
||
return maxQuarter
|
||
}
|
||
|
||
// calculateYearOverYearGrowth 计算同比增长率
|
||
func (dao *OrderYearlyStatisticsDAO) calculateYearOverYearGrowth(ctx context.Context, tenantID int64, year int, currentOrders int64) float64 {
|
||
// 查询去年同期的订单数据
|
||
lastYear := year - 1
|
||
lastYearStartDate := time.Date(lastYear, 1, 1, 0, 0, 0, 0, time.Local)
|
||
lastYearEndDate := lastYearStartDate.AddDate(1, 0, 0)
|
||
|
||
filter := bson.M{
|
||
"tenantId": tenantID,
|
||
"createdAt": bson.M{
|
||
"$gte": lastYearStartDate,
|
||
"$lt": lastYearEndDate,
|
||
},
|
||
}
|
||
|
||
var lastYearOrders []*entity.OrderBase
|
||
err := mongo.DB().Find(ctx, filter, &lastYearOrders, consts.OrderCollection)
|
||
if err != nil || len(lastYearOrders) == 0 {
|
||
return 0.0
|
||
}
|
||
|
||
lastYearOrderCount := int64(len(lastYearOrders))
|
||
if lastYearOrderCount == 0 {
|
||
return 0.0
|
||
}
|
||
|
||
// 计算同比增长率
|
||
growth := (float64(currentOrders) - float64(lastYearOrderCount)) / float64(lastYearOrderCount) * 100
|
||
return growth
|
||
}
|
||
|
||
// Save 保存年度统计数据
|
||
func (dao *OrderYearlyStatisticsDAO) Save(ctx context.Context, statistics *entity.OrderYearlyStatistics) error {
|
||
_, err := mongo.DB().Insert(ctx, []interface{}{statistics}, consts.OrderYearlyStatisticsCollection)
|
||
return err
|
||
}
|
||
|
||
// Update 更新年度统计数据
|
||
func (dao *OrderYearlyStatisticsDAO) Update(ctx context.Context, statistics *entity.OrderYearlyStatistics) error {
|
||
filter := bson.M{
|
||
"tenantId": statistics.TenantId,
|
||
"reportDate": statistics.ReportDate,
|
||
}
|
||
|
||
update := bson.M{
|
||
"$set": statistics,
|
||
}
|
||
|
||
_, err := mongo.DB().Update(ctx, filter, update, consts.OrderYearlyStatisticsCollection)
|
||
return err
|
||
}
|
||
|
||
// GetByTenantAndDate 获取指定租户和日期的年度统计数据
|
||
func (dao *OrderYearlyStatisticsDAO) GetByTenantAndDate(ctx context.Context, tenantID int64, reportDate time.Time) (*entity.OrderYearlyStatistics, error) {
|
||
var result entity.OrderYearlyStatistics
|
||
|
||
filter := bson.M{
|
||
"tenantId": tenantID,
|
||
"reportDate": reportDate,
|
||
}
|
||
|
||
err := mongo.DB().FindOne(ctx, filter, &result, consts.OrderYearlyStatisticsCollection)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return &result, nil
|
||
}
|