2026-06-12 03:08:18 +08:00

119 lines
3.3 KiB
Go

package dashboard
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"hyapp-admin-server/internal/config"
"hyapp-admin-server/internal/repository"
)
type DashboardService struct {
store *repository.Store
cfg config.Config
httpClient *http.Client
}
type StatisticsQuery struct {
AppCode string
StartMS int64
EndMS int64
SeriesStartMS int64
SeriesEndMS int64
RegionID int64
CountryID int64
}
type SelfGameStatisticsQuery struct {
AppCode string
StartMS int64
EndMS int64
RegionID int64
CountryID int64
GameID string
}
func NewService(store *repository.Store, cfg config.Config) *DashboardService {
return &DashboardService{
store: store,
cfg: cfg,
httpClient: &http.Client{Timeout: cfg.StatisticsService.RequestTimeout},
}
}
func (s *DashboardService) Overview() (*repository.DashboardOverview, error) {
return s.store.DashboardOverview()
}
func (s *DashboardService) StatisticsOverview(ctx context.Context, query StatisticsQuery) (map[string]any, error) {
values := url.Values{}
values.Set("app_code", query.AppCode)
if query.StartMS > 0 {
values.Set("start_ms", strconv.FormatInt(query.StartMS, 10))
}
if query.EndMS > 0 {
values.Set("end_ms", strconv.FormatInt(query.EndMS, 10))
}
if query.SeriesStartMS > 0 {
values.Set("series_start_ms", strconv.FormatInt(query.SeriesStartMS, 10))
}
if query.SeriesEndMS > 0 {
values.Set("series_end_ms", strconv.FormatInt(query.SeriesEndMS, 10))
}
if query.RegionID > 0 {
values.Set("region_id", strconv.FormatInt(query.RegionID, 10))
}
if query.CountryID > 0 {
values.Set("country_id", strconv.FormatInt(query.CountryID, 10))
}
return s.statisticsGET(ctx, "/internal/v1/statistics/overview", values)
}
func (s *DashboardService) SelfGameStatisticsOverview(ctx context.Context, query SelfGameStatisticsQuery) (map[string]any, error) {
values := url.Values{}
values.Set("app_code", query.AppCode)
if query.StartMS > 0 {
values.Set("start_ms", strconv.FormatInt(query.StartMS, 10))
}
if query.EndMS > 0 {
values.Set("end_ms", strconv.FormatInt(query.EndMS, 10))
}
if query.RegionID > 0 {
values.Set("region_id", strconv.FormatInt(query.RegionID, 10))
}
if query.CountryID > 0 {
values.Set("country_id", strconv.FormatInt(query.CountryID, 10))
}
if gameID := strings.TrimSpace(query.GameID); gameID != "" && gameID != "all" {
values.Set("game_id", gameID)
}
// 数据大屏只通过 statistics-service 读取自研游戏聚合指标,避免 admin 服务绕过聚合层去扫业务明细表。
return s.statisticsGET(ctx, "/internal/v1/statistics/self-games/overview", values)
}
func (s *DashboardService) statisticsGET(ctx context.Context, path string, values url.Values) (map[string]any, error) {
baseURL := s.cfg.StatisticsService.BaseURL + path
req, err := http.NewRequestWithContext(ctx, http.MethodGet, baseURL+"?"+values.Encode(), nil)
if err != nil {
return nil, err
}
resp, err := s.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("statistics service returned status %d", resp.StatusCode)
}
var out map[string]any
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return nil, err
}
return out, nil
}