2026-06-08 00:55:30 +08:00

93 lines
2.3 KiB
Go

package app
import (
"context"
"encoding/json"
"errors"
"net"
"net/http"
"strconv"
"strings"
"time"
mysqlstorage "hyapp/services/statistics-service/internal/storage/mysql"
)
type queryHTTPServer struct {
repo *mysqlstorage.Repository
server *http.Server
listener net.Listener
}
func newQueryHTTPServer(addr string, repo *mysqlstorage.Repository) (*queryHTTPServer, error) {
addr = strings.TrimSpace(addr)
if addr == "" {
return nil, nil
}
listener, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}
s := &queryHTTPServer{repo: repo, listener: listener}
mux := http.NewServeMux()
mux.HandleFunc("/internal/v1/statistics/overview", s.overview)
s.server = &http.Server{Handler: mux, ReadHeaderTimeout: 2 * time.Second}
return s, nil
}
func (s *queryHTTPServer) Run() error {
if s == nil {
return nil
}
err := s.server.Serve(s.listener)
if errors.Is(err, http.ErrServerClosed) {
return nil
}
return err
}
func (s *queryHTTPServer) Close(ctx context.Context) error {
if s == nil {
return nil
}
return s.server.Shutdown(ctx)
}
func (s *queryHTTPServer) overview(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
startMS := parseInt64(query.Get("start_ms"))
endMS := parseInt64(query.Get("end_ms"))
if startMS <= 0 {
now := time.Now().UTC()
startMS = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC).UnixMilli()
}
if endMS <= startMS {
endMS = startMS + 24*time.Hour.Milliseconds()
}
overview, err := s.repo.QueryOverview(r.Context(), mysqlstorage.OverviewQuery{
AppCode: query.Get("app_code"),
StartMS: startMS,
EndMS: endMS,
SeriesStartMS: parseInt64(query.Get("series_start_ms")),
SeriesEndMS: parseInt64(query.Get("series_end_ms")),
CountryID: parseInt64(query.Get("country_id")),
RegionID: parseInt64(query.Get("region_id")),
})
if err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()})
return
}
writeJSON(w, http.StatusOK, overview)
}
func parseInt64(value string) int64 {
parsed, _ := strconv.ParseInt(strings.TrimSpace(value), 10, 64)
return parsed
}
func writeJSON(w http.ResponseWriter, status int, payload any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
_ = json.NewEncoder(w).Encode(payload)
}