package roomapi import ( "net/http" "time" "hyapp/pkg/tencentrtc" "hyapp/services/gateway-service/internal/client" "hyapp/services/gateway-service/internal/transport/http/appapi" "hyapp/services/gateway-service/internal/transport/http/giftlimit" "hyapp/services/gateway-service/internal/transport/http/httproutes" ) // Handler owns room-facing HTTP endpoints in gateway. // It keeps gateway as protocol adapter only: room state still belongs to room-service. type Handler struct { roomClient client.RoomClient roomGuardClient client.RoomGuardClient roomQueryClient client.RoomQueryClient userProfileClient client.UserProfileClient userCountryClient client.UserCountryQueryClient userRegionClient client.UserRegionClient userSocialClient client.UserSocialClient userHostClient client.UserHostClient appConfigReader appapi.ConfigReader giftComboReader giftComboConfigReader walletClient client.WalletClient giftPanelCache *roomGiftPanelConfigCache growthLevelClient client.GrowthLevelClient achievementClient client.AchievementClient giftCapacityEnabled bool giftCapacityLimiter giftlimit.Limiter giftRequestTimeout time.Duration giftMaxTargets int giftMaxCount int giftMaxUnits int rtcTokenConfig tencentrtc.TokenConfig // gift-panel 的预算保留在 handler 内,生产使用固定安全值;测试可缩短预算验证真实超时分支, // 避免把 Flutter 的 15 秒客户端超时当成后端取消机制。 giftPanelTotalBudget time.Duration giftPanelRecipientCoreBudget time.Duration } type Config struct { RoomClient client.RoomClient RoomGuardClient client.RoomGuardClient RoomQueryClient client.RoomQueryClient UserProfileClient client.UserProfileClient UserCountryClient client.UserCountryQueryClient UserRegionClient client.UserRegionClient UserSocialClient client.UserSocialClient UserHostClient client.UserHostClient AppConfigReader appapi.ConfigReader WalletClient client.WalletClient GrowthLevelClient client.GrowthLevelClient AchievementClient client.AchievementClient GiftCapacityEnabled bool GiftCapacityLimiter giftlimit.Limiter GiftRequestTimeout time.Duration GiftMaxTargets int GiftMaxCount int GiftMaxUnits int RTCTokenConfig tencentrtc.TokenConfig } func New(config Config) *Handler { giftRequestTimeout := config.GiftRequestTimeout if giftRequestTimeout <= 0 { giftRequestTimeout = 5 * time.Second } giftMaxTargets := config.GiftMaxTargets if giftMaxTargets <= 0 { giftMaxTargets = 30 } giftMaxCount := config.GiftMaxCount if giftMaxCount <= 0 { giftMaxCount = 999 } giftMaxUnits := config.GiftMaxUnits if giftMaxUnits <= 0 { giftMaxUnits = 5_000 } comboReader, _ := any(config.AppConfigReader).(giftComboConfigReader) return &Handler{ roomClient: config.RoomClient, roomGuardClient: config.RoomGuardClient, roomQueryClient: config.RoomQueryClient, userProfileClient: config.UserProfileClient, userCountryClient: config.UserCountryClient, userRegionClient: config.UserRegionClient, userSocialClient: config.UserSocialClient, userHostClient: config.UserHostClient, appConfigReader: config.AppConfigReader, giftComboReader: comboReader, walletClient: config.WalletClient, giftPanelCache: newRoomGiftPanelConfigCache(45 * time.Second), growthLevelClient: config.GrowthLevelClient, achievementClient: config.AchievementClient, giftCapacityEnabled: config.GiftCapacityEnabled, giftCapacityLimiter: config.GiftCapacityLimiter, giftRequestTimeout: giftRequestTimeout, giftMaxTargets: giftMaxTargets, giftMaxCount: giftMaxCount, giftMaxUnits: giftMaxUnits, rtcTokenConfig: config.RTCTokenConfig, giftPanelTotalBudget: roomGiftPanelTotalBudget, giftPanelRecipientCoreBudget: roomGiftPanelRecipientCoreBudget, } } func (h *Handler) RoomHandlers() httproutes.RoomHandlers { return httproutes.RoomHandlers{ GetMyRoom: h.getMyRoom, ListRoomFeeds: h.listRoomFeeds, ListRoomFilters: h.listRoomFilters, ListRooms: h.listRooms, GetCurrentRoom: h.getCurrentRoom, GetRoomSnapshot: h.getRoomSnapshot, GetRoomDetail: h.getRoomDetail, GetRoomShare: h.getRoomShare, GetRoomShareLanding: h.getRoomShareLanding, ListRoomOnlineUsers: h.listRoomOnlineUsers, ListRoomBannedUsers: h.listRoomBannedUsers, GetRoomContributionRank: h.getRoomContributionRank, GetRoomGiftPanel: h.getRoomGiftPanel, GetRoomRocket: h.getRoomRocket, FollowRoom: h.handleRoomFollow, CreateRoom: h.createRoom, UpdateRoomProfile: h.updateRoomProfile, SaveRoomBackground: h.saveRoomBackground, ListRoomBackgrounds: h.listRoomBackgrounds, SetRoomBackground: h.setRoomBackground, JoinRoom: h.joinRoom, RoomHeartbeat: h.roomHeartbeat, LeaveRoom: h.leaveRoom, CloseRoom: h.closeRoom, MicUp: h.micUp, MicDown: h.micDown, ChangeMicSeat: h.changeMicSeat, ConfirmMicPublishing: h.confirmMicPublishing, MicHeartbeat: h.micHeartbeat, SetMicMute: h.setMicMute, SetMicSeatLock: h.setMicSeatLock, SetChatEnabled: h.setChatEnabled, SetRoomPassword: h.setRoomPassword, SetRoomAdmin: h.setRoomAdmin, MuteUser: h.muteUser, KickUser: h.kickUser, UnbanUser: h.unbanUser, SendGift: h.sendGift, SendGiftBatch: h.sendGiftBatch, SendGiftV2: h.sendGiftV2, } } func (h *Handler) IssueTencentRTCToken(writer http.ResponseWriter, request *http.Request) { h.issueTencentRTCToken(writer, request) } func (h *Handler) BatchRoomDisplayProfiles(writer http.ResponseWriter, request *http.Request) { h.batchRoomDisplayProfiles(writer, request) }