2026-06-16 14:54:57 +08:00

450 lines
17 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package gamemanagement
import (
"strconv"
"strings"
gamev1 "hyapp.local/api/proto/game/v1"
)
type platformDTO struct {
AppCode string `json:"appCode"`
PlatformCode string `json:"platformCode"`
PlatformName string `json:"platformName"`
Status string `json:"status"`
APIBaseURL string `json:"apiBaseUrl"`
// adapterType 决定服务端按哪家厂商协议拼启动 URL 和处理回调。
AdapterType string `json:"adapterType"`
// callbackSecret 是后台配置页可见的厂商 key/AppSecret只对有 game:view 权限的管理员返回。
CallbackSecret string `json:"callbackSecret"`
CallbackSecretSet bool `json:"callbackSecretSet"`
CallbackIPWhitelist []string `json:"callbackIpWhitelist"`
// adapterConfigJson 承载 uid_mode/default_lang/token_ttl_seconds 等可热更新配置。
AdapterConfigJSON string `json:"adapterConfigJson"`
SortOrder int32 `json:"sortOrder"`
CreatedAtMS int64 `json:"createdAtMs"`
UpdatedAtMS int64 `json:"updatedAtMs"`
}
type catalogDTO struct {
AppCode string `json:"appCode"`
GameID string `json:"gameId"`
PlatformCode string `json:"platformCode"`
ProviderGameID string `json:"providerGameId"`
GameName string `json:"gameName"`
Category string `json:"category"`
IconURL string `json:"iconUrl"`
CoverURL string `json:"coverUrl"`
// launchUrl 只在厂商列表预览时返回,正式目录仍由 platform.adapterConfigJson.game_urls 按 providerGameId 解析。
LaunchURL string `json:"launchUrl,omitempty"`
LaunchMode string `json:"launchMode"`
Orientation string `json:"orientation"`
SafeHeight int32 `json:"safeHeight"`
MinCoin int64 `json:"minCoin"`
Status string `json:"status"`
SortOrder int32 `json:"sortOrder"`
Tags []string `json:"tags"`
CreatedAtMS int64 `json:"createdAtMs"`
UpdatedAtMS int64 `json:"updatedAtMs"`
}
type diceConfigDTO struct {
AppCode string `json:"appCode"`
GameID string `json:"gameId"`
Status string `json:"status"`
StakeOptions []diceStakeDTO `json:"stakeOptions"`
FeeBPS int32 `json:"feeBps"`
PoolBPS int32 `json:"poolBps"`
MinPlayers int32 `json:"minPlayers"`
MaxPlayers int32 `json:"maxPlayers"`
RobotEnabled bool `json:"robotEnabled"`
RobotMatchWaitMS int64 `json:"robotMatchWaitMs"`
PoolBalanceCoin int64 `json:"poolBalanceCoin"`
CreatedAtMS int64 `json:"createdAtMs"`
UpdatedAtMS int64 `json:"updatedAtMs"`
}
type diceStakeDTO struct {
StakeCoin int64 `json:"stakeCoin"`
Enabled bool `json:"enabled"`
SortOrder int32 `json:"sortOrder"`
}
type dicePoolAdjustmentDTO struct {
AdjustmentID string `json:"adjustmentId"`
GameID string `json:"gameId"`
StakeCoin int64 `json:"stakeCoin"`
AmountCoin int64 `json:"amountCoin"`
Direction string `json:"direction"`
Reason string `json:"reason"`
BalanceAfter int64 `json:"balanceAfter"`
CreatedAtMS int64 `json:"createdAtMs"`
}
type selfGameStakePoolDTO struct {
AppCode string `json:"appCode"`
GameID string `json:"gameId"`
StakeCoin int64 `json:"stakeCoin"`
BalanceCoin int64 `json:"balanceCoin"`
ReservedCoin int64 `json:"reservedCoin"`
AvailableCoin int64 `json:"availableCoin"`
TargetBalanceCoin int64 `json:"targetBalanceCoin"`
SafeBalanceCoin int64 `json:"safeBalanceCoin"`
WarningBalanceCoin int64 `json:"warningBalanceCoin"`
DangerBalanceCoin int64 `json:"dangerBalanceCoin"`
Status string `json:"status"`
PoolLevel string `json:"poolLevel"`
RequiredPoolCoin int64 `json:"requiredPoolCoin"`
HumanWinCapacity int64 `json:"humanWinCapacity"`
BotMatchEnabled bool `json:"botMatchEnabled"`
BlackReason string `json:"blackReason"`
CreatedAtMS int64 `json:"createdAtMs"`
UpdatedAtMS int64 `json:"updatedAtMs"`
}
type selfGameNewUserPolicyDTO struct {
AppCode string `json:"appCode"`
GameID string `json:"gameId"`
Enabled bool `json:"enabled"`
ProtectionRounds int32 `json:"protectionRounds"`
ProtectionHours int32 `json:"protectionHours"`
MaxStakeCoin int64 `json:"maxStakeCoin"`
LifetimeSubsidyQuotaCoin int64 `json:"lifetimeSubsidyQuotaCoin"`
Day1SubsidyQuotaCoin int64 `json:"day1SubsidyQuotaCoin"`
SingleRoundSubsidyCapCoin int64 `json:"singleRoundSubsidyCapCoin"`
StrategyLevel string `json:"strategyLevel"`
LoseStreakProtectionEnabled bool `json:"loseStreakProtectionEnabled"`
LoseStreakTrigger int32 `json:"loseStreakTrigger"`
NormalPhaseTargetWinRatePercent int32 `json:"normalPhaseTargetWinRatePercent"`
BlackPoolRobotForceWinEnabled bool `json:"blackPoolRobotForceWinEnabled"`
CreatedAtMS int64 `json:"createdAtMs"`
UpdatedAtMS int64 `json:"updatedAtMs"`
}
type diceRobotDTO struct {
AppCode string `json:"appCode"`
GameID string `json:"gameId"`
UserID string `json:"userId"`
UserIDNumber int64 `json:"userIdNumber"`
ShortID string `json:"shortId"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Status string `json:"status"`
CreatedByAdminID int64 `json:"createdByAdminId"`
CreatedAtMS int64 `json:"createdAtMs"`
UpdatedAtMS int64 `json:"updatedAtMs"`
}
type roomRPSConfigDTO struct {
AppCode string `json:"appCode"`
GameID string `json:"gameId"`
Status string `json:"status"`
ChallengeTimeoutMS int64 `json:"challengeTimeoutMs"`
RevealCountdownMS int64 `json:"revealCountdownMs"`
StakeGifts []roomRPSStakeGiftDTO `json:"stakeGifts"`
CreatedAtMS int64 `json:"createdAtMs"`
UpdatedAtMS int64 `json:"updatedAtMs"`
}
type roomRPSStakeGiftDTO struct {
GiftID string `json:"giftId"`
GiftIDNumber int64 `json:"giftIdNumber"`
GiftName string `json:"giftName"`
GiftIconURL string `json:"giftIconUrl"`
GiftAnimationURL string `json:"giftAnimationUrl"`
GiftPriceCoin int64 `json:"giftPriceCoin"`
Enabled bool `json:"enabled"`
SortOrder int32 `json:"sortOrder"`
}
type roomRPSChallengeDTO struct {
AppCode string `json:"appCode"`
ChallengeID string `json:"challengeId"`
RoomID string `json:"roomId"`
RegionID int64 `json:"regionId"`
Status string `json:"status"`
StakeGiftID string `json:"stakeGiftId"`
StakeGiftIDNumber int64 `json:"stakeGiftIdNumber"`
StakeCoin int64 `json:"stakeCoin"`
Initiator roomRPSPlayerDTO `json:"initiator"`
Challenger roomRPSPlayerDTO `json:"challenger"`
WinnerUserID string `json:"winnerUserId"`
WinnerUserIDNumber int64 `json:"winnerUserIdNumber"`
SettlementStatus string `json:"settlementStatus"`
FailureReason string `json:"failureReason"`
TimeoutAtMS int64 `json:"timeoutAtMs"`
RevealAtMS int64 `json:"revealAtMs"`
CreatedAtMS int64 `json:"createdAtMs"`
MatchedAtMS int64 `json:"matchedAtMs"`
SettledAtMS int64 `json:"settledAtMs"`
UpdatedAtMS int64 `json:"updatedAtMs"`
}
type roomRPSPlayerDTO struct {
UserID string `json:"userId"`
UserIDNumber int64 `json:"userIdNumber"`
Gesture string `json:"gesture"`
Result string `json:"result"`
BalanceAfter int64 `json:"balanceAfter"`
JoinedAtMS int64 `json:"joinedAtMs"`
}
func platformFromProto(item *gamev1.GamePlatform) platformDTO {
if item == nil {
return platformDTO{}
}
return platformDTO{
AppCode: item.GetAppCode(),
PlatformCode: item.GetPlatformCode(),
PlatformName: item.GetPlatformName(),
Status: item.GetStatus(),
APIBaseURL: item.GetApiBaseUrl(),
AdapterType: item.GetAdapterType(),
CallbackSecret: item.GetCallbackSecret(),
CallbackSecretSet: item.GetCallbackSecretSet(),
CallbackIPWhitelist: item.GetCallbackIpWhitelist(),
AdapterConfigJSON: item.GetAdapterConfigJson(),
SortOrder: item.GetSortOrder(),
CreatedAtMS: item.GetCreatedAtMs(),
UpdatedAtMS: item.GetUpdatedAtMs(),
}
}
func catalogFromProto(item *gamev1.GameCatalogItem) catalogDTO {
if item == nil {
return catalogDTO{}
}
return catalogDTO{
AppCode: item.GetAppCode(),
GameID: item.GetGameId(),
PlatformCode: item.GetPlatformCode(),
ProviderGameID: item.GetProviderGameId(),
GameName: item.GetGameName(),
Category: item.GetCategory(),
IconURL: item.GetIconUrl(),
CoverURL: item.GetCoverUrl(),
LaunchMode: item.GetLaunchMode(),
Orientation: item.GetOrientation(),
SafeHeight: item.GetSafeHeight(),
MinCoin: item.GetMinCoin(),
Status: item.GetStatus(),
SortOrder: item.GetSortOrder(),
Tags: item.GetTags(),
CreatedAtMS: item.GetCreatedAtMs(),
UpdatedAtMS: item.GetUpdatedAtMs(),
}
}
func diceConfigFromProto(item *gamev1.DiceConfig) diceConfigDTO {
if item == nil {
return diceConfigDTO{}
}
options := make([]diceStakeDTO, 0, len(item.GetStakeOptions()))
for _, option := range item.GetStakeOptions() {
options = append(options, diceStakeDTO{
StakeCoin: option.GetStakeCoin(),
Enabled: option.GetEnabled(),
SortOrder: option.GetSortOrder(),
})
}
return diceConfigDTO{
AppCode: item.GetAppCode(),
GameID: item.GetGameId(),
Status: item.GetStatus(),
StakeOptions: options,
FeeBPS: item.GetFeeBps(),
PoolBPS: item.GetPoolBps(),
MinPlayers: item.GetMinPlayers(),
MaxPlayers: item.GetMaxPlayers(),
RobotEnabled: item.GetRobotEnabled(),
RobotMatchWaitMS: item.GetRobotMatchWaitMs(),
PoolBalanceCoin: item.GetPoolBalanceCoin(),
CreatedAtMS: item.GetCreatedAtMs(),
UpdatedAtMS: item.GetUpdatedAtMs(),
}
}
func dicePoolAdjustmentFromProto(item *gamev1.DicePoolAdjustment) dicePoolAdjustmentDTO {
if item == nil {
return dicePoolAdjustmentDTO{}
}
return dicePoolAdjustmentDTO{
AdjustmentID: item.GetAdjustmentId(),
GameID: item.GetGameId(),
StakeCoin: item.GetStakeCoin(),
AmountCoin: item.GetAmountCoin(),
Direction: item.GetDirection(),
Reason: item.GetReason(),
BalanceAfter: item.GetBalanceAfter(),
CreatedAtMS: item.GetCreatedAtMs(),
}
}
func selfGameStakePoolFromProto(item *gamev1.SelfGameStakePool) selfGameStakePoolDTO {
if item == nil {
return selfGameStakePoolDTO{}
}
return selfGameStakePoolDTO{
AppCode: item.GetAppCode(),
GameID: item.GetGameId(),
StakeCoin: item.GetStakeCoin(),
BalanceCoin: item.GetBalanceCoin(),
ReservedCoin: item.GetReservedCoin(),
AvailableCoin: item.GetAvailableCoin(),
TargetBalanceCoin: item.GetTargetBalanceCoin(),
SafeBalanceCoin: item.GetSafeBalanceCoin(),
WarningBalanceCoin: item.GetWarningBalanceCoin(),
DangerBalanceCoin: item.GetDangerBalanceCoin(),
Status: item.GetStatus(),
PoolLevel: item.GetPoolLevel(),
RequiredPoolCoin: item.GetRequiredPoolCoin(),
HumanWinCapacity: item.GetHumanWinCapacity(),
BotMatchEnabled: item.GetBotMatchEnabled(),
BlackReason: item.GetBlackReason(),
CreatedAtMS: item.GetCreatedAtMs(),
UpdatedAtMS: item.GetUpdatedAtMs(),
}
}
func selfGameNewUserPolicyFromProto(item *gamev1.SelfGameNewUserPolicy) selfGameNewUserPolicyDTO {
if item == nil {
return selfGameNewUserPolicyDTO{}
}
return selfGameNewUserPolicyDTO{
AppCode: item.GetAppCode(),
GameID: item.GetGameId(),
Enabled: item.GetEnabled(),
ProtectionRounds: item.GetProtectionRounds(),
ProtectionHours: item.GetProtectionHours(),
MaxStakeCoin: item.GetMaxStakeCoin(),
LifetimeSubsidyQuotaCoin: item.GetLifetimeSubsidyQuotaCoin(),
Day1SubsidyQuotaCoin: item.GetDay1SubsidyQuotaCoin(),
SingleRoundSubsidyCapCoin: item.GetSingleRoundSubsidyCapCoin(),
StrategyLevel: item.GetStrategyLevel(),
LoseStreakProtectionEnabled: item.GetLoseStreakProtectionEnabled(),
LoseStreakTrigger: item.GetLoseStreakTrigger(),
NormalPhaseTargetWinRatePercent: item.GetNormalPhaseTargetWinRatePercent(),
BlackPoolRobotForceWinEnabled: item.GetBlackPoolRobotForceWinEnabled(),
CreatedAtMS: item.GetCreatedAtMs(),
UpdatedAtMS: item.GetUpdatedAtMs(),
}
}
func diceRobotFromProto(item *gamev1.DiceRobot) diceRobotDTO {
if item == nil {
return diceRobotDTO{}
}
return diceRobotDTO{
AppCode: item.GetAppCode(),
GameID: item.GetGameId(),
UserID: strconv.FormatInt(item.GetUserId(), 10),
UserIDNumber: item.GetUserId(),
Status: item.GetStatus(),
CreatedByAdminID: item.GetCreatedByAdminId(),
CreatedAtMS: item.GetCreatedAtMs(),
UpdatedAtMS: item.GetUpdatedAtMs(),
}
}
func roomRPSConfigFromProto(item *gamev1.RoomRPSConfig) roomRPSConfigDTO {
if item == nil {
return roomRPSConfigDTO{}
}
gifts := make([]roomRPSStakeGiftDTO, 0, len(item.GetStakeGifts()))
for _, gift := range item.GetStakeGifts() {
// 礼物详情由 game-service 结合礼物配置补齐admin-server 只保持展示字段和 ID 双写,不重新查礼物表。
gifts = append(gifts, roomRPSStakeGiftDTO{
GiftID: roomRPSStakeGiftIDFromProto(gift),
GiftIDNumber: gift.GetGiftId(),
GiftName: gift.GetGiftName(),
GiftIconURL: gift.GetGiftIconUrl(),
GiftAnimationURL: gift.GetGiftAnimationUrl(),
GiftPriceCoin: gift.GetGiftPriceCoin(),
Enabled: gift.GetEnabled(),
SortOrder: gift.GetSortOrder(),
})
}
// DTO 只做 proto 到后台 JSON 的字段命名转换;配置默认值和合法性已经在 game-service/admin request 层处理。
return roomRPSConfigDTO{
AppCode: item.GetAppCode(),
GameID: item.GetGameId(),
Status: item.GetStatus(),
ChallengeTimeoutMS: item.GetChallengeTimeoutMs(),
RevealCountdownMS: item.GetRevealCountdownMs(),
StakeGifts: gifts,
CreatedAtMS: item.GetCreatedAtMs(),
UpdatedAtMS: item.GetUpdatedAtMs(),
}
}
func roomRPSChallengeFromProto(item *gamev1.RoomRPSChallenge) roomRPSChallengeDTO {
if item == nil {
return roomRPSChallengeDTO{}
}
// 后台订单页要同时服务浏览器展示和问题排查ID 用字符串保护前端精度,也保留 number 字段便于排序、复制和接口调试。
// 胜负、结算状态、失败原因全部按 game-service 返回值展示admin-server 不根据手势重新计算,避免和真实结算事实分叉。
return roomRPSChallengeDTO{
AppCode: item.GetAppCode(),
ChallengeID: item.GetChallengeId(),
RoomID: item.GetRoomId(),
RegionID: item.GetRegionId(),
Status: item.GetStatus(),
StakeGiftID: roomRPSChallengeStakeGiftIDFromProto(item),
StakeGiftIDNumber: item.GetStakeGiftId(),
StakeCoin: item.GetStakeCoin(),
Initiator: roomRPSPlayerFromProto(item.GetInitiator()),
Challenger: roomRPSPlayerFromProto(item.GetChallenger()),
WinnerUserID: strconv.FormatInt(item.GetWinnerUserId(), 10),
WinnerUserIDNumber: item.GetWinnerUserId(),
SettlementStatus: item.GetSettlementStatus(),
FailureReason: item.GetFailureReason(),
TimeoutAtMS: item.GetTimeoutAtMs(),
RevealAtMS: item.GetRevealAtMs(),
CreatedAtMS: item.GetCreatedAtMs(),
MatchedAtMS: item.GetMatchedAtMs(),
SettledAtMS: item.GetSettledAtMs(),
UpdatedAtMS: item.GetUpdatedAtMs(),
}
}
func roomRPSStakeGiftIDFromProto(gift *gamev1.RoomRPSStakeGift) string {
if gift == nil {
return ""
}
if text := strings.TrimSpace(gift.GetGiftIdText()); text != "" {
return text
}
if gift.GetGiftId() > 0 {
return strconv.FormatInt(gift.GetGiftId(), 10)
}
return ""
}
func roomRPSChallengeStakeGiftIDFromProto(item *gamev1.RoomRPSChallenge) string {
if item == nil {
return ""
}
if text := strings.TrimSpace(item.GetStakeGiftIdText()); text != "" {
return text
}
if item.GetStakeGiftId() > 0 {
return strconv.FormatInt(item.GetStakeGiftId(), 10)
}
return ""
}
func roomRPSPlayerFromProto(item *gamev1.RoomRPSPlayer) roomRPSPlayerDTO {
if item == nil {
return roomRPSPlayerDTO{}
}
// 管理后台玩家 DTO 只展示订单内快照字段;头像昵称属于 App/IM 展示增强,后台如需用户资料应走独立用户查询。
return roomRPSPlayerDTO{
UserID: strconv.FormatInt(item.GetUserId(), 10),
UserIDNumber: item.GetUserId(),
Gesture: item.GetGesture(),
Result: item.GetResult(),
BalanceAfter: item.GetBalanceAfter(),
JoinedAtMS: item.GetJoinedAtMs(),
}
}