package admin import ( "net/http" "bindbox-game/internal/code" "bindbox-game/internal/pkg/core" "bindbox-game/internal/pkg/validation" usersvc "bindbox-game/internal/service/user" ) type batchPointsRequest struct { Users []int64 `json:"users" binding:"required"` Amount int64 `json:"amount" binding:"min=1"` Reason string `json:"reason"` IdempotencyKey string `json:"idempotency_key"` } type batchCouponsRequest struct { Users []int64 `json:"users" binding:"required"` CouponID int64 `json:"coupon_id" binding:"required"` QuantityPerUser int `json:"quantity_per_user"` IdempotencyKey string `json:"idempotency_key"` } type batchRewardsRequest struct { Users []int64 `json:"users" binding:"required"` ProductID int64 `json:"product_id" binding:"required"` Quantity int `json:"quantity" binding:"min=1"` ActivityID *int64 `json:"activity_id"` RewardID *int64 `json:"reward_id"` AddressID *int64 `json:"address_id"` Remark string `json:"remark"` IdempotencyKey string `json:"idempotency_key"` } type batchItemResult struct { UserID int64 `json:"user_id"` Status string `json:"status"` Message string `json:"message"` } type batchResponse struct { Success int `json:"success"` Failed int `json:"failed"` Details []batchItemResult `json:"details"` } func (h *handler) BatchAddUserPoints() core.HandlerFunc { return func(ctx core.Context) { if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作")) return } req := new(batchPointsRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } if len(req.Users) != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "当前仅支持单用户操作,请仅选择1位用户")) return } res := &batchResponse{Details: make([]batchItemResult, 0, len(req.Users))} for _, uid := range req.Users { if err := h.user.AddPoints(ctx.RequestContext(), uid, req.Amount, "manual", req.Reason, nil, nil); err != nil { res.Failed++ res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "failed", Message: err.Error()}) } else { res.Success++ res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "success"}) } } ctx.Payload(res) } } func (h *handler) BatchAddUserCoupons() core.HandlerFunc { return func(ctx core.Context) { if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作")) return } req := new(batchCouponsRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } if len(req.Users) != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "当前仅支持单用户操作,请仅选择1位用户")) return } if req.QuantityPerUser <= 0 { req.QuantityPerUser = 1 } if req.QuantityPerUser > 5 { req.QuantityPerUser = 5 } res := &batchResponse{Details: make([]batchItemResult, 0, len(req.Users))} for _, uid := range req.Users { ok := true for i := 0; i < req.QuantityPerUser; i++ { if err := h.user.AddCoupon(ctx.RequestContext(), uid, req.CouponID); err != nil { ok = false } } if ok { res.Success++ res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "success"}) } else { res.Failed++ res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "failed"}) } } ctx.Payload(res) } } func (h *handler) BatchGrantUserRewards() core.HandlerFunc { return func(ctx core.Context) { if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作")) return } req := new(batchRewardsRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } if len(req.Users) != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "当前仅支持单用户操作,请仅选择1位用户")) return } if req.Quantity <= 0 { req.Quantity = 1 } if req.Quantity > 10 { req.Quantity = 10 } res := &batchResponse{Details: make([]batchItemResult, 0, len(req.Users))} r := usersvc.GrantRewardRequest{ProductID: req.ProductID, Quantity: req.Quantity, ActivityID: req.ActivityID, RewardID: req.RewardID, AddressID: req.AddressID, Remark: req.Remark} for _, uid := range req.Users { _, err := h.user.GrantReward(ctx.RequestContext(), uid, r) if err != nil { res.Failed++ res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "failed", Message: err.Error()}) } else { res.Success++ res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "success"}) } } ctx.Payload(res) } }