167 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			167 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package admin_promotion | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"context" | ||
|  | 	"time" | ||
|  | 
 | ||
|  | 	"tydata-server/app/main/api/internal/svc" | ||
|  | 	"tydata-server/app/main/api/internal/types" | ||
|  | 	"tydata-server/app/main/model" | ||
|  | 	"tydata-server/common/ctxdata" | ||
|  | 	"tydata-server/common/xerr" | ||
|  | 
 | ||
|  | 	"github.com/pkg/errors" | ||
|  | 	"github.com/zeromicro/go-zero/core/logx" | ||
|  | 	"github.com/zeromicro/go-zero/core/mr" | ||
|  | ) | ||
|  | 
 | ||
|  | type GetPromotionStatsTotalLogic struct { | ||
|  | 	logx.Logger | ||
|  | 	ctx    context.Context | ||
|  | 	svcCtx *svc.ServiceContext | ||
|  | } | ||
|  | 
 | ||
|  | func NewGetPromotionStatsTotalLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPromotionStatsTotalLogic { | ||
|  | 	return &GetPromotionStatsTotalLogic{ | ||
|  | 		Logger: logx.WithContext(ctx), | ||
|  | 		ctx:    ctx, | ||
|  | 		svcCtx: svcCtx, | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (l *GetPromotionStatsTotalLogic) GetPromotionStatsTotal(req *types.GetPromotionStatsTotalReq) (resp *types.GetPromotionStatsTotalResp, err error) { | ||
|  | 	// 获取当前用户ID | ||
|  | 	adminUserId, getUidErr := ctxdata.GetUidFromCtx(l.ctx) | ||
|  | 	if getUidErr != nil { | ||
|  | 		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取当前用户ID失败, %+v", getUidErr) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// 获取用户的所有推广链接 | ||
|  | 	linkBuilder := l.svcCtx.AdminPromotionLinkModel.SelectBuilder() | ||
|  | 	linkBuilder = linkBuilder.Where("admin_user_id = ?", adminUserId) | ||
|  | 	links, err := l.svcCtx.AdminPromotionLinkModel.FindAll(l.ctx, linkBuilder, "") | ||
|  | 	if err != nil { | ||
|  | 		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广链接列表失败, %+v", err) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// 如果没有推广链接,返回空统计 | ||
|  | 	if len(links) == 0 { | ||
|  | 		return &types.GetPromotionStatsTotalResp{}, nil | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// 构建链接ID列表 | ||
|  | 	linkIds := make([]int64, len(links)) | ||
|  | 	for i, link := range links { | ||
|  | 		linkIds[i] = link.Id | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// 获取并计算总统计数据 | ||
|  | 	var totalClickCount, totalPayCount int64 | ||
|  | 	var totalPayAmount float64 | ||
|  | 	err = mr.MapReduceVoid(func(source chan<- interface{}) { | ||
|  | 		for _, linkId := range linkIds { | ||
|  | 			source <- linkId | ||
|  | 		} | ||
|  | 	}, func(item interface{}, writer mr.Writer[struct { | ||
|  | 		ClickCount int64 | ||
|  | 		PayCount   int64 | ||
|  | 		PayAmount  float64 | ||
|  | 	}], cancel func(error)) { | ||
|  | 		linkId := item.(int64) | ||
|  | 		stats, err := l.svcCtx.AdminPromotionLinkStatsTotalModel.FindOneByLinkId(l.ctx, linkId) | ||
|  | 		if err != nil && !errors.Is(err, model.ErrNotFound) { | ||
|  | 			cancel(errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取总统计数据失败, linkId: %d, %+v", linkId, err)) | ||
|  | 			return | ||
|  | 		} | ||
|  | 		if stats != nil { | ||
|  | 			writer.Write(struct { | ||
|  | 				ClickCount int64 | ||
|  | 				PayCount   int64 | ||
|  | 				PayAmount  float64 | ||
|  | 			}{ | ||
|  | 				ClickCount: stats.ClickCount, | ||
|  | 				PayCount:   stats.PayCount, | ||
|  | 				PayAmount:  stats.PayAmount, | ||
|  | 			}) | ||
|  | 		} | ||
|  | 	}, func(pipe <-chan struct { | ||
|  | 		ClickCount int64 | ||
|  | 		PayCount   int64 | ||
|  | 		PayAmount  float64 | ||
|  | 	}, cancel func(error)) { | ||
|  | 		for stats := range pipe { | ||
|  | 			totalClickCount += stats.ClickCount | ||
|  | 			totalPayCount += stats.PayCount | ||
|  | 			totalPayAmount += stats.PayAmount | ||
|  | 		} | ||
|  | 	}) | ||
|  | 	if err != nil { | ||
|  | 		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取总统计数据失败, %+v", err) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// 获取今日统计数据 | ||
|  | 	now := time.Now() | ||
|  | 	today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local) | ||
|  | 	var todayClickCount, todayPayCount int64 | ||
|  | 	var todayPayAmount float64 | ||
|  | 
 | ||
|  | 	err = mr.MapReduceVoid(func(source chan<- interface{}) { | ||
|  | 		for _, linkId := range linkIds { | ||
|  | 			source <- linkId | ||
|  | 		} | ||
|  | 	}, func(item interface{}, writer mr.Writer[struct { | ||
|  | 		ClickCount int64 | ||
|  | 		PayCount   int64 | ||
|  | 		PayAmount  float64 | ||
|  | 	}], cancel func(error)) { | ||
|  | 		linkId := item.(int64) | ||
|  | 		builder := l.svcCtx.AdminPromotionLinkStatsHistoryModel.SelectBuilder() | ||
|  | 		builder = builder.Where("link_id = ? AND DATE(stats_date) = DATE(?)", linkId, today) | ||
|  | 		histories, err := l.svcCtx.AdminPromotionLinkStatsHistoryModel.FindAll(l.ctx, builder, "") | ||
|  | 		if err != nil { | ||
|  | 			cancel(errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取今日统计数据失败, linkId: %d, %+v", linkId, err)) | ||
|  | 			return | ||
|  | 		} | ||
|  | 
 | ||
|  | 		var clickCount, payCount int64 | ||
|  | 		var payAmount float64 | ||
|  | 		for _, history := range histories { | ||
|  | 			clickCount += history.ClickCount | ||
|  | 			payCount += history.PayCount | ||
|  | 			payAmount += history.PayAmount | ||
|  | 		} | ||
|  | 
 | ||
|  | 		writer.Write(struct { | ||
|  | 			ClickCount int64 | ||
|  | 			PayCount   int64 | ||
|  | 			PayAmount  float64 | ||
|  | 		}{ | ||
|  | 			ClickCount: clickCount, | ||
|  | 			PayCount:   payCount, | ||
|  | 			PayAmount:  payAmount, | ||
|  | 		}) | ||
|  | 	}, func(pipe <-chan struct { | ||
|  | 		ClickCount int64 | ||
|  | 		PayCount   int64 | ||
|  | 		PayAmount  float64 | ||
|  | 	}, cancel func(error)) { | ||
|  | 		for stats := range pipe { | ||
|  | 			todayClickCount += stats.ClickCount | ||
|  | 			todayPayCount += stats.PayCount | ||
|  | 			todayPayAmount += stats.PayAmount | ||
|  | 		} | ||
|  | 	}) | ||
|  | 	if err != nil { | ||
|  | 		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取今日统计数据失败, %+v", err) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return &types.GetPromotionStatsTotalResp{ | ||
|  | 		TodayClickCount: int64(todayClickCount), | ||
|  | 		TodayPayCount:   int64(todayPayCount), | ||
|  | 		TodayPayAmount:  todayPayAmount, | ||
|  | 		TotalClickCount: int64(totalClickCount), | ||
|  | 		TotalPayCount:   int64(totalPayCount), | ||
|  | 		TotalPayAmount:  totalPayAmount, | ||
|  | 	}, nil | ||
|  | } |