201 lines
6.7 KiB
Go
201 lines
6.7 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func (r *MySQLRepository) ResolveWalletGame(ctx context.Context, sysOrigin string, eventType string, eventID string) (string, string, string, error) {
|
|
if provider, gameID, fallback, ok := directGameMeta(eventType); ok {
|
|
gameName, err := r.lookupGameName(ctx, sysOrigin, provider, gameID)
|
|
if gameName == "" {
|
|
gameName = fallback
|
|
}
|
|
return provider, gameID, gameName, err
|
|
}
|
|
if provider, gameID, gameName, ok, err := r.resolveGameOpenByWalletEvent(ctx, sysOrigin, eventType, eventID); ok || err != nil {
|
|
return provider, gameID, gameName, err
|
|
}
|
|
if provider, gameID, gameName, ok, err := r.resolveBaishunByWalletEvent(ctx, sysOrigin, eventID); ok || err != nil {
|
|
return provider, gameID, gameName, err
|
|
}
|
|
|
|
provider, gameID, fallback := fallbackGameMeta(eventType)
|
|
gameName, err := r.lookupGameName(ctx, sysOrigin, provider, gameID)
|
|
if err != nil {
|
|
return provider, gameID, fallback, err
|
|
}
|
|
if gameName == "" {
|
|
gameName = fallback
|
|
}
|
|
return provider, gameID, gameName, nil
|
|
}
|
|
|
|
func (r *MySQLRepository) resolveBaishunByWalletEvent(ctx context.Context, sysOrigin string, eventID string) (string, string, string, bool, error) {
|
|
if strings.TrimSpace(eventID) == "" {
|
|
return "", "", "", false, nil
|
|
}
|
|
var vendorID int64
|
|
err := r.db.QueryRowContext(ctx, `
|
|
SELECT vendor_game_id
|
|
FROM baishun_order_idempotency
|
|
WHERE sys_origin = ? AND wallet_event_id = ?
|
|
LIMIT 1
|
|
`, sysOrigin, eventID).Scan(&vendorID)
|
|
if err == sql.ErrNoRows {
|
|
return "", "", "", false, nil
|
|
}
|
|
if err != nil {
|
|
return "", "", "", false, err
|
|
}
|
|
gameID := strconv.FormatInt(vendorID, 10)
|
|
gameName, err := r.lookupGameName(ctx, sysOrigin, "BAISHUN", gameID)
|
|
if gameName == "" {
|
|
gameName = gameID
|
|
}
|
|
return "BAISHUN", gameID, gameName, true, err
|
|
}
|
|
|
|
func (r *MySQLRepository) resolveGameOpenByWalletEvent(ctx context.Context, sysOrigin string, eventType string, eventID string) (string, string, string, bool, error) {
|
|
orderID := strings.TrimPrefix(eventID, "GAME_OPEN:")
|
|
if orderID == eventID && !strings.HasPrefix(eventType, "GAME_OPEN_") {
|
|
return "", "", "", false, nil
|
|
}
|
|
if orderID != "" && orderID != eventID {
|
|
var gameID string
|
|
err := r.db.QueryRowContext(ctx, `
|
|
SELECT game_id
|
|
FROM game_open_callback_log
|
|
WHERE sys_origin = ? AND order_id = ?
|
|
LIMIT 1
|
|
`, sysOrigin, orderID).Scan(&gameID)
|
|
if err != nil && err != sql.ErrNoRows {
|
|
return "", "", "", false, err
|
|
}
|
|
if err == nil && strings.TrimSpace(gameID) != "" {
|
|
gameName, err := r.lookupGameName(ctx, sysOrigin, "GAME_OPEN", gameID)
|
|
if gameName == "" {
|
|
gameName = gameID
|
|
}
|
|
return "GAME_OPEN", gameID, gameName, true, err
|
|
}
|
|
}
|
|
if strings.HasPrefix(eventType, "GAME_OPEN_") {
|
|
gameID := strings.TrimPrefix(eventType, "GAME_OPEN_")
|
|
gameName, err := r.lookupGameName(ctx, sysOrigin, "GAME_OPEN", gameID)
|
|
if gameName == "" {
|
|
gameName = gameID
|
|
}
|
|
return "GAME_OPEN", gameID, gameName, true, err
|
|
}
|
|
return "", "", "", false, nil
|
|
}
|
|
|
|
func (r *MySQLRepository) lookupGameName(ctx context.Context, sysOrigin string, provider string, gameID string) (string, error) {
|
|
cacheKey := strings.Join([]string{sysOrigin, provider, gameID}, "|")
|
|
if name, ok := r.gameNameCache.Get(cacheKey); ok {
|
|
return name, nil
|
|
}
|
|
var name string
|
|
if provider == "BAISHUN" {
|
|
err := r.db.QueryRowContext(ctx, `
|
|
SELECT name
|
|
FROM baishun_game_catalog
|
|
WHERE sys_origin = ? AND profile = 'PROD' AND vendor_game_id = ?
|
|
LIMIT 1
|
|
`, sysOrigin, gameID).Scan(&name)
|
|
if err == nil || err != sql.ErrNoRows {
|
|
if err == nil {
|
|
r.gameNameCache.Set(cacheKey, name)
|
|
}
|
|
return name, err
|
|
}
|
|
}
|
|
err := r.db.QueryRowContext(ctx, `
|
|
SELECT name
|
|
FROM lingxian_game_catalog
|
|
WHERE sys_origin = ? AND profile = 'PROD' AND vendor_game_id = ?
|
|
LIMIT 1
|
|
`, sysOrigin, gameID).Scan(&name)
|
|
if err == nil || err != sql.ErrNoRows {
|
|
if err == nil {
|
|
r.gameNameCache.Set(cacheKey, name)
|
|
}
|
|
return name, err
|
|
}
|
|
err = r.db.QueryRowContext(ctx, `
|
|
SELECT name
|
|
FROM sys_game_list_config
|
|
WHERE sys_origin = ? AND game_id = ?
|
|
LIMIT 1
|
|
`, sysOrigin, gameID).Scan(&name)
|
|
if err == sql.ErrNoRows {
|
|
r.gameNameCache.Set(cacheKey, "")
|
|
return "", nil
|
|
}
|
|
if err == nil {
|
|
r.gameNameCache.Set(cacheKey, name)
|
|
}
|
|
return name, err
|
|
}
|
|
|
|
func directGameMeta(eventType string) (string, string, string, bool) {
|
|
switch {
|
|
case strings.HasPrefix(eventType, "BAISHUN_GAME_"),
|
|
strings.HasPrefix(eventType, "GAME_OPEN_"),
|
|
strings.HasPrefix(eventType, "YOMI_GAME_"),
|
|
strings.HasPrefix(eventType, "HKYS_GAME_"),
|
|
strings.HasPrefix(eventType, "HOT_GAME_"),
|
|
in(eventType, "FRUIT_GAME", "DOUBLE_LAYER_FRUIT", "GAME_FRUIT_BET", "GAME_FRUIT_AWARD",
|
|
"LUDO_GAME", "LUDO_VICTORY", "LUDO_REFUND", "GAME_LUDO_REFUND",
|
|
"GAME_BARBECUE", "DOUBLE_LAYER_BARBECUE", "GAME_SLOT_MACHINE", "TURNTABLE_GAME",
|
|
"GAME_BURST_CRYSTAL", "TEEN_PATTI", "BET_TEEN_PATTI", "LOTTERY_NUMBER_BET", "LOTTERY_REWARD"):
|
|
provider, gameID, fallback := fallbackGameMeta(eventType)
|
|
return provider, gameID, fallback, true
|
|
default:
|
|
return "", "", "", false
|
|
}
|
|
}
|
|
|
|
func fallbackGameMeta(eventType string) (string, string, string) {
|
|
switch {
|
|
case strings.HasPrefix(eventType, "BAISHUN_GAME_"):
|
|
return "BAISHUN", strings.TrimPrefix(eventType, "BAISHUN_GAME_"), strings.TrimPrefix(eventType, "BAISHUN_GAME_")
|
|
case strings.HasPrefix(eventType, "YOMI_GAME_"):
|
|
return "YOMI", strings.TrimPrefix(eventType, "YOMI_GAME_"), strings.TrimPrefix(eventType, "YOMI_GAME_")
|
|
case strings.HasPrefix(eventType, "HKYS_GAME_"):
|
|
return "HKYS", strings.TrimPrefix(eventType, "HKYS_GAME_"), strings.TrimPrefix(eventType, "HKYS_GAME_")
|
|
case strings.HasPrefix(eventType, "HOT_GAME_"):
|
|
return "HOT", strings.TrimPrefix(eventType, "HOT_GAME_"), strings.TrimPrefix(eventType, "HOT_GAME_")
|
|
case in(eventType, "FRUIT_GAME", "DOUBLE_LAYER_FRUIT", "GAME_FRUIT_BET", "GAME_FRUIT_AWARD"):
|
|
return "INTERNAL", "FRUIT_GAME", "Fruit Game"
|
|
case in(eventType, "LUDO_GAME", "LUDO_VICTORY", "LUDO_REFUND", "GAME_LUDO_REFUND"):
|
|
return "INTERNAL", "LUDO_GAME", "Ludo Game"
|
|
case in(eventType, "GAME_BARBECUE", "DOUBLE_LAYER_BARBECUE"):
|
|
return "INTERNAL", "BARBECUE_GAME", "Barbecue Game"
|
|
case eventType == "GAME_SLOT_MACHINE":
|
|
return "INTERNAL", "SLOT_MACHINE", "Slot Machine"
|
|
case eventType == "TURNTABLE_GAME":
|
|
return "INTERNAL", "TURNTABLE_GAME", "Turntable Game"
|
|
case eventType == "GAME_BURST_CRYSTAL":
|
|
return "INTERNAL", "BURST_CRYSTAL", "Burst Crystal"
|
|
case in(eventType, "TEEN_PATTI", "BET_TEEN_PATTI"):
|
|
return "INTERNAL", "TEEN_PATTI", "Teen Patti"
|
|
case in(eventType, "LOTTERY_NUMBER_BET", "LOTTERY_REWARD"):
|
|
return "INTERNAL", "LOTTERY_NUMBER", "Lottery Number"
|
|
default:
|
|
return "INTERNAL", eventType, eventType
|
|
}
|
|
}
|
|
|
|
func in(value string, candidates ...string) bool {
|
|
for _, candidate := range candidates {
|
|
if value == candidate {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|