package crm import ( "context" crmUC "apps/backend/internal/module/crm/usecase" "apps/backend/internal/svc" "apps/backend/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type GetCrmStatsLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewGetCrmStatsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCrmStatsLogic { return &GetCrmStatsLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx} } func (l *GetCrmStatsLogic) GetCrmStats(req *types.CrmStatsReq) (*types.CrmStatsData, error) { uid, err := ownerUID(l.ctx) if err != nil { return nil, err } stats, err := l.svcCtx.Crm.Stats(l.ctx, uid, req.From, req.To) if err != nil { return nil, err } terms := make([]types.TermConversionStat, 0, len(stats.Terms)) for _, s := range stats.Terms { row := types.TermConversionStat{ Term: s.Key, Accepted: s.Accepted, Replied: s.Replied, Won: s.Won, InsufficientSample: s.Accepted < crmUC.StatsMinSample, } // 樣本不足只給絕對數,不給會被過度解讀的比率(spec §9.5) if !row.InsufficientSample { row.ConversionRate = float64(s.Won) / float64(s.Accepted) } terms = append(terms, row) } sources := make([]types.SourceConversionStat, 0, len(stats.Sources)) for _, s := range stats.Sources { sources = append(sources, types.SourceConversionStat{ Source: s.Key, Won: s.Won, InsufficientSample: s.Won < crmUC.StatsMinSample, }) } return &types.CrmStatsData{ Terms: terms, Variants: []types.VariantConversionStat{}, Sources: sources, UnavailableDimensions: stats.UnavailableDimensions, }, nil }