Skip to content

Commit 59152af

Browse files
committed
refactor: streamline chat UI and session handling
1 parent a0857d9 commit 59152af

29 files changed

Lines changed: 3898 additions & 669 deletions

File tree

backend/docs/docs.go

Lines changed: 675 additions & 225 deletions
Large diffs are not rendered by default.

backend/docs/swagger.json

Lines changed: 675 additions & 225 deletions
Large diffs are not rendered by default.

backend/docs/swagger.yaml

Lines changed: 505 additions & 214 deletions
Large diffs are not rendered by default.

backend/internal/app/app.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ func NewApp() (*App, error) {
283283
adminService.SetAuthSecurityService(authService)
284284
adminService.SetSystemEventService(systemEventService)
285285
adminService.SetUsageLogService(billingService)
286+
adminService.SetUsageStatisticsService(billingService)
286287
adminService.SetOrderLogService(billingService)
287288
adminService.SetConversationEventService(conversationService)
288289
adminService.SetLogCleanupService(logCleanupService)

backend/internal/application/admin/service.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ type usageLogService interface {
9696
ListUsageLogs(ctx context.Context, page int, pageSize int, filter billing.UsageLogListFilter) ([]domainbilling.UsageLedger, int64, error)
9797
}
9898

99+
type usageStatisticsService interface {
100+
GetUsageStatistics(ctx context.Context, filter billing.UsageStatisticsFilter) (domainbilling.UsageStatistics, error)
101+
}
102+
99103
type orderLogService interface {
100104
ListPaymentOrders(ctx context.Context, page int, pageSize int, filter billing.PaymentOrderListFilter) ([]domainbilling.PaymentOrder, int64, error)
101105
}
@@ -119,6 +123,7 @@ type Service struct {
119123
auditService auditService
120124
systemEventService systemEventService
121125
usageLogService usageLogService
126+
usageStatisticsService usageStatisticsService
122127
orderLogService orderLogService
123128
conversationEventSvc conversationEventService
124129
logCleanupService logCleanupService
@@ -187,6 +192,11 @@ func (s *Service) SetUsageLogService(service usageLogService) {
187192
s.usageLogService = service
188193
}
189194

195+
// SetUsageStatisticsService 注入管理员用量统计能力。
196+
func (s *Service) SetUsageStatisticsService(service usageStatisticsService) {
197+
s.usageStatisticsService = service
198+
}
199+
190200
// SetOrderLogService 注入支付订单日志查询能力。
191201
func (s *Service) SetOrderLogService(service orderLogService) {
192202
s.orderLogService = service

backend/internal/application/admin/service_logs.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ func (s *Service) ListUsageLogs(ctx context.Context, page int, pageSize int, fil
2828
return s.usageLogService.ListUsageLogs(ctx, page, pageSize, filter)
2929
}
3030

31+
// GetUsageStatistics 查询管理员仪表盘的全局用量聚合。
32+
func (s *Service) GetUsageStatistics(ctx context.Context, filter billing.UsageStatisticsFilter) (domainbilling.UsageStatistics, error) {
33+
if s.usageStatisticsService == nil {
34+
return domainbilling.UsageStatistics{}, errors.New("usage statistics service unavailable")
35+
}
36+
return s.usageStatisticsService.GetUsageStatistics(ctx, filter)
37+
}
38+
3139
// ListPaymentOrders 查询管理员支付订单记录。
3240
func (s *Service) ListPaymentOrders(ctx context.Context, page int, pageSize int, filter billing.PaymentOrderListFilter) ([]domainbilling.PaymentOrder, int64, error) {
3341
if s.orderLogService == nil {

backend/internal/application/billing/service.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,87 @@ func (s *Service) ListUsageLogs(ctx context.Context, page int, pageSize int, fil
22662266
}, offset, limit)
22672267
}
22682268

2269+
// UsageStatisticsFilter 描述管理员仪表盘的用量统计条件。
2270+
type UsageStatisticsFilter struct {
2271+
StartDate time.Time
2272+
EndDate time.Time
2273+
UserID uint
2274+
PlatformModelName string
2275+
BillingScope string
2276+
RankBy string
2277+
}
2278+
2279+
// GetUsageStatistics 查询管理员仪表盘使用的全局用量统计。
2280+
func (s *Service) GetUsageStatistics(ctx context.Context, filter UsageStatisticsFilter) (domainbilling.UsageStatistics, error) {
2281+
statisticsRepo, ok := s.repo.(repository.UsageStatisticsRepository)
2282+
if !ok {
2283+
return domainbilling.UsageStatistics{}, errors.New("usage statistics repository unavailable")
2284+
}
2285+
2286+
startDate := time.Date(filter.StartDate.Year(), filter.StartDate.Month(), filter.StartDate.Day(), 0, 0, 0, 0, filter.StartDate.Location())
2287+
endDate := time.Date(filter.EndDate.Year(), filter.EndDate.Month(), filter.EndDate.Day(), 0, 0, 0, 0, filter.EndDate.Location())
2288+
if endDate.Before(startDate) {
2289+
return domainbilling.UsageStatistics{}, errors.New("invalid usage statistics date range")
2290+
}
2291+
days := int(endDate.Sub(startDate).Hours()/24) + 1
2292+
if days <= 0 || days > 366 {
2293+
return domainbilling.UsageStatistics{}, errors.New("invalid usage statistics date range")
2294+
}
2295+
2296+
granularity := "day"
2297+
if days > 90 {
2298+
granularity = "month"
2299+
}
2300+
result, err := statisticsRepo.GetUsageStatistics(ctx, repository.UsageStatisticsFilter{
2301+
StartDate: startDate,
2302+
EndDateExclusive: endDate.AddDate(0, 0, 1),
2303+
UserID: filter.UserID,
2304+
PlatformModelName: strings.TrimSpace(filter.PlatformModelName),
2305+
BillingScope: strings.TrimSpace(filter.BillingScope),
2306+
Granularity: granularity,
2307+
RankBy: strings.TrimSpace(filter.RankBy),
2308+
RankLimit: 10,
2309+
})
2310+
if err != nil {
2311+
return domainbilling.UsageStatistics{}, err
2312+
}
2313+
result.Granularity = granularity
2314+
result.Trend = fillUsageStatisticsTrend(result.Trend, startDate, endDate, granularity)
2315+
return result, nil
2316+
}
2317+
2318+
func fillUsageStatisticsTrend(
2319+
items []domainbilling.UsageStatisticsTrendPoint,
2320+
startDate time.Time,
2321+
endDate time.Time,
2322+
granularity string,
2323+
) []domainbilling.UsageStatisticsTrendPoint {
2324+
byPeriod := make(map[string]domainbilling.UsageStatisticsTrendPoint, len(items))
2325+
for _, item := range items {
2326+
byPeriod[item.PeriodStart.Format("2006-01-02")] = item
2327+
}
2328+
2329+
current := startDate
2330+
if granularity == "month" {
2331+
current = time.Date(startDate.Year(), startDate.Month(), 1, 0, 0, 0, 0, startDate.Location())
2332+
}
2333+
results := make([]domainbilling.UsageStatisticsTrendPoint, 0, len(items))
2334+
for !current.After(endDate) {
2335+
key := current.Format("2006-01-02")
2336+
if item, exists := byPeriod[key]; exists {
2337+
results = append(results, item)
2338+
} else {
2339+
results = append(results, domainbilling.UsageStatisticsTrendPoint{PeriodStart: current})
2340+
}
2341+
if granularity == "month" {
2342+
current = current.AddDate(0, 1, 0)
2343+
} else {
2344+
current = current.AddDate(0, 0, 1)
2345+
}
2346+
}
2347+
return results
2348+
}
2349+
22692350
// ListPaymentOrders 分页查询管理员支付订单记录。
22702351
func (s *Service) ListPaymentOrders(ctx context.Context, page int, pageSize int, filter PaymentOrderListFilter) ([]domainbilling.PaymentOrder, int64, error) {
22712352
offset, limit := normalizePage(page, pageSize)

backend/internal/domain/billing/types.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,3 +406,45 @@ type UsageDailyModelSummary struct {
406406
AvgLatencyMS int64
407407
BilledNanousd int64
408408
}
409+
410+
// UsageStatisticsMetrics 表示一组聚合后的用量指标。
411+
type UsageStatisticsMetrics struct {
412+
RecordCount int64
413+
InputTokens int64
414+
CacheReadTokens int64
415+
CacheWriteTokens int64
416+
OutputTokens int64
417+
ReasoningTokens int64
418+
CallCount int64
419+
AvgLatencyMS int64
420+
BilledNanousd int64
421+
}
422+
423+
// UsageStatisticsTrendPoint 表示一个按日或按月聚合的趋势点。
424+
type UsageStatisticsTrendPoint struct {
425+
PeriodStart time.Time
426+
Metrics UsageStatisticsMetrics
427+
}
428+
429+
// UsageStatisticsModelRank 表示平台模型的用量排名项。
430+
type UsageStatisticsModelRank struct {
431+
PlatformModelName string
432+
Metrics UsageStatisticsMetrics
433+
Trend []UsageStatisticsTrendPoint
434+
}
435+
436+
// UsageStatisticsUserRank 表示用户的用量排名项。
437+
type UsageStatisticsUserRank struct {
438+
UserID uint
439+
Metrics UsageStatisticsMetrics
440+
Trend []UsageStatisticsTrendPoint
441+
}
442+
443+
// UsageStatistics 表示管理员仪表盘使用的全局用量聚合。
444+
type UsageStatistics struct {
445+
Granularity string
446+
Totals UsageStatisticsMetrics
447+
Trend []UsageStatisticsTrendPoint
448+
TopModels []UsageStatisticsModelRank
449+
TopUsers []UsageStatisticsUserRank
450+
}

0 commit comments

Comments
 (0)