模拟飘屏
This commit is contained in:
parent
adcc722284
commit
4cf4eba5ff
@ -4,6 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"chatapp3-golang/internal/config"
|
"chatapp3-golang/internal/config"
|
||||||
|
"chatapp3-golang/internal/service/highwin"
|
||||||
"chatapp3-golang/internal/service/regionimgroup"
|
"chatapp3-golang/internal/service/regionimgroup"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -65,6 +66,7 @@ func registerRegionIMGroupInternalRoutes(engine *gin.Engine, cfg config.Config,
|
|||||||
func registerRegionIMGroupAdminRoutes(engine *gin.Engine, javaClient authGateway, service *regionimgroup.Service) {
|
func registerRegionIMGroupAdminRoutes(engine *gin.Engine, javaClient authGateway, service *regionimgroup.Service) {
|
||||||
registerRegionIMGroupAdminGroup(engine.Group("/region/config"), javaClient, service)
|
registerRegionIMGroupAdminGroup(engine.Group("/region/config"), javaClient, service)
|
||||||
registerRegionIMGroupAdminGroup(engine.Group("/resident-activity/voice-room-red-packet"), javaClient, service)
|
registerRegionIMGroupAdminGroup(engine.Group("/resident-activity/voice-room-red-packet"), javaClient, service)
|
||||||
|
registerRegionBroadcastSimulationAdminGroup(engine.Group("/operate/region-broadcast"), javaClient, service)
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerRegionIMGroupAdminGroup(group *gin.RouterGroup, javaClient authGateway, service *regionimgroup.Service) {
|
func registerRegionIMGroupAdminGroup(group *gin.RouterGroup, javaClient authGateway, service *regionimgroup.Service) {
|
||||||
@ -104,3 +106,20 @@ func registerRegionIMGroupAdminGroup(group *gin.RouterGroup, javaClient authGate
|
|||||||
writeOK(c, resp)
|
writeOK(c, resp)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerRegionBroadcastSimulationAdminGroup(group *gin.RouterGroup, javaClient authGateway, service *regionimgroup.Service) {
|
||||||
|
group.Use(consoleAuthMiddleware(javaClient))
|
||||||
|
group.POST("/simulate", func(c *gin.Context) {
|
||||||
|
var req highwin.BroadcastSimulationRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
writeError(c, regionimgroup.NewAppError(http.StatusBadRequest, "bad_request", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, err := highwin.SendSimulationBroadcast(c.Request.Context(), service, req)
|
||||||
|
if err != nil {
|
||||||
|
writeError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
writeOK(c, resp)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
202
internal/service/highwin/admin.go
Normal file
202
internal/service/highwin/admin.go
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
package highwin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"chatapp3-golang/internal/common"
|
||||||
|
"chatapp3-golang/internal/service/regionimgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SimulationKindLuckyGift = "LUCKY_GIFT"
|
||||||
|
SimulationKindGameWin = "GAME_WIN"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BroadcastSimulationRequest struct {
|
||||||
|
SysOrigin string `json:"sysOrigin"`
|
||||||
|
RegionCode string `json:"regionCode"`
|
||||||
|
Kind string `json:"kind"`
|
||||||
|
SenderUserID string `json:"senderUserId"`
|
||||||
|
RoomID string `json:"roomId"`
|
||||||
|
Multiple string `json:"multiple"`
|
||||||
|
WinAmount string `json:"winAmount"`
|
||||||
|
|
||||||
|
AcceptUserID string `json:"acceptUserId"`
|
||||||
|
GiftID string `json:"giftId"`
|
||||||
|
GiftCandy string `json:"giftCandy"`
|
||||||
|
GiftQuantity string `json:"giftQuantity"`
|
||||||
|
GameID string `json:"gameId"`
|
||||||
|
GameRoundID string `json:"gameRoundId"`
|
||||||
|
GameURL string `json:"gameUrl"`
|
||||||
|
BetAmount string `json:"betAmount"`
|
||||||
|
ProviderOrder string `json:"providerOrderId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BroadcastSimulationResponse struct {
|
||||||
|
SysOrigin string `json:"sysOrigin"`
|
||||||
|
RegionCode string `json:"regionCode"`
|
||||||
|
GroupID string `json:"groupId"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Data map[string]any `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendSimulationBroadcast(
|
||||||
|
ctx context.Context,
|
||||||
|
broadcaster RegionBroadcaster,
|
||||||
|
req BroadcastSimulationRequest,
|
||||||
|
) (*BroadcastSimulationResponse, error) {
|
||||||
|
if broadcaster == nil {
|
||||||
|
return nil, common.NewAppError(http.StatusInternalServerError, "region_broadcaster_missing", "region broadcaster is missing")
|
||||||
|
}
|
||||||
|
messageType, err := simulationMessageType(req.Kind)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
userID, err := parseRequiredInt64(req.SenderUserID, "senderUserId")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
roomID := strings.TrimSpace(req.RoomID)
|
||||||
|
if roomID == "" {
|
||||||
|
return nil, common.NewAppError(http.StatusBadRequest, "missing_room_id", "roomId is required")
|
||||||
|
}
|
||||||
|
amount, err := parseRequiredInt64(req.WinAmount, "winAmount")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
multiple, err := parseRequiredFloat64(req.Multiple, "multiple")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !ShouldBroadcast(multiple, amount) {
|
||||||
|
return nil, common.NewAppError(http.StatusBadRequest, "broadcast_threshold_not_met", "multiple must be >= 10 and winAmount must be > 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
data := simulationData(messageType, req, amount)
|
||||||
|
event := BroadcastEvent{
|
||||||
|
SysOrigin: req.SysOrigin,
|
||||||
|
RegionCode: req.RegionCode,
|
||||||
|
Type: messageType,
|
||||||
|
UserID: userID,
|
||||||
|
RoomID: roomID,
|
||||||
|
Multiple: multiple,
|
||||||
|
Amount: amount,
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
if err := SendRegionBroadcast(ctx, broadcaster, event); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
previewData := cloneData(data)
|
||||||
|
setRequired(previewData, "userId", strconv.FormatInt(userID, 10))
|
||||||
|
setRequired(previewData, "sendUserId", strconv.FormatInt(userID, 10))
|
||||||
|
setRequired(previewData, "senderUserId", strconv.FormatInt(userID, 10))
|
||||||
|
setRequired(previewData, "roomId", roomID)
|
||||||
|
setRequired(previewData, "multiple", normalizeMultiple(multiple))
|
||||||
|
setRequired(previewData, "winMultiple", normalizeMultiple(multiple))
|
||||||
|
setRequired(previewData, "winAmount", amount)
|
||||||
|
setRequired(previewData, "awardAmount", amount)
|
||||||
|
setRequired(previewData, "msg", highWinMessage(previewData, messageType, strconv.FormatInt(userID, 10), multiple, amount))
|
||||||
|
|
||||||
|
return &BroadcastSimulationResponse{
|
||||||
|
SysOrigin: strings.ToUpper(strings.TrimSpace(req.SysOrigin)),
|
||||||
|
RegionCode: strings.TrimSpace(req.RegionCode),
|
||||||
|
Type: messageType,
|
||||||
|
Data: previewData,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func simulationMessageType(kind string) (string, error) {
|
||||||
|
switch strings.ToUpper(strings.TrimSpace(kind)) {
|
||||||
|
case SimulationKindLuckyGift:
|
||||||
|
return MessageTypeLuckyGift, nil
|
||||||
|
case SimulationKindGameWin:
|
||||||
|
return MessageTypeBaishunWin, nil
|
||||||
|
default:
|
||||||
|
return "", common.NewAppError(http.StatusBadRequest, "invalid_broadcast_kind", "kind must be LUCKY_GIFT or GAME_WIN")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func simulationData(messageType string, req BroadcastSimulationRequest, amount int64) map[string]any {
|
||||||
|
now := strconv.FormatInt(time.Now().UnixMilli(), 10)
|
||||||
|
switch messageType {
|
||||||
|
case MessageTypeLuckyGift:
|
||||||
|
data := map[string]any{
|
||||||
|
"businessId": firstNonBlank(req.ProviderOrder, "admin-sim-lucky-gift-"+now),
|
||||||
|
"orderId": firstNonBlank(req.ProviderOrder, "admin-sim-order-"+now),
|
||||||
|
"globalNews": true,
|
||||||
|
"multipleType": "WIN",
|
||||||
|
}
|
||||||
|
setOptional(data, "acceptUserId", req.AcceptUserID)
|
||||||
|
setOptional(data, "giftId", req.GiftID)
|
||||||
|
setOptionalInt64(data, "giftCandy", req.GiftCandy)
|
||||||
|
setOptionalInt64(data, "giftQuantity", req.GiftQuantity)
|
||||||
|
return data
|
||||||
|
default:
|
||||||
|
data := map[string]any{
|
||||||
|
"gameRoundId": firstNonBlank(req.GameRoundID, "admin-sim-game-round-"+now),
|
||||||
|
"currencyDiff": amount,
|
||||||
|
}
|
||||||
|
setOptional(data, "gameId", req.GameID)
|
||||||
|
setOptional(data, "gameUrl", req.GameURL)
|
||||||
|
setOptionalInt64(data, "betAmount", req.BetAmount)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setOptional(data map[string]any, key string, value string) {
|
||||||
|
if value = strings.TrimSpace(value); value != "" {
|
||||||
|
data[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setOptionalInt64(data map[string]any, key string, value string) {
|
||||||
|
parsed, err := parseOptionalInt64(value)
|
||||||
|
if err == nil && parsed > 0 {
|
||||||
|
data[key] = parsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func firstNonBlank(values ...string) string {
|
||||||
|
for _, value := range values {
|
||||||
|
if trimmed := strings.TrimSpace(value); trimmed != "" {
|
||||||
|
return trimmed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseRequiredInt64(value string, field string) (int64, error) {
|
||||||
|
parsed, err := parseOptionalInt64(value)
|
||||||
|
if err != nil || parsed <= 0 {
|
||||||
|
return 0, common.NewAppError(http.StatusBadRequest, "invalid_"+field, fmt.Sprintf("%s must be a positive integer", field))
|
||||||
|
}
|
||||||
|
return parsed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseOptionalInt64(value string) (int64, error) {
|
||||||
|
raw := strings.TrimSpace(value)
|
||||||
|
if raw == "" {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return strconv.ParseInt(raw, 10, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseRequiredFloat64(value string, field string) (float64, error) {
|
||||||
|
raw := strings.TrimSpace(value)
|
||||||
|
if raw == "" {
|
||||||
|
return 0, common.NewAppError(http.StatusBadRequest, "invalid_"+field, fmt.Sprintf("%s must be a positive number", field))
|
||||||
|
}
|
||||||
|
parsed, err := strconv.ParseFloat(raw, 64)
|
||||||
|
if err != nil || parsed <= 0 {
|
||||||
|
return 0, common.NewAppError(http.StatusBadRequest, "invalid_"+field, fmt.Sprintf("%s must be a positive number", field))
|
||||||
|
}
|
||||||
|
return parsed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ RegionBroadcaster = (*regionimgroup.Service)(nil)
|
||||||
@ -22,13 +22,14 @@ type RegionBroadcaster interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BroadcastEvent struct {
|
type BroadcastEvent struct {
|
||||||
SysOrigin string
|
SysOrigin string
|
||||||
Type string
|
RegionCode string
|
||||||
UserID int64
|
Type string
|
||||||
RoomID string
|
UserID int64
|
||||||
Multiple float64
|
RoomID string
|
||||||
Amount int64
|
Multiple float64
|
||||||
Data map[string]any
|
Amount int64
|
||||||
|
Data map[string]any
|
||||||
}
|
}
|
||||||
|
|
||||||
func IntegralMultiple(amount, base int64) int64 {
|
func IntegralMultiple(amount, base int64) int64 {
|
||||||
@ -78,9 +79,10 @@ func SendRegionBroadcast(ctx context.Context, broadcaster RegionBroadcaster, eve
|
|||||||
setRequired(data, "msg", highWinMessage(data, messageType, userIDText, event.Multiple, event.Amount))
|
setRequired(data, "msg", highWinMessage(data, messageType, userIDText, event.Multiple, event.Amount))
|
||||||
|
|
||||||
_, err := broadcaster.SendRegionBroadcast(ctx, regionimgroup.RegionBroadcastRequest{
|
_, err := broadcaster.SendRegionBroadcast(ctx, regionimgroup.RegionBroadcastRequest{
|
||||||
SysOrigin: strings.TrimSpace(event.SysOrigin),
|
SysOrigin: strings.TrimSpace(event.SysOrigin),
|
||||||
Type: messageType,
|
RegionCode: strings.TrimSpace(event.RegionCode),
|
||||||
Data: data,
|
Type: messageType,
|
||||||
|
Data: data,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user