feat: complete remaining Go backend modules
This commit is contained in:
1 parent
cea2751dc5
commit
aef5a97165
145 files changed
+18376
-199
No files matched your search
@@ -1,6 +1,7 @@
|
||||
package usage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
@@ -17,11 +18,20 @@ const (
|
||||
)
|
||||
|
||||
var ErrForbidden = errors.New("usage scope forbidden")
|
||||
var ErrInvalidDateRange = errors.New("invalid usage date range")
|
||||
var ErrDateRangeTooLong = errors.New("usage date range exceeds 3660 days")
|
||||
|
||||
const UnassignedOrganizationID = "__unassigned__"
|
||||
|
||||
var shanghai = time.FixedZone("Asia/Shanghai", 8*60*60)
|
||||
|
||||
type DateRange struct {
|
||||
From, To, StartDate, EndDate string
|
||||
DayCount int
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
StartDate string `json:"startDate"`
|
||||
EndDate string `json:"endDate"`
|
||||
Label string `json:"label"`
|
||||
DayCount int `json:"dayCount"`
|
||||
}
|
||||
|
||||
func PresetRange(preset Preset, now time.Time) (DateRange, error) {
|
||||
@@ -39,7 +49,8 @@ func PresetRange(preset Preset, now time.Time) (DateRange, error) {
|
||||
return DateRange{}, fmt.Errorf("unknown usage preset %q", preset)
|
||||
}
|
||||
end := time.Date(today.Year(), today.Month(), today.Day(), 0, 0, 0, 0, shanghai)
|
||||
return DateRange{From: start.Format(time.RFC3339), To: end.AddDate(0, 0, 1).Format(time.RFC3339), StartDate: start.Format("2006-01-02"), EndDate: end.Format("2006-01-02"), DayCount: int(end.Sub(start).Hours()/24) + 1}, nil
|
||||
labels := map[Preset]string{PresetToday: "今天", Preset7Days: "近 7 天", Preset30Days: "近 30 天", PresetMonth: "本月"}
|
||||
return DateRange{From: start.Format(time.RFC3339), To: end.AddDate(0, 0, 1).Format(time.RFC3339), StartDate: start.Format("2006-01-02"), EndDate: end.Format("2006-01-02"), Label: labels[preset], DayCount: int(end.Sub(start).Hours()/24) + 1}, nil
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
@@ -53,7 +64,111 @@ type Repository interface {
|
||||
Insert(Event) (Event, bool, error)
|
||||
List(Filters) ([]Event, error)
|
||||
}
|
||||
type Service struct{ Repository Repository }
|
||||
type OrganizationOptionSource interface {
|
||||
ListOrganizationOptions(context.Context, Requester) ([]Option, error)
|
||||
}
|
||||
type OrganizationOptionSourceFunc func(context.Context, Requester) ([]Option, error)
|
||||
|
||||
func (fn OrganizationOptionSourceFunc) ListOrganizationOptions(ctx context.Context, requester Requester) ([]Option, error) {
|
||||
return fn(ctx, requester)
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
Repository Repository
|
||||
OrganizationOptions OrganizationOptionSource
|
||||
}
|
||||
|
||||
type PersonalRequest struct {
|
||||
AccountID string
|
||||
Preset Preset
|
||||
Now time.Time
|
||||
}
|
||||
type AdminRequest struct {
|
||||
Requester
|
||||
StartDate, EndDate, OwnerID, Capability, Provider string
|
||||
Now time.Time
|
||||
RedactAccounts bool
|
||||
}
|
||||
type CountItem struct {
|
||||
Key string `json:"key"`
|
||||
Label string `json:"label"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
type Record struct {
|
||||
ID string `json:"id"`
|
||||
JobID string `json:"jobId"`
|
||||
OwnerID string `json:"ownerId"`
|
||||
AccountName string `json:"accountName"`
|
||||
AccountUsername string `json:"accountUsername,omitempty"`
|
||||
OrganizationID string `json:"organizationId"`
|
||||
OrganizationName string `json:"organizationName"`
|
||||
Capability string `json:"capability"`
|
||||
CapabilityLabel string `json:"capabilityLabel"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
ProviderLabel string `json:"providerLabel"`
|
||||
ReqKey string `json:"reqKey,omitempty"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
type TrendPoint struct {
|
||||
Date string `json:"date"`
|
||||
Label string `json:"label"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
type Summary struct {
|
||||
Total int `json:"total"`
|
||||
ActiveAccounts int `json:"activeAccounts"`
|
||||
ActiveOrganizations int `json:"activeOrganizations"`
|
||||
AveragePerDay float64 `json:"averagePerDay"`
|
||||
}
|
||||
type organizationRow struct {
|
||||
OrganizationID string `json:"organizationId"`
|
||||
OrganizationName string `json:"organizationName"`
|
||||
Count int `json:"count"`
|
||||
AccountCount int `json:"accountCount"`
|
||||
LastUsedAt string `json:"lastUsedAt,omitempty"`
|
||||
accounts map[string]bool
|
||||
}
|
||||
type accountRow struct {
|
||||
OwnerID string `json:"ownerId"`
|
||||
AccountName string `json:"accountName"`
|
||||
AccountUsername string `json:"accountUsername,omitempty"`
|
||||
OrganizationID string `json:"organizationId"`
|
||||
OrganizationName string `json:"organizationName"`
|
||||
Count int `json:"count"`
|
||||
LastUsedAt string `json:"lastUsedAt,omitempty"`
|
||||
}
|
||||
type Options struct {
|
||||
Organizations []Option `json:"organizations"`
|
||||
Accounts []Option `json:"accounts"`
|
||||
Capabilities []Option `json:"capabilities"`
|
||||
Providers []Option `json:"providers"`
|
||||
}
|
||||
type Option struct {
|
||||
Value string `json:"value"`
|
||||
Label string `json:"label"`
|
||||
}
|
||||
type PersonalReport struct {
|
||||
Preset Preset `json:"preset"`
|
||||
Range DateRange `json:"range"`
|
||||
Total int `json:"total"`
|
||||
ByCapability []CountItem `json:"byCapability"`
|
||||
Recent []Record `json:"recent"`
|
||||
}
|
||||
type AdminReport struct {
|
||||
Range DateRange `json:"range"`
|
||||
Summary Summary `json:"summary"`
|
||||
Trend []TrendPoint `json:"trend"`
|
||||
ByCapability []CountItem `json:"byCapability"`
|
||||
ByProvider []CountItem `json:"byProvider"`
|
||||
Organizations any `json:"organizations"`
|
||||
Accounts any `json:"accounts"`
|
||||
Recent any `json:"recent"`
|
||||
Options Options `json:"options"`
|
||||
}
|
||||
type Reporter interface {
|
||||
Personal(context.Context, PersonalRequest) (PersonalReport, error)
|
||||
Admin(context.Context, AdminRequest) (AdminReport, error)
|
||||
}
|
||||
|
||||
func (s Service) Record(event Event) (*Event, error) {
|
||||
if event.Source == "api" || event.Provider == "mock" {
|
||||
|
||||
Reference in new issue
Block a user