package service import ( "context" "database/sql" "time" "tyc-server/app/main/model" "tyc-server/common/xerr" "github.com/pkg/errors" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stores/sqlx" ) type AdminPromotionLinkStatsService struct { logx.Logger svcCtx *ServiceContext } type ServiceContext struct { AdminPromotionLinkModel model.AdminPromotionLinkModel AdminPromotionLinkStatsTotalModel model.AdminPromotionLinkStatsTotalModel AdminPromotionLinkStatsHistoryModel model.AdminPromotionLinkStatsHistoryModel } func NewAdminPromotionLinkStatsService(svcCtx *ServiceContext) *AdminPromotionLinkStatsService { return &AdminPromotionLinkStatsService{ Logger: logx.WithContext(context.Background()), svcCtx: svcCtx, } } // ensureTotalStats 确保总统计记录存在,如果不存在则创建 func (s *AdminPromotionLinkStatsService) ensureTotalStats(ctx context.Context, session sqlx.Session, linkId int64) (*model.AdminPromotionLinkStatsTotal, error) { totalStats, err := s.svcCtx.AdminPromotionLinkStatsTotalModel.FindOneByLinkId(ctx, linkId) if err != nil { if errors.Is(err, model.ErrNotFound) { // 如果记录不存在,创建新记录 totalStats = &model.AdminPromotionLinkStatsTotal{ LinkId: linkId, ClickCount: 0, PayCount: 0, PayAmount: 0, } _, err = s.svcCtx.AdminPromotionLinkStatsTotalModel.Insert(ctx, session, totalStats) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建总统计记录失败: %+v", err) } // 重新获取创建后的记录 totalStats, err = s.svcCtx.AdminPromotionLinkStatsTotalModel.FindOneByLinkId(ctx, linkId) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取新创建的总统计记录失败: %+v", err) } } else { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询总统计失败: %+v", err) } } return totalStats, nil } // ensureHistoryStats 确保历史统计记录存在,如果不存在则创建 func (s *AdminPromotionLinkStatsService) ensureHistoryStats(ctx context.Context, session sqlx.Session, linkId int64, today time.Time) (*model.AdminPromotionLinkStatsHistory, error) { historyStats, err := s.svcCtx.AdminPromotionLinkStatsHistoryModel.FindOneByLinkIdStatsDate(ctx, linkId, today) if err != nil { if errors.Is(err, model.ErrNotFound) { // 如果记录不存在,创建新记录 historyStats = &model.AdminPromotionLinkStatsHistory{ LinkId: linkId, StatsDate: today, ClickCount: 0, PayCount: 0, PayAmount: 0, } _, err = s.svcCtx.AdminPromotionLinkStatsHistoryModel.Insert(ctx, session, historyStats) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建今日统计记录失败: %+v", err) } // 重新获取创建后的记录 historyStats, err = s.svcCtx.AdminPromotionLinkStatsHistoryModel.FindOneByLinkIdStatsDate(ctx, linkId, today) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取新创建的今日统计记录失败: %+v", err) } } else { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询今日统计记录失败: %+v", err) } } return historyStats, nil } // UpdateLinkStats 更新推广链接统计 func (s *AdminPromotionLinkStatsService) UpdateLinkStats(ctx context.Context, linkId int64) error { return s.svcCtx.AdminPromotionLinkStatsTotalModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error { // 确保总统计记录存在 totalStats, err := s.ensureTotalStats(ctx, session, linkId) if err != nil { return err } // 更新总统计 totalStats.ClickCount++ totalStats.LastClickTime = sql.NullTime{Time: time.Now(), Valid: true} err = s.svcCtx.AdminPromotionLinkStatsTotalModel.UpdateWithVersion(ctx, session, totalStats) if err != nil { return 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) historyStats, err := s.ensureHistoryStats(ctx, session, linkId, today) if err != nil { return err } // 更新历史统计 historyStats.ClickCount++ historyStats.LastClickTime = sql.NullTime{Time: time.Now(), Valid: true} err = s.svcCtx.AdminPromotionLinkStatsHistoryModel.UpdateWithVersion(ctx, session, historyStats) if err != nil { return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新历史统计失败: %+v", err) } return nil }) } // UpdatePaymentStats 更新付费统计 func (s *AdminPromotionLinkStatsService) UpdatePaymentStats(ctx context.Context, linkId int64, amount float64) error { return s.svcCtx.AdminPromotionLinkStatsTotalModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error { // 确保总统计记录存在 totalStats, err := s.ensureTotalStats(ctx, session, linkId) if err != nil { return err } // 更新总统计 totalStats.PayCount++ totalStats.PayAmount += amount totalStats.LastPayTime = sql.NullTime{Time: time.Now(), Valid: true} err = s.svcCtx.AdminPromotionLinkStatsTotalModel.UpdateWithVersion(ctx, session, totalStats) if err != nil { return 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) historyStats, err := s.ensureHistoryStats(ctx, session, linkId, today) if err != nil { return err } // 更新历史统计 historyStats.PayCount++ historyStats.PayAmount += amount historyStats.LastPayTime = sql.NullTime{Time: time.Now(), Valid: true} err = s.svcCtx.AdminPromotionLinkStatsHistoryModel.UpdateWithVersion(ctx, session, historyStats) if err != nil { return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新历史统计失败: %+v", err) } return nil }) } // CreateLinkStats 创建新的推广链接统计记录 func (s *AdminPromotionLinkStatsService) CreateLinkStats(ctx context.Context, linkId int64) error { return s.svcCtx.AdminPromotionLinkStatsTotalModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error { // 检查总统计记录是否已存在 _, err := s.svcCtx.AdminPromotionLinkStatsTotalModel.FindOneByLinkId(ctx, linkId) if err == nil { // 记录已存在,不需要创建 return nil } if err != model.ErrNotFound { return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询总统计记录失败: %+v", err) } // 创建总统计记录 totalStats := &model.AdminPromotionLinkStatsTotal{ LinkId: linkId, ClickCount: 0, PayCount: 0, PayAmount: 0, } _, err = s.svcCtx.AdminPromotionLinkStatsTotalModel.Insert(ctx, session, totalStats) if err != nil { return 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) historyStats := &model.AdminPromotionLinkStatsHistory{ LinkId: linkId, StatsDate: today, ClickCount: 0, PayCount: 0, PayAmount: 0, } _, err = s.svcCtx.AdminPromotionLinkStatsHistoryModel.Insert(ctx, session, historyStats) if err != nil { return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建历史统计记录失败: %+v", err) } return nil }) }