Files
kra-new/internal/data/business/dashboard.go
T

95 lines
4.2 KiB
Go

package business
import (
"context"
"golang.org/x/sync/errgroup"
"kra/internal/biz/business"
)
type dashboardRepo struct{ data Provider }
func NewDashboardRepo(data Provider) business.DashboardRepo { return &dashboardRepo{data: data} }
func (r *dashboardRepo) Overview(ctx context.Context, scope business.AnalyticsScope, sources []string, w business.DashboardWindow) (*business.DashboardData, error) {
db := r.data.DB().WithContext(ctx)
out := &business.DashboardData{Current: business.DashboardMetrics{Pay: "0.00"}, Previous: business.DashboardMetrics{Pay: "0.00"}, Available: true}
empty, available, err := workbenchAvailable(db, scope, sources, "")
if err != nil {
return nil, err
}
out.Available = available
if empty || !available {
return out, nil
}
begin, end, previous := w.Begin.Format("2006-01-02"), w.End.Format("2006-01-02"), w.PreviousBegin.Format("2006-01-02")
f := business.AnalyticsFilter{Sources: sources, Begin: previous, End: end}
mode := 0
if scope.IDCardDedup {
mode = 1
}
var counts []struct {
Current bool
Metric int
Count int64
}
var amounts struct{ CurrentPay, PreviousPay string }
type activeRow struct {
Current bool
SourceDB string `gorm:"column:source_db"`
PromoteID uint64
}
var registered, paid []activeRow
var channels struct{ CurrentNew, PreviousNew, CurrentEffective, PreviousEffective int64 }
group, gctx := errgroup.WithContext(ctx)
group.SetLimit(2)
qdb := db.WithContext(gctx)
group.Go(func() error {
return storageError(analyticsQuery(qdb, scope, f, "tab_sw_report_day_key", mode).Where("r.metric IN (1,2)").Select("(r.stat_date>=?) AS current,r.metric,COUNT(DISTINCT "+portraitIdentity(qdb, scope.IDCardDedup)+") AS count", begin).Group("current,r.metric").Scan(&counts).Error)
})
group.Go(func() error {
return storageError(analyticsQuery(qdb, scope, f, "tab_sw_report_day", 0).Select("CAST(COALESCE(SUM(CASE WHEN r.stat_date>=? THEN r.total_pay ELSE 0 END),0) AS CHAR) AS current_pay,CAST(COALESCE(SUM(CASE WHEN r.stat_date<? THEN r.total_pay ELSE 0 END),0) AS CHAR) AS previous_pay", begin, begin).Scan(&amounts).Error)
})
group.Go(func() error {
return storageError(analyticsQuery(qdb, scope, f, "tab_sw_report_day_key", mode).Where("r.metric=1 AND r.identity_key IS NOT NULL").Select("DISTINCT (r.stat_date>=?) AS current,r.source_db,r.promote_id", begin).Scan(&registered).Error)
})
group.Go(func() error {
return storageError(analyticsQuery(qdb, scope, f, "tab_sw_report_day", 0).Select("(r.stat_date>=?) AS current,r.source_db,r.promote_id", begin).Group("current,r.source_db,r.promote_id").Having("SUM(r.total_pay)>0").Scan(&paid).Error)
})
group.Go(func() error {
q := analyticsBasePromotes(qdb, scope, f, "p")
q = joinEffectiveness(q)
return storageError(q.Select("COALESCE(SUM(CASE WHEN p.create_time>=? AND p.create_time<? THEN 1 ELSE 0 END),0) AS current_new,"+
"COALESCE(SUM(CASE WHEN p.create_time>=? AND p.create_time<? THEN 1 ELSE 0 END),0) AS previous_new,"+
"COALESCE(SUM(CASE WHEN e.qualified_at>=? AND e.qualified_at<? THEN 1 ELSE 0 END),0) AS current_effective,"+
"COALESCE(SUM(CASE WHEN e.qualified_at>=? AND e.qualified_at<? THEN 1 ELSE 0 END),0) AS previous_effective",
w.Begin.Unix(), w.End.AddDate(0, 0, 1).Unix(), w.PreviousBegin.Unix(), w.Begin.Unix(), w.Begin.Unix(), w.End.AddDate(0, 0, 1).Unix(), w.PreviousBegin.Unix(), w.Begin.Unix()).Scan(&channels).Error)
})
if err := group.Wait(); err != nil {
return nil, err
}
for _, c := range counts {
target := &out.Previous
if c.Current {
target = &out.Current
}
if c.Metric == 1 {
target.Register = c.Count
} else {
target.Active = c.Count
}
}
current, prior := map[business.ChannelKey]bool{}, map[business.ChannelKey]bool{}
for _, a := range append(registered, paid...) {
target := prior
if a.Current {
target = current
}
target[business.ChannelKey{SourceDB: a.SourceDB, ID: a.PromoteID}] = true
}
out.Current.ActiveChannels, out.Previous.ActiveChannels = int64(len(current)), int64(len(prior))
out.Current.NewChannels, out.Previous.NewChannels = channels.CurrentNew, channels.PreviousNew
out.Current.Effective, out.Previous.Effective = channels.CurrentEffective, channels.PreviousEffective
out.Current.Pay, out.Previous.Pay = amounts.CurrentPay, amounts.PreviousPay
return out, nil
}