feat: 实现分层架构,包含 domain、service、repository 和 pkg 层
- 新增 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(已迁移至分层架构)
This commit is contained in:
85
backend/internal/service/stats_service_impl.go
Normal file
85
backend/internal/service/stats_service_impl.go
Normal file
@@ -0,0 +1,85 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user