package httproutes import ( "net/http" "hyapp/services/gateway-service/internal/transport/http/httpkit" ) const APIV1Prefix = "/api/v1" type Wrapper func(http.HandlerFunc) http.Handler type Config struct { PublicWrap Wrapper AuthWrap Wrapper ProfileWrap Wrapper Auth AuthHandlers App AppHandlers User UserHandlers Manager ManagerHandlers Room RoomHandlers Message MessageHandlers Task TaskHandlers Level LevelHandlers Achievement AchievementHandlers Wallet WalletHandlers VIP VIPHandlers Game GameHandlers } type AuthHandlers struct { LoginPassword http.HandlerFunc SetPassword http.HandlerFunc QuickCreateAccount http.HandlerFunc LoginThirdParty http.HandlerFunc RefreshToken http.HandlerFunc Logout http.HandlerFunc } type AppHandlers struct { ListRegistrationCountries http.HandlerFunc ListLoginRiskBlockedCountries http.HandlerFunc GetAppBootstrap http.HandlerFunc ListH5Links http.HandlerFunc ListExploreTabs http.HandlerFunc ListAppBanners http.HandlerFunc GetAppVersion http.HandlerFunc GetResourceGroup http.HandlerFunc ListResourceShopItems http.HandlerFunc PurchaseResourceShopItem http.HandlerFunc ListGifts http.HandlerFunc ListGiftTabs http.HandlerFunc ListEmojiPacks http.HandlerFunc IssueTencentIMUserSig http.HandlerFunc IssueTencentRTCToken http.HandlerFunc HandleTencentIMCallback http.HandlerFunc HandleTencentRTCCallback http.HandlerFunc UploadFile http.HandlerFunc UploadAvatar http.HandlerFunc HandlePushToken http.HandlerFunc } type UserHandlers struct { ResolveDisplayUserID http.HandlerFunc BatchUserProfiles http.HandlerFunc BatchRoomDisplayProfiles http.HandlerFunc GetMyOverview http.HandlerFunc GetMyGiftWall http.HandlerFunc GetMyIdentity http.HandlerFunc GetMyHostIdentity http.HandlerFunc GetMyRoleSummary http.HandlerFunc SearchHostAgencies http.HandlerFunc ApplyToHostAgency http.HandlerFunc CompleteMyOnboarding http.HandlerFunc UpdateMyProfile http.HandlerFunc ChangeMyCountry http.HandlerFunc ChangeMyDisplayUserID http.HandlerFunc ApplyMyPrettyDisplayUserID http.HandlerFunc ListMyProfileVisitors http.HandlerFunc ListMyFollowing http.HandlerFunc ListMyFriends http.HandlerFunc ListMyFriendApplications http.HandlerFunc GetMyProfile http.HandlerFunc ListMyResources http.HandlerFunc EquipMyResource http.HandlerFunc UserSocialAction http.HandlerFunc } type ManagerHandlers struct { ListManagerGrantResources http.HandlerFunc GrantManagerResource http.HandlerFunc LookupBusinessUsers http.HandlerFunc } type RoomHandlers struct { GetMyRoom http.HandlerFunc ListRoomFeeds http.HandlerFunc ListRooms http.HandlerFunc GetCurrentRoom http.HandlerFunc GetRoomSnapshot http.HandlerFunc GetRoomDetail http.HandlerFunc ListRoomOnlineUsers http.HandlerFunc GetRoomGiftPanel http.HandlerFunc GetRoomTreasure http.HandlerFunc FollowRoom http.HandlerFunc CreateRoom http.HandlerFunc UpdateRoomProfile http.HandlerFunc JoinRoom http.HandlerFunc RoomHeartbeat http.HandlerFunc LeaveRoom http.HandlerFunc CloseRoom http.HandlerFunc MicUp http.HandlerFunc MicDown http.HandlerFunc ChangeMicSeat http.HandlerFunc ConfirmMicPublishing http.HandlerFunc SetMicMute http.HandlerFunc SetMicSeatLock http.HandlerFunc SetChatEnabled http.HandlerFunc SetRoomPassword http.HandlerFunc SetRoomAdmin http.HandlerFunc MuteUser http.HandlerFunc KickUser http.HandlerFunc UnbanUser http.HandlerFunc SendGift http.HandlerFunc } type MessageHandlers struct { ListMessageTabs http.HandlerFunc MarkInboxSectionRead http.HandlerFunc MarkInboxMessageReadPath http.HandlerFunc DeleteInboxMessagePath http.HandlerFunc ListInboxMessages http.HandlerFunc } type TaskHandlers struct { ListTaskTabs http.HandlerFunc ClaimTaskReward http.HandlerFunc GetRegistrationRewardEligibility http.HandlerFunc GetFirstRechargeRewardStatus http.HandlerFunc GetSevenDayCheckInStatus http.HandlerFunc SignSevenDayCheckIn http.HandlerFunc ListUserLeaderboards http.HandlerFunc CheckLuckyGift http.HandlerFunc } type LevelHandlers struct { GetMyLevelOverview http.HandlerFunc GetLevelTrack http.HandlerFunc ListLevelRewards http.HandlerFunc } type AchievementHandlers struct { ListAchievements http.HandlerFunc ListMyBadges http.HandlerFunc SetBadgeDisplay http.HandlerFunc } type WalletHandlers struct { GetWalletOverview http.HandlerFunc GetMyBalances http.HandlerFunc ListRechargeProducts http.HandlerFunc ConfirmGooglePayment http.HandlerFunc GetDiamondExchangeConfig http.HandlerFunc ApplyWithdrawal http.HandlerFunc ListCoinTransactions http.HandlerFunc ListWalletTransactions http.HandlerFunc ListCoinSellers http.HandlerFunc TransferCoinFromSeller http.HandlerFunc GetRedPacketConfig http.HandlerFunc ListRoomRedPackets http.HandlerFunc CreateRoomRedPacket http.HandlerFunc GetRedPacket http.HandlerFunc ClaimRedPacket http.HandlerFunc } type VIPHandlers struct { GetMyVIP http.HandlerFunc ListVIPPackages http.HandlerFunc PurchaseVIP http.HandlerFunc } type GameHandlers struct { ListGames http.HandlerFunc LaunchGame http.HandlerFunc HandleCallback http.HandlerFunc } type routes struct { mux *http.ServeMux config Config } // New 只维护 gateway 对外 HTTP 路径到 transport handler 的绑定。 // 业务状态和命令执行仍然全部下沉到 owner service,路由层不承载业务规则。 func New(config Config) http.Handler { mux := http.NewServeMux() routes := routes{mux: mux, config: config} routes.registerAuthRoutes() routes.registerAppRoutes() routes.registerUserRoutes() routes.registerManagerRoutes() routes.registerRoomRoutes() routes.registerMessageRoutes() routes.registerTaskRoutes() routes.registerLevelRoutes() routes.registerAchievementRoutes() routes.registerWalletRoutes() routes.registerVIPRoutes() routes.registerGameRoutes() return mux } func (r routes) public(path string, method string, next http.HandlerFunc) { r.register(path, method, r.config.PublicWrap, next) } func (r routes) auth(path string, method string, next http.HandlerFunc) { r.register(path, method, r.config.AuthWrap, next) } func (r routes) profile(path string, method string, next http.HandlerFunc) { r.register(path, method, r.config.ProfileWrap, next) } func (r routes) register(path string, method string, wrap Wrapper, next http.HandlerFunc) { if method != "" { // method 继续走 gateway envelope,而不是使用 ServeMux 自动 405。 next = httpkit.RequireMethod(method, next) } r.mux.Handle(APIV1Prefix+path, wrap(next)) } func (r routes) registerAuthRoutes() { h := r.config.Auth r.public("/auth/account/login", "", h.LoginPassword) r.auth("/auth/password/set", "", h.SetPassword) r.public("/auth/account/quick-create", http.MethodPost, h.QuickCreateAccount) r.public("/auth/third-party/login", "", h.LoginThirdParty) r.public("/auth/token/refresh", "", h.RefreshToken) r.public("/auth/logout", "", h.Logout) } func (r routes) registerAppRoutes() { h := r.config.App r.public("/countries", "", h.ListRegistrationCountries) r.public("/login-risk/blocked-countries", http.MethodGet, h.ListLoginRiskBlockedCountries) r.public("/app/bootstrap", "", h.GetAppBootstrap) r.public("/app/h5-links", "", h.ListH5Links) r.public("/app/explore-tabs", http.MethodGet, h.ListExploreTabs) r.public("/app/banners", "", h.ListAppBanners) r.public("/app/version", http.MethodGet, h.GetAppVersion) r.public("/resource-groups/{group_id}", "", h.GetResourceGroup) r.public("/resource-shop/items", http.MethodGet, h.ListResourceShopItems) r.profile("/resource-shop/items/{shop_item_id}/purchase", http.MethodPost, h.PurchaseResourceShopItem) r.public("/gifts", "", h.ListGifts) r.public("/gift-tabs", http.MethodGet, h.ListGiftTabs) r.public("/emoji-packs", http.MethodGet, h.ListEmojiPacks) r.profile("/im/usersig", http.MethodGet, h.IssueTencentIMUserSig) r.profile("/rtc/token", http.MethodPost, h.IssueTencentRTCToken) r.public("/tencent-im/callback", "", h.HandleTencentIMCallback) r.public("/tencent-rtc/callback", "", h.HandleTencentRTCCallback) r.auth("/files/upload", "", h.UploadFile) r.auth("/files/avatar/upload", "", h.UploadAvatar) r.profile("/devices/push-token", "", h.HandlePushToken) } func (r routes) registerUserRoutes() { h := r.config.User r.public("/users/by-display-user-id/{display_user_id}", "", h.ResolveDisplayUserID) r.profile("/users/profiles:batch", "", h.BatchUserProfiles) r.profile("/users/room-display-profiles:batch", http.MethodGet, h.BatchRoomDisplayProfiles) r.profile("/users/me/overview", "", h.GetMyOverview) r.profile("/users/me/gift-wall", http.MethodGet, h.GetMyGiftWall) r.auth("/users/me/identity", "", h.GetMyIdentity) r.profile("/users/me/host-identity", "", h.GetMyHostIdentity) r.profile("/users/me/role-summary", "", h.GetMyRoleSummary) r.profile("/host/agencies/search", http.MethodGet, h.SearchHostAgencies) r.profile("/host/agency-applications", http.MethodPost, h.ApplyToHostAgency) r.auth("/users/me/onboarding/complete", "", h.CompleteMyOnboarding) r.profile("/users/me/profile/update", "", h.UpdateMyProfile) r.profile("/users/me/country/change", "", h.ChangeMyCountry) r.auth("/users/me/display-id/change", "", h.ChangeMyDisplayUserID) r.auth("/users/me/display-id/pretty/apply", "", h.ApplyMyPrettyDisplayUserID) r.profile("/users/me/visitors", http.MethodGet, h.ListMyProfileVisitors) r.profile("/users/me/following", http.MethodGet, h.ListMyFollowing) r.profile("/users/me/friends", http.MethodGet, h.ListMyFriends) r.profile("/users/me/friend-requests", http.MethodGet, h.ListMyFriendApplications) r.profile("/users/me", "", h.GetMyProfile) r.profile("/users/me/resources", "", h.ListMyResources) r.profile("/users/me/resources/{resource_id}/equip", "", h.EquipMyResource) r.profile("/users/{user_id}/{action...}", "", h.UserSocialAction) } func (r routes) registerManagerRoutes() { h := r.config.Manager r.profile("/manager-center/resource-grants/resources", http.MethodGet, h.ListManagerGrantResources) r.profile("/manager-center/resource-grants", http.MethodPost, h.GrantManagerResource) r.profile("/business/users/lookup", http.MethodGet, h.LookupBusinessUsers) } func (r routes) registerRoomRoutes() { h := r.config.Room r.profile("/rooms/me", http.MethodGet, h.GetMyRoom) r.profile("/rooms/feeds", http.MethodGet, h.ListRoomFeeds) r.profile("/rooms", http.MethodGet, h.ListRooms) r.profile("/rooms/current", http.MethodGet, h.GetCurrentRoom) r.profile("/rooms/snapshot", http.MethodGet, h.GetRoomSnapshot) r.profile("/rooms/{room_id}/detail", http.MethodGet, h.GetRoomDetail) r.profile("/rooms/{room_id}/online-users", http.MethodGet, h.ListRoomOnlineUsers) r.profile("/rooms/{room_id}/gift-panel", http.MethodGet, h.GetRoomGiftPanel) r.profile("/rooms/{room_id}/treasure", http.MethodGet, h.GetRoomTreasure) r.profile("/rooms/{room_id}/follow", "", h.FollowRoom) r.profile("/rooms/create", http.MethodPost, h.CreateRoom) r.profile("/rooms/profile/update", http.MethodPost, h.UpdateRoomProfile) r.profile("/rooms/join", http.MethodPost, h.JoinRoom) r.profile("/rooms/heartbeat", http.MethodPost, h.RoomHeartbeat) r.profile("/rooms/leave", http.MethodPost, h.LeaveRoom) r.profile("/rooms/close", http.MethodPost, h.CloseRoom) r.profile("/rooms/mic/up", http.MethodPost, h.MicUp) r.profile("/rooms/mic/down", http.MethodPost, h.MicDown) r.profile("/rooms/mic/change", http.MethodPost, h.ChangeMicSeat) r.profile("/rooms/mic/publishing/confirm", http.MethodPost, h.ConfirmMicPublishing) r.profile("/rooms/mic/mute", http.MethodPost, h.SetMicMute) r.profile("/rooms/mic/lock", http.MethodPost, h.SetMicSeatLock) r.profile("/rooms/chat/enabled", http.MethodPost, h.SetChatEnabled) r.profile("/rooms/password", http.MethodPost, h.SetRoomPassword) r.profile("/rooms/admin/set", http.MethodPost, h.SetRoomAdmin) r.profile("/rooms/user/mute", http.MethodPost, h.MuteUser) r.profile("/rooms/user/kick", http.MethodPost, h.KickUser) r.profile("/rooms/user/unban", http.MethodPost, h.UnbanUser) r.profile("/rooms/gift/send", http.MethodPost, h.SendGift) } func (r routes) registerMessageRoutes() { h := r.config.Message r.profile("/messages/tabs", "", h.ListMessageTabs) r.profile("/messages/read-all", "", h.MarkInboxSectionRead) r.profile("/messages/{message_id}/read", "", h.MarkInboxMessageReadPath) r.profile("/messages/{message_id}", "", h.DeleteInboxMessagePath) r.profile("/messages", "", h.ListInboxMessages) } func (r routes) registerTaskRoutes() { h := r.config.Task r.profile("/activities/registration-reward/eligibility", http.MethodGet, h.GetRegistrationRewardEligibility) r.profile("/activities/first-recharge-reward", http.MethodGet, h.GetFirstRechargeRewardStatus) r.profile("/activities/seven-day-checkin", http.MethodGet, h.GetSevenDayCheckInStatus) r.profile("/activities/seven-day-checkin/sign", http.MethodPost, h.SignSevenDayCheckIn) r.profile("/activities/user-leaderboards", http.MethodGet, h.ListUserLeaderboards) // App 侧接口保持稳定;内部仍按 pool_id 走当前 v2 规则、抽奖和返奖实现。 r.profile("/activities/lucky-gifts/check", http.MethodPost, h.CheckLuckyGift) r.profile("/tasks/tabs", http.MethodGet, h.ListTaskTabs) r.profile("/tasks/claim", http.MethodPost, h.ClaimTaskReward) } func (r routes) registerLevelRoutes() { h := r.config.Level r.profile("/levels/me/overview", http.MethodGet, h.GetMyLevelOverview) r.profile("/levels/tracks/{track}", http.MethodGet, h.GetLevelTrack) r.profile("/levels/rewards", http.MethodGet, h.ListLevelRewards) } func (r routes) registerAchievementRoutes() { h := r.config.Achievement r.profile("/achievements", http.MethodGet, h.ListAchievements) r.profile("/badges/me", http.MethodGet, h.ListMyBadges) r.profile("/badges/display", http.MethodPost, h.SetBadgeDisplay) } func (r routes) registerWalletRoutes() { h := r.config.Wallet r.profile("/wallet/me/overview", http.MethodGet, h.GetWalletOverview) r.profile("/wallet/me/balances", "", h.GetMyBalances) r.profile("/wallet/recharge/products", http.MethodGet, h.ListRechargeProducts) r.profile("/wallet/payments/google/confirm", http.MethodPost, h.ConfirmGooglePayment) r.profile("/wallet/diamond-exchange/config", http.MethodGet, h.GetDiamondExchangeConfig) r.profile("/wallet/withdrawals/apply", http.MethodPost, h.ApplyWithdrawal) r.profile("/wallet/coin-transactions", http.MethodGet, h.ListCoinTransactions) r.profile("/wallet/transactions", http.MethodGet, h.ListWalletTransactions) r.profile("/wallet/coin-sellers", http.MethodGet, h.ListCoinSellers) r.profile("/wallet/coin-seller/transfer", "", h.TransferCoinFromSeller) r.profile("/red-packets/config", http.MethodGet, h.GetRedPacketConfig) r.profile("/rooms/{room_id}/red-packets", http.MethodGet, h.ListRoomRedPackets) r.profile("/rooms/{room_id}/red-packets/create", http.MethodPost, h.CreateRoomRedPacket) r.profile("/red-packets/{packet_id}", http.MethodGet, h.GetRedPacket) r.profile("/red-packets/{packet_id}/claim", http.MethodPost, h.ClaimRedPacket) } func (r routes) registerVIPRoutes() { h := r.config.VIP r.profile("/vip/me", http.MethodGet, h.GetMyVIP) r.profile("/vip/packages", http.MethodGet, h.ListVIPPackages) r.profile("/vip/purchase", http.MethodPost, h.PurchaseVIP) } func (r routes) registerGameRoutes() { h := r.config.Game r.profile("/games", http.MethodGet, h.ListGames) r.profile("/games/{game_id}/launch", http.MethodPost, h.LaunchGame) r.public("/game-callbacks/{platform_code}/{operation}", http.MethodPost, h.HandleCallback) }