package highwin import ( "context" "fmt" "math" "strconv" "strings" "chatapp3-golang/internal/service/regionimgroup" ) const ( ThresholdMultiple = 10 MessageTypeLuckyGift = "GAME_LUCKY_GIFT" MessageTypeBaishunWin = "GAME_BAISHUN_WIN" ) type RegionBroadcaster interface { SendRegionBroadcast(ctx context.Context, req regionimgroup.RegionBroadcastRequest) (*regionimgroup.RegionBroadcastResponse, error) } type BroadcastEvent struct { SysOrigin string RegionCode string Type string UserID int64 RoomID string Multiple float64 Amount int64 Data map[string]any } func IntegralMultiple(amount, base int64) int64 { if amount <= 0 || base <= 0 { return 0 } return amount / base } func Multiple(amount, base int64) float64 { if amount <= 0 || base <= 0 { return 0 } return float64(amount) / float64(base) } func ShouldBroadcast(multiple float64, amount int64) bool { return amount > 0 && multiple >= ThresholdMultiple } func SendRegionBroadcast(ctx context.Context, broadcaster RegionBroadcaster, event BroadcastEvent) error { if broadcaster == nil || !ShouldBroadcast(event.Multiple, event.Amount) { return nil } messageType := strings.TrimSpace(event.Type) if messageType == "" { return fmt.Errorf("high win broadcast type is required") } if event.UserID <= 0 { return fmt.Errorf("high win broadcast user id is required") } roomID := strings.TrimSpace(event.RoomID) if roomID == "" { return fmt.Errorf("high win broadcast room id is required") } data := cloneData(event.Data) userIDText := strconv.FormatInt(event.UserID, 10) setRequired(data, "userId", userIDText) setRequired(data, "sendUserId", userIDText) setRequired(data, "senderUserId", userIDText) setRequired(data, "roomId", roomID) setRequired(data, "multiple", normalizeMultiple(event.Multiple)) setRequired(data, "winMultiple", normalizeMultiple(event.Multiple)) setRequired(data, "winAmount", event.Amount) setRequired(data, "awardAmount", event.Amount) setRequired(data, "msg", highWinMessage(data, messageType, userIDText, event.Multiple, event.Amount)) _, err := broadcaster.SendRegionBroadcast(ctx, regionimgroup.RegionBroadcastRequest{ SysOrigin: strings.TrimSpace(event.SysOrigin), RegionCode: strings.TrimSpace(event.RegionCode), Type: messageType, Data: data, }) return err } func cloneData(data map[string]any) map[string]any { clone := map[string]any{} for key, value := range data { clone[key] = value } return clone } func setRequired(data map[string]any, key string, value any) { data[key] = value } func normalizeMultiple(value float64) any { if value <= 0 { return 0 } if math.Trunc(value) == value { return int64(value) } return math.Round(value*100) / 100 } func highWinMessage(data map[string]any, messageType, fallbackUser string, multiple float64, amount int64) string { user := firstTextValue(data, "userNickname", "nickname", "account", "actualAccount", "sendUserId", "senderUserId", "userId") if user == "" { user = fallbackUser } return fmt.Sprintf("%s play %s get x %s win %d coins!!!", user, highWinPlayTarget(messageType), formatMultipleText(multiple), amount) } func highWinPlayTarget(messageType string) string { switch strings.TrimSpace(messageType) { case MessageTypeLuckyGift: return "lucky_gift" case MessageTypeBaishunWin: return "game" default: return "game" } } func firstTextValue(data map[string]any, keys ...string) string { for _, key := range keys { if value := strings.TrimSpace(fmt.Sprint(data[key])); value != "" && value != "" { return value } } return "" } func formatMultipleText(value float64) string { normalized := normalizeMultiple(value) switch typed := normalized.(type) { case int64: return strconv.FormatInt(typed, 10) case float64: return strconv.FormatFloat(typed, 'f', -1, 64) default: return strings.TrimSpace(fmt.Sprint(typed)) } }