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 创建或更新第三方游戏平台配置;平台密钥后续走单独的密钥托管接口。
|
|
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 ""
|
|
}
|