package admin import ( "net/http" "strconv" "bindbox-game/internal/code" "bindbox-game/internal/pkg/core" "bindbox-game/internal/pkg/validation" activitysvc "bindbox-game/internal/service/activity" ) type rewardItem struct { ID int64 `json:"id"` ProductID int64 `json:"product_id"` Name string `json:"name" binding:"required"` Weight float64 `json:"weight" binding:"required"` Quantity int64 `json:"quantity" binding:"required"` OriginalQty int64 `json:"original_qty" binding:"required"` Level int32 `json:"level" binding:"required"` Sort int32 `json:"sort"` IsBoss int32 `json:"is_boss"` MinScore int64 `json:"min_score"` } type createRewardsRequest struct { Rewards []rewardItem `json:"rewards" binding:"required"` } type listRewardsResponse struct { List []rewardItem `json:"list"` } // CreateIssueRewards 创建期数奖品 // @Summary 创建期数奖品 // @Description 为指定期数批量创建奖励配置 // @Tags 管理端.活动 // @Accept json // @Produce json // @Param activity_id path integer true "活动ID" // @Param issue_id path integer true "期ID" // @Param RequestBody body createRewardsRequest true "请求参数" // @Success 200 {object} simpleMessageResponse // @Failure 400 {object} code.Failure // @Router /api/admin/activities/{activity_id}/issues/{issue_id}/rewards [post] // @Security LoginVerifyToken func (h *handler) CreateIssueRewards() core.HandlerFunc { return func(ctx core.Context) { req := new(createRewardsRequest) res := new(simpleMessageResponse) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateIssueRewardsError, "禁止操作")) return } issueID, err := strconv.ParseInt(ctx.Param("issue_id"), 10, 64) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递期ID")) return } var rewards []activitysvc.CreateRewardInput for _, r := range req.Rewards { rewards = append(rewards, activitysvc.CreateRewardInput{ ProductID: r.ProductID, Name: r.Name, Weight: int32(r.Weight), Quantity: r.Quantity, OriginalQty: r.OriginalQty, Level: r.Level, Sort: r.Sort, IsBoss: r.IsBoss, MinScore: r.MinScore, }) } if err := h.activity.CreateIssueRewards(ctx.RequestContext(), issueID, rewards); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateIssueRewardsError, err.Error())) return } res.Message = "操作成功" ctx.Payload(res) } } // ListIssueRewards 查看期数奖品 // @Summary 查看期数奖品 // @Description 查看指定期数的奖励配置列表 // @Tags 管理端.活动 // @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/admin/activities/{activity_id}/issues/{issue_id}/rewards [get] // @Security LoginVerifyToken func (h *handler) ListIssueRewards() core.HandlerFunc { return func(ctx core.Context) { issueID, err := strconv.ParseInt(ctx.Param("issue_id"), 10, 64) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递期ID")) return } items, err := h.activity.ListIssueRewards(ctx.RequestContext(), issueID) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ListIssueRewardsError, err.Error())) return } res := new(listRewardsResponse) res.List = make([]rewardItem, len(items)) for i, v := range items { res.List[i] = rewardItem{ ID: v.ID, ProductID: v.ProductID, Name: v.Name, Weight: float64(v.Weight), Quantity: v.Quantity, OriginalQty: v.OriginalQty, Level: v.Level, Sort: v.Sort, IsBoss: v.IsBoss, MinScore: v.MinScore, } } ctx.Payload(res) } } type modifyRewardRequest struct { 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"` Sort *int32 `json:"sort"` IsBoss *int32 `json:"is_boss"` MinScore *int64 `json:"min_score"` } // ModifyIssueReward 更新期数奖励 // @Summary 更新期数奖励 // @Tags 管理端.活动 // @Accept json // @Produce json // @Param activity_id path integer true "活动ID" // @Param issue_id path integer true "期ID" // @Param reward_id path integer true "奖励ID" // @Param RequestBody body modifyRewardRequest true "请求参数" // @Success 200 {object} simpleMessageResponse // @Failure 400 {object} code.Failure // @Router /api/admin/activities/{activity_id}/issues/{issue_id}/rewards/{reward_id} [put] // @Security LoginVerifyToken func (h *handler) ModifyIssueReward() core.HandlerFunc { return func(ctx core.Context) { req := new(modifyRewardRequest) res := new(simpleMessageResponse) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateIssueRewardsError, "禁止操作")) return } rewardID, err := strconv.ParseInt(ctx.Param("reward_id"), 10, 64) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递奖励ID")) return } in := activitysvc.ModifyRewardInput{ ProductID: req.ProductID, Name: req.Name, Weight: req.Weight, Quantity: req.Quantity, OriginalQty: req.OriginalQty, Level: req.Level, Sort: req.Sort, IsBoss: req.IsBoss, MinScore: req.MinScore, } if err := h.activity.ModifyIssueReward(ctx.RequestContext(), rewardID, in); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateIssueRewardsError, err.Error())) return } res.Message = "操作成功" ctx.Payload(res) } } // DeleteIssueReward 删除期数奖励 // @Summary 删除期数奖励 // @Tags 管理端.活动 // @Accept json // @Produce json // @Param activity_id path integer true "活动ID" // @Param issue_id path integer true "期ID" // @Param reward_id path integer true "奖励ID" // @Success 200 {object} simpleMessageResponse // @Failure 400 {object} code.Failure // @Router /api/admin/activities/{activity_id}/issues/{issue_id}/rewards/{reward_id} [delete] // @Security LoginVerifyToken func (h *handler) DeleteIssueReward() core.HandlerFunc { return func(ctx core.Context) { res := new(simpleMessageResponse) if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateIssueRewardsError, "禁止操作")) return } rewardID, err := strconv.ParseInt(ctx.Param("reward_id"), 10, 64) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递奖励ID")) return } if err := h.activity.DeleteIssueReward(ctx.RequestContext(), rewardID); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateIssueRewardsError, err.Error())) return } res.Message = "操作成功" ctx.Payload(res) } } type batchModifyRewardItem struct { RewardID int64 `json:"reward_id" binding:"required"` Weight *int32 `json:"weight" binding:"omitempty,gte=0"` } type batchModifyRewardsRequest struct { Rewards []batchModifyRewardItem `json:"rewards" binding:"required,dive"` } // BatchModifyIssueRewards 批量更新期数奖励 // @Summary 批量更新期数奖励 // @Tags 管理端.活动 // @Accept json // @Produce json // @Param activity_id path integer true "活动ID" // @Param issue_id path integer true "期ID" // @Param RequestBody body batchModifyRewardsRequest true "请求参数" // @Success 200 {object} simpleMessageResponse // @Failure 400 {object} code.Failure // @Router /api/admin/activities/{activity_id}/issues/{issue_id}/rewards/batch [put] // @Security LoginVerifyToken func (h *handler) BatchModifyIssueRewards() core.HandlerFunc { return func(ctx core.Context) { req := new(batchModifyRewardsRequest) res := new(simpleMessageResponse) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateIssueRewardsError, "禁止操作")) return } for _, item := range req.Rewards { in := activitysvc.ModifyRewardInput{ Weight: item.Weight, } if err := h.activity.ModifyIssueReward(ctx.RequestContext(), item.RewardID, in); err != nil { // Log error but continue or abort? For batch, aborting on first error is usually safer or return partial errors. // For simplicity here, we abort. ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateIssueRewardsError, err.Error())) return } } res.Message = "批量操作成功" ctx.Payload(res) } }