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

105 lines
3.8 KiB
Go

package business
import (
"context"
"strconv"
"time"
)
type DashboardWindow struct{ Begin, End, PreviousBegin, PreviousEnd time.Time }
type DashboardMetrics struct {
Register, Active, Effective, ActiveChannels, NewChannels int64
LockedChannels, TerminatedChannels int64
Pay string
}
type DashboardData struct {
Current, Previous DashboardMetrics
Available bool
EventsAvailable bool
}
type DashboardRepo interface {
Overview(context.Context, AnalyticsScope, []string, DashboardWindow) (*DashboardData, error)
}
type DashboardOverview struct {
Cards map[string]*WorkbenchCard
Begin, End string
Settings OtherSettings
Available bool
}
type DashboardUsecase struct {
repo DashboardRepo
workbench *WorkbenchUsecase
effective *EffectivenessUsecase
now func() time.Time
}
func NewDashboardUsecase(repo DashboardRepo, workbench *WorkbenchUsecase, effective *EffectivenessUsecase) *DashboardUsecase {
return &DashboardUsecase{repo: repo, workbench: workbench, effective: effective, now: time.Now}
}
func (uc *DashboardUsecase) Overview(ctx context.Context, sources []string, period string, begin, end *time.Time) (*DashboardOverview, error) {
scope, err := uc.workbench.scope(ctx, sources)
if err != nil {
return nil, err
}
today := workbenchWindow(uc.now()).Today
b, e := today, today
switch period {
case "", "today":
case "yesterday":
b, e = today.AddDate(0, 0, -1), today.AddDate(0, 0, -1)
case "last7":
b = today.AddDate(0, 0, -6)
case "last30":
b = today.AddDate(0, 0, -29)
case "custom":
if begin == nil || end == nil {
return nil, ErrPerformanceInput
}
b, e = *begin, *end
default:
return nil, ErrPerformanceInput
}
if e.Before(b) || e.After(today) {
return nil, ErrPerformanceInput
}
days := int(e.Sub(b).Hours()/24) + 1
window := DashboardWindow{Begin: b, End: e, PreviousBegin: b.AddDate(0, 0, -days), PreviousEnd: b.AddDate(0, 0, -1)}
if err := uc.effective.Ensure(ctx); err != nil {
return nil, err
}
rule, err := uc.effective.Rule(ctx)
if err != nil {
return nil, err
}
data, err := uc.repo.Overview(ctx, scope, sources, window)
if err != nil {
return nil, err
}
r := &DashboardOverview{Cards: map[string]*WorkbenchCard{}, Begin: b.Format("2006-01-02"), End: e.Format("2006-01-02"), Settings: rule, Available: data.Available}
num := func(v int64) string { return strconv.FormatInt(v, 10) }
for _, card := range []struct{ key, current, previous string }{{"todayRegister", num(data.Current.Register), num(data.Previous.Register)}, {"todayActive", num(data.Current.Active), num(data.Previous.Active)}, {"todayPay", data.Current.Pay, data.Previous.Pay}, {"effectivePromote", num(data.Current.Effective), num(data.Previous.Effective)}, {"activePromote", num(data.Current.ActiveChannels), num(data.Previous.ActiveChannels)}, {"newPromote", num(data.Current.NewChannels), num(data.Previous.NewChannels)}} {
value, err := workbenchCard(card.current, card.previous, "较上一同期", data.Available)
if err != nil {
return nil, err
}
r.Cards[card.key] = value
}
// The imported SDK channel table has only current state; historical event
// counts must stay unavailable until a timestamped event source is connected.
for _, card := range []struct {
key string
current, previous int64
}{{"lockedPromote", data.Current.LockedChannels, data.Previous.LockedChannels}, {"terminatedPromote", data.Current.TerminatedChannels, data.Previous.TerminatedChannels}} {
label := "较上一同期"
if !data.EventsAvailable {
label = "事件数据未接入"
}
value, err := workbenchCard(num(card.current), num(card.previous), label, data.Available && data.EventsAvailable)
if err != nil {
return nil, err
}
r.Cards[card.key] = value
}
return r, nil
}