- 新增 domain 层:model、provider、route、stats 实体 - 新增 service 层:models、providers、routing、stats 业务逻辑 - 新增 repository 层:models、providers、stats 数据访问 - 新增 pkg 工具包:errors、logger、validator - 新增中间件:CORS、logging、recovery、request ID - 新增数据库迁移:初始 schema 和索引 - 新增单元测试和集成测试 - 新增规范文档:config-management、database-migration、error-handling、layered-architecture、middleware-system、request-validation、structured-logging、test-coverage - 移除 config 子包和 model_router(已迁移至分层架构)
86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
package service
|
|
|
|
import (
|
|
"time"
|
|
|
|
"nex/backend/internal/domain"
|
|
"nex/backend/internal/repository"
|
|
)
|
|
|
|
type statsService struct {
|
|
statsRepo repository.StatsRepository
|
|
}
|
|
|
|
func NewStatsService(statsRepo repository.StatsRepository) StatsService {
|
|
return &statsService{statsRepo: statsRepo}
|
|
}
|
|
|
|
func (s *statsService) Record(providerID, modelName string) error {
|
|
return s.statsRepo.Record(providerID, modelName)
|
|
}
|
|
|
|
func (s *statsService) Get(providerID, modelName string, startDate, endDate *time.Time) ([]domain.UsageStats, error) {
|
|
return s.statsRepo.Query(providerID, modelName, startDate, endDate)
|
|
}
|
|
|
|
func (s *statsService) Aggregate(stats []domain.UsageStats, groupBy string) []map[string]interface{} {
|
|
switch groupBy {
|
|
case "provider":
|
|
return s.aggregateByProvider(stats)
|
|
case "model":
|
|
return s.aggregateByModel(stats)
|
|
case "date":
|
|
return s.aggregateByDate(stats)
|
|
default:
|
|
return s.aggregateByProvider(stats)
|
|
}
|
|
}
|
|
|
|
func (s *statsService) aggregateByProvider(stats []domain.UsageStats) []map[string]interface{} {
|
|
aggregated := make(map[string]int)
|
|
for _, stat := range stats {
|
|
aggregated[stat.ProviderID] += stat.RequestCount
|
|
}
|
|
result := make([]map[string]interface{}, 0, len(aggregated))
|
|
for providerID, count := range aggregated {
|
|
result = append(result, map[string]interface{}{
|
|
"provider_id": providerID,
|
|
"request_count": count,
|
|
})
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (s *statsService) aggregateByModel(stats []domain.UsageStats) []map[string]interface{} {
|
|
aggregated := make(map[string]int)
|
|
for _, stat := range stats {
|
|
key := stat.ProviderID + "/" + stat.ModelName
|
|
aggregated[key] += stat.RequestCount
|
|
}
|
|
result := make([]map[string]interface{}, 0, len(aggregated))
|
|
for key, count := range aggregated {
|
|
result = append(result, map[string]interface{}{
|
|
"provider_id": key[:len(key)/2],
|
|
"model_name": key[len(key)/2+1:],
|
|
"request_count": count,
|
|
})
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (s *statsService) aggregateByDate(stats []domain.UsageStats) []map[string]interface{} {
|
|
aggregated := make(map[string]int)
|
|
for _, stat := range stats {
|
|
key := stat.Date.Format("2006-01-02")
|
|
aggregated[key] += stat.RequestCount
|
|
}
|
|
result := make([]map[string]interface{}, 0, len(aggregated))
|
|
for date, count := range aggregated {
|
|
result = append(result, map[string]interface{}{
|
|
"date": date,
|
|
"request_count": count,
|
|
})
|
|
}
|
|
return result
|
|
}
|