128 lines
4.3 KiB
Go
128 lines
4.3 KiB
Go
package http
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"hyapp/pkg/appcode"
|
|
"hyapp/services/gateway-service/internal/appconfig"
|
|
)
|
|
|
|
// appConfigReader 是 gateway 对后台 App 配置的只读依赖。
|
|
type appConfigReader interface {
|
|
ListH5Links(ctx context.Context) ([]appconfig.H5Link, error)
|
|
ListBanners(ctx context.Context, query appconfig.BannerQuery) ([]appconfig.Banner, error)
|
|
}
|
|
|
|
type appBootstrapBottomTab struct {
|
|
Key string `json:"key"`
|
|
Title string `json:"title"`
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
|
|
type appBootstrapResponse struct {
|
|
AppCode string `json:"app_code"`
|
|
ServerTimeMS int64 `json:"server_time_ms"`
|
|
ForceUpgrade bool `json:"force_upgrade"`
|
|
Maintenance bool `json:"maintenance"`
|
|
MinimumVersion string `json:"minimum_version"`
|
|
LatestVersion string `json:"latest_version"`
|
|
FeatureFlags map[string]bool `json:"feature_flags"`
|
|
BottomTabs []appBootstrapBottomTab `json:"bottom_tabs"`
|
|
ConfigVersions map[string]string `json:"config_versions"`
|
|
}
|
|
|
|
// getAppBootstrap 返回 App 启动状态机需要的轻量配置摘要。
|
|
// bootstrap 只下发版本、开关和配置版本号,不返回 banner、礼物或资源大列表。
|
|
func (h *Handler) getAppBootstrap(writer http.ResponseWriter, request *http.Request) {
|
|
writeOK(writer, request, appBootstrapResponse{
|
|
AppCode: appcode.FromContext(request.Context()),
|
|
ServerTimeMS: time.Now().UnixMilli(),
|
|
ForceUpgrade: false,
|
|
Maintenance: false,
|
|
MinimumVersion: "1.0.0",
|
|
LatestVersion: "1.0.0",
|
|
FeatureFlags: map[string]bool{
|
|
"wallet_recharge": true,
|
|
"wallet_withdraw": true,
|
|
"diamond_exchange": true,
|
|
"message_tab": true,
|
|
"host_center": true,
|
|
"room_create": true,
|
|
},
|
|
BottomTabs: []appBootstrapBottomTab{
|
|
{Key: "rooms", Title: "房间", Enabled: true},
|
|
{Key: "messages", Title: "消息", Enabled: true},
|
|
{Key: "me", Title: "我的", Enabled: true},
|
|
},
|
|
ConfigVersions: map[string]string{
|
|
"countries": "v1",
|
|
"banners": "v1",
|
|
"h5_links": "v1",
|
|
"resources": "v1",
|
|
"gifts": "v1",
|
|
},
|
|
})
|
|
}
|
|
|
|
// listH5Links 返回后台 APP配置/H5配置 中维护的 H5 入口地址。
|
|
func (h *Handler) listH5Links(writer http.ResponseWriter, request *http.Request) {
|
|
if h.appConfigReader == nil {
|
|
// H5 地址来自后台配置表;未注入 reader 时不能返回空假数据。
|
|
writeError(writer, request, http.StatusBadGateway, codeUpstreamError, "upstream service error")
|
|
return
|
|
}
|
|
|
|
items, err := h.appConfigReader.ListH5Links(request.Context())
|
|
if err != nil {
|
|
// 配置读取失败属于服务端依赖异常,客户端只需要根据 request_id 排查。
|
|
writeError(writer, request, http.StatusBadGateway, codeUpstreamError, "upstream service error")
|
|
return
|
|
}
|
|
|
|
writeOK(writer, request, map[string]any{"items": items, "total": len(items)})
|
|
}
|
|
|
|
// listAppBanners 返回后台 APP配置/BANNER配置 中维护的首页 banner。
|
|
func (h *Handler) listAppBanners(writer http.ResponseWriter, request *http.Request) {
|
|
if h.appConfigReader == nil {
|
|
writeError(writer, request, http.StatusBadGateway, codeUpstreamError, "upstream service error")
|
|
return
|
|
}
|
|
|
|
items, err := h.appConfigReader.ListBanners(request.Context(), appconfig.BannerQuery{
|
|
AppCode: appcode.FromContext(request.Context()),
|
|
Platform: firstQueryOrHeader(request, "platform", "X-App-Platform", "X-Platform"),
|
|
RegionID: optionalInt64Query(request, "region_id"),
|
|
Country: firstQueryOrHeader(request, "country", "X-Country-Code", "X-App-Country"),
|
|
})
|
|
if err != nil {
|
|
writeError(writer, request, http.StatusBadGateway, codeUpstreamError, "upstream service error")
|
|
return
|
|
}
|
|
|
|
writeOK(writer, request, map[string]any{"items": items, "total": len(items)})
|
|
}
|
|
|
|
func firstQueryOrHeader(request *http.Request, queryKey string, headerNames ...string) string {
|
|
if value := strings.TrimSpace(request.URL.Query().Get(queryKey)); value != "" {
|
|
return value
|
|
}
|
|
return firstHeader(request, headerNames...)
|
|
}
|
|
|
|
func optionalInt64Query(request *http.Request, key string) int64 {
|
|
value := strings.TrimSpace(request.URL.Query().Get(key))
|
|
if value == "" {
|
|
return 0
|
|
}
|
|
parsed, err := strconv.ParseInt(value, 10, 64)
|
|
if err != nil || parsed < 0 {
|
|
return 0
|
|
}
|
|
return parsed
|
|
}
|