Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(抽奖动态): 修复抽奖动态未渲染问题并优化文案展示 fix(用户概览): 修复用户概览无数据显示问题 feat(新用户列表): 在新用户列表显示称号明细 refactor(待办事项): 移除代办模块并全宽展示实时动态 feat(批量操作): 限制为单用户操作并在批量时提醒 fix(称号分配): 防重复分配称号的改造计划 perf(接口性能): 优化新用户和抽奖动态接口性能 feat(订单漏斗): 优化订单转化漏斗指标计算 docs(测试计划): 完善盲盒运营API核查与闭环测试计划
144 lines
5.2 KiB
Go
144 lines
5.2 KiB
Go
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)
|
||
}
|
||
} |