package business import ( "context" "kra/internal/biz/business" "kra/internal/service/dto" "strings" "time" ) type AnalyticsUsecase interface { List(context.Context, business.AnalyticsKind, business.AnalyticsFilter, int, int) (*business.AnalyticsPage, error) ListAll(context.Context, business.AnalyticsKind, business.AnalyticsFilter) (*business.AnalyticsPage, error) } type AnalyticsService struct{ uc AnalyticsUsecase } func NewAnalyticsService(uc *business.AnalyticsUsecase) *AnalyticsService { return &AnalyticsService{uc: uc} } func analyticsRequest(req *dto.AnalyticsQuery) (business.AnalyticsFilter, error) { if req == nil { return business.AnalyticsFilter{}, business.ErrAnalyticsInput } sources, err := normalizePlatforms(req.Sources) if err != nil { return business.AnalyticsFilter{}, err } f := business.AnalyticsFilter{Sources: sources, GameNames: splitQueryValues(req.GameNames), PromoteName: strings.TrimSpace(req.PromoteName), PromoteType: req.PromoteType, SortField: strings.TrimSpace(req.SortField), Ascending: strings.EqualFold(strings.TrimSpace(req.SortOrder), "asc")} f.HasRegister, f.HasPay = req.HasRegister, req.HasPay begin, end := strings.TrimSpace(req.BeginTime), strings.TrimSpace(req.EndTime) location := time.FixedZone("Asia/Shanghai", 8*3600) if begin != "" { b, err := time.ParseInLocation("2006-01-02", begin, location) if err != nil { return f, business.ErrAnalyticsDate } f.StartDate = &b } if end != "" { e, err := time.ParseInLocation("2006-01-02", end, location) if err != nil || f.StartDate != nil && e.Before(*f.StartDate) { return f, business.ErrAnalyticsDate } f.EndDate = &e } return f, nil } func analyticsMetrics(row *business.AnalyticsRow) dto.AnalyticsMetrics { return dto.AnalyticsMetrics{Register: row.Counts.Register, Active: row.Counts.Active, PayUsers: row.Counts.Pay, NewPayUsers: row.Counts.NewPay, TotalPay: row.Pay, PayRate: row.PayRate} } func channelAnalyticsRow(row *business.AnalyticsRow, summary bool) *dto.ChannelAnalyticsRow { result := &dto.ChannelAnalyticsRow{SourceDB: row.SourceDB, SourceDBLabel: business.PlatformName(row.SourceDB), PromoteName: row.Name, PromoteType: row.PromoteType, BusierName: row.BusinessName(), AnalyticsMetrics: analyticsMetrics(row)} if !summary { result.PromoteID = &row.ID } return result } func gameAnalyticsRow(row *business.AnalyticsRow, summary bool) *dto.GameAnalyticsRow { result := &dto.GameAnalyticsRow{SourceDB: row.SourceDB, SourceDBLabel: business.PlatformName(row.SourceDB), GameName: row.Name, AnalyticsMetrics: analyticsMetrics(row), ARPU: row.ARPU, ARPPU: row.ARPPU} if !summary { result.GameID = &row.ID } return result } func (s *AnalyticsService) Channels(ctx context.Context, req *dto.AnalyticsQuery) (*dto.ChannelAnalyticsPage, error) { f, err := analyticsRequest(req) if err != nil { return nil, err } page, err := s.uc.List(ctx, business.ChannelAnalytics, f, req.Page, req.PageSize) if err != nil { return nil, err } result := &dto.ChannelAnalyticsPage{Rows: []*dto.ChannelAnalyticsRow{}, Total: page.Total, BeginTime: page.Begin, EndTime: page.End, Available: page.Available} for _, row := range page.Rows { result.Rows = append(result.Rows, channelAnalyticsRow(row, false)) } if page.Summary != nil { result.EffectiveCount = &page.EffectiveCount result.Summary = channelAnalyticsRow(page.Summary, true) result.ChannelCount = &page.Total result.TotalRegisterCount = &page.Summary.Counts.Register result.TotalPayAmount = &page.Summary.Pay result.AvgPayRate = &page.Summary.PayRate } return result, nil } func (s *AnalyticsService) Games(ctx context.Context, req *dto.AnalyticsQuery) (*dto.GameAnalyticsPage, error) { f, err := analyticsRequest(req) if err != nil { return nil, err } page, err := s.uc.List(ctx, business.GameAnalytics, f, req.Page, req.PageSize) if err != nil { return nil, err } result := &dto.GameAnalyticsPage{Rows: []*dto.GameAnalyticsRow{}, Total: page.Total, BeginTime: page.Begin, EndTime: page.End, Available: page.Available} for _, row := range page.Rows { result.Rows = append(result.Rows, gameAnalyticsRow(row, false)) } if page.Summary != nil { result.Summary = gameAnalyticsRow(page.Summary, true) } return result, nil }