138 lines
4.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package app
import (
"encoding/json"
"net/http"
"sort"
"strconv"
"bindbox-game/internal/code"
"bindbox-game/internal/pkg/core"
"bindbox-game/internal/pkg/validation"
)
type rewardItem struct {
ID int64 `json:"id"`
ProductID int64 `json:"product_id"`
Name string `json:"name"`
Weight int32 `json:"weight"`
Quantity int64 `json:"quantity"`
OriginalQty int64 `json:"original_qty"`
Level int32 `json:"level"`
PrizeLevel int32 `json:"prize_level"` // 兼容部分前端逻辑
Sort int32 `json:"sort"`
IsBoss int32 `json:"is_boss"`
ProductImage string `json:"product_image"`
MinScore int64 `json:"min_score"`
}
type listRewardsResponse struct {
List []rewardItem `json:"list"`
PlayType string `json:"play_type"` // 活动类型
}
// ListIssueRewards 奖励配置列表
// @Summary 奖励配置列表
// @Description 获取指定期的奖励配置列表
// @Tags APP端.活动
// @Accept json
// @Produce json
// @Param activity_id path integer true "活动ID"
// @Param issue_id path integer true "期ID"
// @Success 200 {object} listRewardsResponse
// @Failure 400 {object} code.Failure
// @Router /api/app/activities/{activity_id}/issues/{issue_id}/rewards [get]
func (h *handler) ListIssueRewards() core.HandlerFunc {
return func(ctx core.Context) {
issueIDStr := ctx.Param("issue_id")
if issueIDStr == "" {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递期ID"))
return
}
if _, err := strconv.ParseInt(issueIDStr, 10, 64); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
return
}
issueID, _ := strconv.ParseInt(issueIDStr, 10, 64)
items, err := h.activity.ListIssueRewards(ctx.RequestContext(), issueID)
if err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ListIssueRewardsError, err.Error()))
return
}
// 获取活动信息以判断 PlayType决定排序方式
activityIDStr := ctx.Param("activity_id")
aid, _ := strconv.ParseInt(activityIDStr, 10, 64)
act, _ := h.activity.GetActivity(ctx.RequestContext(), aid)
// 排序逻辑差异化
if act != nil && (act.PlayType == "matching" || act.PlayType == "matching_game") {
// 对对碰:按 MinScore 降序,其次按 Sort 升序
sort.Slice(items, func(i, j int) bool {
if items[i].MinScore != items[j].MinScore {
return items[i].MinScore > items[j].MinScore
}
return items[i].Sort < items[j].Sort
})
} else {
// 通用逻辑:已经在 Service 层处理过初步排序 (IsBoss DESC, Level ASC, Sort ASC)
// 这里如果需要显式再次确认也可以,但目前保持现状
}
pidSet := make(map[int64]struct{})
for _, v := range items {
if v.ProductID > 0 {
pidSet[v.ProductID] = struct{}{}
}
}
imageMap := make(map[int64]string)
nameMap := make(map[int64]string)
if len(pidSet) > 0 {
ids := make([]int64, 0, len(pidSet))
for id := range pidSet {
ids = append(ids, id)
}
pros, err := h.readDB.Products.WithContext(ctx.RequestContext()).ReadDB().Where(h.readDB.Products.ID.In(ids...)).Find()
if err == nil {
for _, p := range pros {
first := ""
if p.ImagesJSON != "" {
var arr []string
_ = json.Unmarshal([]byte(p.ImagesJSON), &arr)
if len(arr) > 0 {
first = arr[0]
}
}
imageMap[p.ID] = first
nameMap[p.ID] = p.Name
}
}
}
res := new(listRewardsResponse)
if act != nil {
res.PlayType = act.PlayType
}
res.List = make([]rewardItem, len(items))
for i, v := range items {
// 直接使用商品名称
nameVal := nameMap[v.ProductID]
res.List[i] = rewardItem{
ID: v.ID,
ProductID: v.ProductID,
Name: nameVal,
Weight: v.Weight,
Quantity: v.Quantity,
OriginalQty: v.OriginalQty,
Level: v.Level,
PrizeLevel: v.Level,
Sort: v.Sort,
IsBoss: v.IsBoss,
ProductImage: imageMap[v.ProductID],
MinScore: v.MinScore,
}
}
ctx.Payload(res)
}
}