1
0
Files
nex/backend/internal/service/stats_service_impl.go
lanyuanxiaoyao f18904af1e 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(已迁移至分层架构)
2026-04-16 00:47:20 +08:00

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
}