package admin_promotion import ( "context" "time" "tyc-server/app/main/api/internal/svc" "tyc-server/app/main/api/internal/types" "tyc-server/app/main/model" "tyc-server/common/ctxdata" "tyc-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) } // 获取今日统计数据 today := time.Now().Truncate(24 * time.Hour) 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 }