172 lines
5.1 KiB
Go
172 lines
5.1 KiB
Go
package gamemanagement
|
||
|
||
import (
|
||
"strconv"
|
||
"strings"
|
||
|
||
"hyapp-admin-server/internal/integration/gameclient"
|
||
"hyapp-admin-server/internal/modules/shared"
|
||
"hyapp-admin-server/internal/response"
|
||
gamev1 "hyapp.local/api/proto/game/v1"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
type Handler struct {
|
||
game gameclient.Client
|
||
audit shared.OperationLogger
|
||
}
|
||
|
||
func New(game gameclient.Client, audit shared.OperationLogger) *Handler {
|
||
return &Handler{game: game, audit: audit}
|
||
}
|
||
|
||
// ListPlatforms 返回后台游戏平台筛选项和平台配置列表。
|
||
func (h *Handler) ListPlatforms(c *gin.Context) {
|
||
resp, err := h.game.ListPlatforms(c.Request.Context(), &gamev1.ListPlatformsRequest{
|
||
Meta: requestMeta(c),
|
||
Status: strings.TrimSpace(c.Query("status")),
|
||
})
|
||
if err != nil {
|
||
response.ServerError(c, "获取游戏平台失败")
|
||
return
|
||
}
|
||
items := make([]platformDTO, 0, len(resp.GetPlatforms()))
|
||
for _, item := range resp.GetPlatforms() {
|
||
items = append(items, platformFromProto(item))
|
||
}
|
||
response.OK(c, gin.H{"items": items, "serverTimeMs": resp.GetServerTimeMs()})
|
||
}
|
||
|
||
func (h *Handler) CreatePlatform(c *gin.Context) {
|
||
h.upsertPlatform(c, "")
|
||
}
|
||
|
||
func (h *Handler) UpdatePlatform(c *gin.Context) {
|
||
h.upsertPlatform(c, strings.TrimSpace(c.Param("platform_code")))
|
||
}
|
||
|
||
// upsertPlatform 创建或更新第三方游戏平台配置;callbackSecret 非空时才会轮换厂商密钥。
|
||
func (h *Handler) upsertPlatform(c *gin.Context, platformCode string) {
|
||
var req platformRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, "游戏平台参数不正确")
|
||
return
|
||
}
|
||
resp, err := h.game.UpsertPlatform(c.Request.Context(), &gamev1.UpsertPlatformRequest{
|
||
Meta: requestMeta(c),
|
||
Platform: req.toProto(platformCode),
|
||
})
|
||
if err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
item := platformFromProto(resp.GetPlatform())
|
||
h.auditLog(c, "upsert-game-platform", "game_platforms", item.PlatformCode, item.PlatformName)
|
||
response.OK(c, item)
|
||
}
|
||
|
||
// ListCatalog 返回游戏目录;当前 game-service 使用 cursor 扩展点,后台先按 pageSize 截断。
|
||
func (h *Handler) ListCatalog(c *gin.Context) {
|
||
pageSize := int32(parsePositiveInt(firstQuery(c, "pageSize", "page_size"), 50))
|
||
resp, err := h.game.ListCatalog(c.Request.Context(), &gamev1.ListCatalogRequest{
|
||
Meta: requestMeta(c),
|
||
PlatformCode: strings.TrimSpace(firstQuery(c, "platformCode", "platform_code")),
|
||
Status: strings.TrimSpace(c.Query("status")),
|
||
PageSize: pageSize,
|
||
Cursor: strings.TrimSpace(c.Query("cursor")),
|
||
})
|
||
if err != nil {
|
||
response.ServerError(c, "获取游戏列表失败")
|
||
return
|
||
}
|
||
items := make([]catalogDTO, 0, len(resp.GetGames()))
|
||
for _, item := range resp.GetGames() {
|
||
items = append(items, catalogFromProto(item))
|
||
}
|
||
response.OK(c, gin.H{
|
||
"items": items,
|
||
"nextCursor": resp.GetNextCursor(),
|
||
"pageSize": pageSize,
|
||
"serverTimeMs": resp.GetServerTimeMs(),
|
||
})
|
||
}
|
||
|
||
func (h *Handler) CreateCatalog(c *gin.Context) {
|
||
h.upsertCatalog(c, "")
|
||
}
|
||
|
||
func (h *Handler) UpdateCatalog(c *gin.Context) {
|
||
h.upsertCatalog(c, strings.TrimSpace(c.Param("game_id")))
|
||
}
|
||
|
||
// upsertCatalog 创建或更新内部 game_id 到 provider_game_id 的映射。
|
||
func (h *Handler) upsertCatalog(c *gin.Context, gameID string) {
|
||
var req catalogRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, "游戏参数不正确")
|
||
return
|
||
}
|
||
resp, err := h.game.UpsertCatalog(c.Request.Context(), &gamev1.UpsertCatalogRequest{
|
||
Meta: requestMeta(c),
|
||
Game: req.toProto(gameID),
|
||
})
|
||
if err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
item := catalogFromProto(resp.GetGame())
|
||
h.auditLog(c, "upsert-game-catalog", "game_catalog", item.GameID, item.GameName)
|
||
response.OK(c, item)
|
||
}
|
||
|
||
// SetGameStatus 只处理 active/maintenance/disabled 状态,不删除历史订单关联的游戏目录。
|
||
func (h *Handler) SetGameStatus(c *gin.Context) {
|
||
gameID := strings.TrimSpace(c.Param("game_id"))
|
||
if gameID == "" {
|
||
response.BadRequest(c, "游戏 ID 参数不正确")
|
||
return
|
||
}
|
||
var req statusRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, "状态参数不正确")
|
||
return
|
||
}
|
||
resp, err := h.game.SetGameStatus(c.Request.Context(), &gamev1.SetGameStatusRequest{
|
||
Meta: requestMeta(c),
|
||
GameId: gameID,
|
||
Status: strings.TrimSpace(req.Status),
|
||
})
|
||
if err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
item := catalogFromProto(resp.GetGame())
|
||
h.auditLog(c, "set-game-status", "game_catalog", item.GameID, item.Status)
|
||
response.OK(c, item)
|
||
}
|
||
|
||
func (h *Handler) auditLog(c *gin.Context, action string, resource string, resourceID string, detail string) {
|
||
shared.OperationLogWithResourceID(c, h.audit, action, resource, resourceID, "success", detail)
|
||
}
|
||
|
||
func parsePositiveInt(raw string, fallback int) int {
|
||
value, err := strconv.Atoi(strings.TrimSpace(raw))
|
||
if err != nil || value <= 0 {
|
||
return fallback
|
||
}
|
||
if value > 200 {
|
||
return 200
|
||
}
|
||
return value
|
||
}
|
||
|
||
func firstQuery(c *gin.Context, keys ...string) string {
|
||
for _, key := range keys {
|
||
if value := c.Query(key); value != "" {
|
||
return value
|
||
}
|
||
}
|
||
return ""
|
||
}
|