429 lines
13 KiB
Go
429 lines
13 KiB
Go
package router
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"chatapp3-golang/internal/config"
|
|
"chatapp3-golang/internal/service/wheel"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
const legacyGoldRewardCoverURL = "static/img/yumi-gold-coin.png"
|
|
|
|
// registerWheelRoutes registers app, admin, and copied H5-compatible wheel APIs.
|
|
func registerWheelRoutes(engine *gin.Engine, cfg config.Config, javaClient authGateway, wheelService *wheel.Service) {
|
|
if wheelService == nil {
|
|
return
|
|
}
|
|
|
|
appGroup := engine.Group("/app/wheel")
|
|
appGroup.Use(authMiddleware(javaClient))
|
|
appGroup.GET("/config", func(c *gin.Context) {
|
|
resp, err := wheelService.GetAppConfig(c.Request.Context(), mustAuthUser(c))
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, resp)
|
|
})
|
|
appGroup.POST("/draw", func(c *gin.Context) {
|
|
var req wheel.DrawRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
writeError(c, wheel.NewAppError(http.StatusBadRequest, "bad_request", err.Error()))
|
|
return
|
|
}
|
|
req.IdempotencyKey = requestIdempotencyKey(c, req.IdempotencyKey)
|
|
resp, err := wheelService.Draw(c.Request.Context(), mustAuthUser(c), req)
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, resp)
|
|
})
|
|
appGroup.GET("/history", func(c *gin.Context) {
|
|
cursor, limit := parseCursorLimit(c)
|
|
user := mustAuthUser(c)
|
|
resp, err := wheelService.PageRecords(c.Request.Context(), user.SysOrigin, c.Query("category"), user.UserID, "SUCCESS", cursor, limit)
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, resp)
|
|
})
|
|
appGroup.GET("/hints", func(c *gin.Context) {
|
|
limit, _ := strconv.Atoi(strings.TrimSpace(c.DefaultQuery("limit", "20")))
|
|
resp, err := wheelService.Hints(c.Request.Context(), mustAuthUser(c), c.Query("category"), limit)
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, gin.H{"values": resp})
|
|
})
|
|
|
|
residentGroup := engine.Group("/resident-activity/wheel")
|
|
residentGroup.Use(consoleAuthMiddleware(javaClient))
|
|
residentGroup.GET("/config", func(c *gin.Context) {
|
|
resp, err := wheelService.GetConfig(c.Request.Context(), c.Query("sysOrigin"))
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, resp)
|
|
})
|
|
residentGroup.POST("/config/save", func(c *gin.Context) {
|
|
var req wheel.SaveConfigRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
writeError(c, wheel.NewAppError(http.StatusBadRequest, "bad_request", err.Error()))
|
|
return
|
|
}
|
|
resp, err := wheelService.SaveConfig(c.Request.Context(), req)
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, resp)
|
|
})
|
|
residentGroup.POST("/config/category/save", func(c *gin.Context) {
|
|
var req wheel.SaveCategoryConfigRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
writeError(c, wheel.NewAppError(http.StatusBadRequest, "bad_request", err.Error()))
|
|
return
|
|
}
|
|
resp, err := wheelService.SaveCategoryConfig(c.Request.Context(), req)
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, resp)
|
|
})
|
|
residentGroup.GET("/record/page", func(c *gin.Context) {
|
|
cursor, limit := parseCursorLimit(c)
|
|
resp, err := wheelService.PageAdminRecords(
|
|
c.Request.Context(),
|
|
c.Query("sysOrigin"),
|
|
c.Query("category"),
|
|
wheel.ParseUserID(c.Query("userId")),
|
|
strings.TrimSpace(c.Query("status")),
|
|
cursor,
|
|
limit,
|
|
c.Query("startTime"),
|
|
c.Query("endTime"),
|
|
)
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, resp)
|
|
})
|
|
residentGroup.POST("/record/retry", func(c *gin.Context) {
|
|
var req struct {
|
|
ID int64 `json:"id,string"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
writeError(c, wheel.NewAppError(http.StatusBadRequest, "bad_request", err.Error()))
|
|
return
|
|
}
|
|
if err := wheelService.RetryDrawRecord(c.Request.Context(), req.ID); err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, gin.H{"success": true})
|
|
})
|
|
|
|
internalGroup := engine.Group("/internal/wheel")
|
|
internalGroup.Use(internalSecretMiddleware(cfg.HTTP.InternalCallbackSecret))
|
|
internalGroup.POST("/records/retry-failed", func(c *gin.Context) {
|
|
limit, _ := strconv.Atoi(strings.TrimSpace(c.DefaultQuery("limit", "50")))
|
|
processed, err := wheelService.ProcessFailedRecords(c.Request.Context(), limit)
|
|
if err != nil {
|
|
writeError(c, err)
|
|
return
|
|
}
|
|
writeOK(c, gin.H{"processed": processed})
|
|
})
|
|
|
|
registerWheelLegacyH5Routes(engine, javaClient, wheelService)
|
|
}
|
|
|
|
func registerWheelLegacyH5Routes(engine *gin.Engine, javaClient authGateway, wheelService *wheel.Service) {
|
|
legacyGroup := engine.Group("/client/api/v1")
|
|
legacyGroup.Use(authMiddleware(javaClient))
|
|
legacyGroup.GET("/config/mobile", func(c *gin.Context) {
|
|
resp, err := wheelService.GetAppConfig(c.Request.Context(), mustAuthUser(c))
|
|
if err != nil {
|
|
legacyError(c, err)
|
|
return
|
|
}
|
|
classic := legacyCategoryConfig(resp, "CLASSIC")
|
|
luxury := legacyCategoryConfig(resp, "LUXURY")
|
|
advanced := legacyCategoryConfig(resp, "ADVANCED")
|
|
legacyOK(c, gin.H{
|
|
"luckyBoxEnabled": classic.Enabled,
|
|
"middleLuckyBoxEnabled": luxury.Enabled,
|
|
"advancedLuckyBoxEnabled": advanced.Enabled,
|
|
"luckyBoxDrawAmount": classic.PriceOneGold,
|
|
"middleLuckyBoxDrawAmount": luxury.PriceOneGold,
|
|
"advancedLuckyBoxDrawAmount": advanced.PriceOneGold,
|
|
"luckyBoxDraw10Amount": classic.PriceTenGold,
|
|
"middleLuckyBoxDraw10Amount": luxury.PriceTenGold,
|
|
"advancedLuckyBoxDraw10Amount": advanced.PriceTenGold,
|
|
"luckyBoxDraw50Amount": classic.PriceFiftyGold,
|
|
"middleLuckyBoxDraw50Amount": luxury.PriceFiftyGold,
|
|
"advancedLuckyBoxDraw50Amount": advanced.PriceFiftyGold,
|
|
"wheelDrawAmount": classic.PriceOneGold,
|
|
"wheelDraw10Amount": classic.PriceTenGold,
|
|
"wheelDraw50Amount": classic.PriceFiftyGold,
|
|
})
|
|
})
|
|
legacyGroup.POST("/wallet/list", func(c *gin.Context) {
|
|
balance, err := wheelService.WalletBalances(c.Request.Context(), mustAuthUser(c))
|
|
if err != nil {
|
|
legacyError(c, err)
|
|
return
|
|
}
|
|
legacyOK(c, []gin.H{
|
|
{"walletType": "COIN", "balance": balance},
|
|
{"walletType": "DCOIN", "balance": 0},
|
|
})
|
|
})
|
|
|
|
probabilityGroup := legacyGroup.Group("/probability")
|
|
for _, prefix := range []string{"lucky-box", "middle-lucky-box", "advanced-lucky-box"} {
|
|
pathPrefix := "/" + prefix
|
|
category := legacyCategoryFromPrefix(prefix)
|
|
probabilityGroup.GET(pathPrefix+"/rewards", legacyRewardsHandler(wheelService, category))
|
|
probabilityGroup.POST(pathPrefix+"/rewards", legacyRewardsHandler(wheelService, category))
|
|
probabilityGroup.GET(pathPrefix+"/history", legacyHistoryHandler(wheelService, category))
|
|
probabilityGroup.POST(pathPrefix+"/history", legacyHistoryHandler(wheelService, category))
|
|
probabilityGroup.GET(pathPrefix+"/hints", legacyHintsHandler(wheelService, category))
|
|
probabilityGroup.POST(pathPrefix+"/hints", legacyHintsHandler(wheelService, category))
|
|
probabilityGroup.POST(pathPrefix+"/draw", legacyDrawHandler(wheelService, category))
|
|
}
|
|
}
|
|
|
|
func legacyRewardsHandler(wheelService *wheel.Service, category string) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
resp, err := wheelService.GetAppConfig(c.Request.Context(), mustAuthUser(c))
|
|
if err != nil {
|
|
legacyError(c, err)
|
|
return
|
|
}
|
|
pool := legacyCategoryConfig(resp, category)
|
|
if !pool.Enabled {
|
|
legacyOK(c, []gin.H{})
|
|
return
|
|
}
|
|
items := make([]gin.H, 0, len(pool.Rewards))
|
|
for _, reward := range pool.Rewards {
|
|
items = append(items, gin.H{
|
|
"id": reward.ID,
|
|
"animationUrl": reward.ResourceURL,
|
|
"resourceUrl": reward.ResourceURL,
|
|
"value": legacyRewardValue(reward),
|
|
"merchandise": gin.H{
|
|
"animationUrl": reward.ResourceURL,
|
|
"coverUrl": legacyRewardCover(reward),
|
|
"name": legacyRewardName(reward),
|
|
"resourceUrl": reward.ResourceURL,
|
|
},
|
|
})
|
|
}
|
|
legacyOK(c, items)
|
|
}
|
|
}
|
|
|
|
func legacyDrawHandler(wheelService *wheel.Service, category string) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var req wheel.DrawRequest
|
|
_ = c.ShouldBindJSON(&req)
|
|
req.Category = category
|
|
req.IdempotencyKey = requestIdempotencyKey(c, req.IdempotencyKey)
|
|
resp, err := wheelService.Draw(c.Request.Context(), mustAuthUser(c), req)
|
|
if err != nil {
|
|
legacyError(c, err)
|
|
return
|
|
}
|
|
rewards := make([]gin.H, 0, len(resp.Rewards))
|
|
for _, reward := range resp.Rewards {
|
|
rewards = append(rewards, gin.H{
|
|
"animationUrl": reward.ResourceURL,
|
|
"coverUrl": legacyDrawRewardCover(reward),
|
|
"count": reward.Count,
|
|
"name": legacyDrawRewardName(reward),
|
|
"resourceUrl": reward.ResourceURL,
|
|
"value": reward.Value,
|
|
})
|
|
}
|
|
legacyOK(c, gin.H{
|
|
"drawNo": resp.DrawNo,
|
|
"roomId": resp.RoomID,
|
|
"rewardValue": resp.RewardValue,
|
|
"rewards": rewards,
|
|
"balanceAfter": resp.BalanceAfter,
|
|
})
|
|
}
|
|
}
|
|
|
|
func legacyHistoryHandler(wheelService *wheel.Service, category string) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
cursor, limit := parseCursorLimit(c)
|
|
user := mustAuthUser(c)
|
|
resp, err := wheelService.PageRecords(c.Request.Context(), user.SysOrigin, category, user.UserID, "SUCCESS", cursor, limit)
|
|
if err != nil {
|
|
legacyError(c, err)
|
|
return
|
|
}
|
|
records := make([]gin.H, 0, len(resp.Records))
|
|
for _, record := range resp.Records {
|
|
records = append(records, gin.H{
|
|
"createdTime": record.CreateTime,
|
|
"drawNo": record.DrawNo,
|
|
"drawTimes": record.DrawTimes,
|
|
"rewardValue": legacyRecordValue(record),
|
|
"rewards": []gin.H{{
|
|
"animationUrl": record.ResourceURL,
|
|
"coverUrl": legacyRecordCover(record),
|
|
"count": 1,
|
|
"name": legacyRecordName(record),
|
|
"resourceUrl": record.ResourceURL,
|
|
"value": legacyRecordValue(record),
|
|
}},
|
|
})
|
|
}
|
|
legacyOK(c, gin.H{"records": records, "total": resp.Total})
|
|
}
|
|
}
|
|
|
|
func legacyHintsHandler(wheelService *wheel.Service, category string) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
resp, err := wheelService.Hints(c.Request.Context(), mustAuthUser(c), category, 20)
|
|
if err != nil {
|
|
legacyError(c, err)
|
|
return
|
|
}
|
|
values := make([]gin.H, 0, len(resp))
|
|
for index, reward := range resp {
|
|
values = append(values, gin.H{
|
|
"avatar": reward.CoverURL,
|
|
"nickname": "User" + strconv.Itoa(index+1),
|
|
"value": legacyDrawRewardName(reward),
|
|
})
|
|
}
|
|
legacyOK(c, gin.H{"values": values})
|
|
}
|
|
}
|
|
|
|
func parseCursorLimit(c *gin.Context) (int, int) {
|
|
cursor, _ := strconv.Atoi(strings.TrimSpace(c.DefaultQuery("cursor", "1")))
|
|
limit, _ := strconv.Atoi(strings.TrimSpace(c.DefaultQuery("limit", "20")))
|
|
return cursor, limit
|
|
}
|
|
|
|
func legacyOK(c *gin.Context, data any) {
|
|
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "success", "data": data})
|
|
}
|
|
|
|
func legacyError(c *gin.Context, err error) {
|
|
c.JSON(http.StatusOK, gin.H{"code": 500, "msg": err.Error(), "data": nil})
|
|
}
|
|
|
|
func legacyCategoryFromPrefix(prefix string) string {
|
|
switch prefix {
|
|
case "middle-lucky-box":
|
|
return "LUXURY"
|
|
case "advanced-lucky-box":
|
|
return "ADVANCED"
|
|
default:
|
|
return "CLASSIC"
|
|
}
|
|
}
|
|
|
|
func legacyCategoryConfig(resp *wheel.ConfigResponse, category string) wheel.CategoryConfigPayload {
|
|
for _, item := range resp.Categories {
|
|
if strings.EqualFold(item.Category, category) {
|
|
return item
|
|
}
|
|
}
|
|
return wheel.CategoryConfigPayload{Category: category, Rewards: []wheel.RewardConfigPayload{}}
|
|
}
|
|
|
|
func legacyRewardValue(reward wheel.RewardConfigPayload) int64 {
|
|
if strings.EqualFold(reward.RewardType, "GOLD") {
|
|
return reward.GoldAmount
|
|
}
|
|
return reward.DisplayGoldAmount
|
|
}
|
|
|
|
func legacyRewardCover(reward wheel.RewardConfigPayload) string {
|
|
if strings.TrimSpace(reward.CoverURL) != "" {
|
|
return reward.CoverURL
|
|
}
|
|
if strings.EqualFold(reward.RewardType, "GOLD") {
|
|
return legacyGoldRewardCoverURL
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func legacyDrawRewardCover(reward wheel.DrawRewardPayload) string {
|
|
if strings.TrimSpace(reward.CoverURL) != "" {
|
|
return reward.CoverURL
|
|
}
|
|
if strings.EqualFold(reward.RewardType, "GOLD") {
|
|
return legacyGoldRewardCoverURL
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func legacyRecordCover(record wheel.DrawRecordPayload) string {
|
|
if strings.TrimSpace(record.CoverURL) != "" {
|
|
return record.CoverURL
|
|
}
|
|
if strings.EqualFold(record.RewardType, "GOLD") {
|
|
return legacyGoldRewardCoverURL
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func legacyRecordValue(record wheel.DrawRecordPayload) int64 {
|
|
if strings.EqualFold(record.RewardType, "GOLD") {
|
|
return record.GoldAmount
|
|
}
|
|
return record.DisplayGoldAmount
|
|
}
|
|
|
|
func legacyRewardName(reward wheel.RewardConfigPayload) string {
|
|
if reward.ResourceName != "" {
|
|
return reward.ResourceName
|
|
}
|
|
if reward.RewardType == "GOLD" {
|
|
return "金币"
|
|
}
|
|
return "Reward"
|
|
}
|
|
|
|
func legacyDrawRewardName(reward wheel.DrawRewardPayload) string {
|
|
if reward.Name != "" {
|
|
return reward.Name
|
|
}
|
|
if reward.ResourceName != "" {
|
|
return reward.ResourceName
|
|
}
|
|
if reward.RewardType == "GOLD" {
|
|
return "金币"
|
|
}
|
|
return "Reward"
|
|
}
|
|
|
|
func legacyRecordName(record wheel.DrawRecordPayload) string {
|
|
if record.ResourceName != "" {
|
|
return record.ResourceName
|
|
}
|
|
if record.RewardType == "GOLD" {
|
|
return "金币"
|
|
}
|
|
return "Reward"
|
|
}
|