package admin import ( "net/http" "strconv" "time" "bindbox-game/internal/code" "bindbox-game/internal/pkg/core" "bindbox-game/internal/pkg/validation" "bindbox-game/internal/repository/mysql/model" ) type simpleMessageResponse struct { Message string `json:"message"` } type createItemCardRequest struct { Name string `json:"name" binding:"required"` Status int32 `json:"status"` CardType int32 `json:"card_type" binding:"required"` ScopeType int32 `json:"scope_type" binding:"required"` ActivityCategoryID int64 `json:"activity_category_id"` ActivityID int64 `json:"activity_id"` IssueID int64 `json:"issue_id"` Price int64 `json:"price" binding:"required"` ValidStartUnix *int64 `json:"valid_start_unix"` ValidEndUnix *int64 `json:"valid_end_unix"` EffectType int32 `json:"effect_type" binding:"required"` RewardMultiplierX1000 int32 `json:"reward_multiplier_x1000"` BoostRateX1000 int32 `json:"boost_rate_x1000"` StackingStrategy int32 `json:"stacking_strategy"` MaxEffectValueX1000 int32 `json:"max_effect_value_x1000"` Remark string `json:"remark"` } type createItemCardResponse struct { ID int64 `json:"id"` Message string `json:"message"` } // CreateSystemItemCard 创建道具卡 // @Summary 创建道具卡 // @Description 管理员创建新的道具卡,支持设置类型、效果、有效期等属性 // @Tags 管理端.运营管理 // @Accept json // @Produce json // @Param RequestBody body createItemCardRequest true "创建道具卡请求参数" // @Success 200 {object} createItemCardResponse // @Failure 400 {object} code.Failure "参数错误" // @Failure 401 {object} code.Failure "未授权" // @Failure 403 {object} code.Failure "无权限,仅超管可操作" // @Failure 500 {object} code.Failure "服务器内部错误" // @Router /api/admin/system_item_cards [post] func (h *handler) CreateSystemItemCard() core.HandlerFunc { return func(ctx core.Context) { req := new(createItemCardRequest) res := new(createItemCardResponse) 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.CreateAdminError, "禁止操作")) return } item := &model.SystemItemCards{ Name: req.Name, Status: func() int32 { if req.Status == 0 { return 1 } return req.Status }(), CardType: req.CardType, ScopeType: req.ScopeType, ActivityCategoryID: req.ActivityCategoryID, ActivityID: req.ActivityID, IssueID: req.IssueID, Price: req.Price, EffectType: req.EffectType, RewardMultiplierX1000: req.RewardMultiplierX1000, BoostRateX1000: req.BoostRateX1000, StackingStrategy: func() int32 { if req.StackingStrategy == 0 { return 1 } return req.StackingStrategy }(), MaxEffectValueX1000: req.MaxEffectValueX1000, Remark: req.Remark, } do := h.writeDB.SystemItemCards.WithContext(ctx.RequestContext()) if req.ValidStartUnix != nil { item.ValidStart = time.Unix(*req.ValidStartUnix, 0) } if req.ValidEndUnix != nil { item.ValidEnd = time.Unix(*req.ValidEndUnix, 0) } else { do = do.Omit(h.writeDB.SystemItemCards.ValidEnd) } if err := do.Create(item); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error())) return } res.ID = item.ID res.Message = "操作成功" ctx.Payload(res) } } type modifyItemCardRequest struct { Name *string `json:"name"` Status *int32 `json:"status"` CardType *int32 `json:"card_type"` ScopeType *int32 `json:"scope_type"` ActivityCategoryID *int64 `json:"activity_category_id"` ActivityID *int64 `json:"activity_id"` IssueID *int64 `json:"issue_id"` Price *int64 `json:"price"` ValidStartUnix *int64 `json:"valid_start_unix"` ValidEndUnix *int64 `json:"valid_end_unix"` EffectType *int32 `json:"effect_type"` RewardMultiplierX1000 *int32 `json:"reward_multiplier_x1000"` BoostRateX1000 *int32 `json:"boost_rate_x1000"` StackingStrategy *int32 `json:"stacking_strategy"` MaxEffectValueX1000 *int32 `json:"max_effect_value_x1000"` Remark *string `json:"remark"` } // ModifySystemItemCard 修改道具卡 // @Summary 修改道具卡 // @Description 管理员修改道具卡信息,支持修改名称、价格、有效期等属性 // @Tags 管理端.运营管理 // @Accept json // @Produce json // @Param item_card_id path integer true "道具卡ID" // @Param RequestBody body modifyItemCardRequest true "修改道具卡请求参数" // @Success 200 {object} simpleMessageResponse // @Failure 400 {object} code.Failure "参数错误" // @Failure 401 {object} code.Failure "未授权" // @Failure 403 {object} code.Failure "无权限,仅超管可操作" // @Failure 500 {object} code.Failure "服务器内部错误" // @Router /api/admin/system_item_cards/{item_card_id} [put] func (h *handler) ModifySystemItemCard() core.HandlerFunc { return func(ctx core.Context) { req := new(modifyItemCardRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } idStr := ctx.Param("item_card_id") id, _ := strconv.ParseInt(idStr, 10, 64) if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作")) return } set := map[string]any{} if req.Name != nil { set["name"] = *req.Name } if req.Status != nil { set["status"] = *req.Status } if req.CardType != nil { set["card_type"] = *req.CardType } if req.ScopeType != nil { set["scope_type"] = *req.ScopeType } if req.ActivityCategoryID != nil { set["activity_category_id"] = *req.ActivityCategoryID } if req.ActivityID != nil { set["activity_id"] = *req.ActivityID } if req.IssueID != nil { set["issue_id"] = *req.IssueID } if req.Price != nil { set["price"] = *req.Price } if req.EffectType != nil { set["effect_type"] = *req.EffectType } if req.RewardMultiplierX1000 != nil { set["reward_multiplier_x1000"] = *req.RewardMultiplierX1000 } if req.BoostRateX1000 != nil { set["boost_rate_x1000"] = *req.BoostRateX1000 } if req.StackingStrategy != nil { set["stacking_strategy"] = *req.StackingStrategy } if req.MaxEffectValueX1000 != nil { set["max_effect_value_x1000"] = *req.MaxEffectValueX1000 } if req.Remark != nil { set["remark"] = *req.Remark } if req.ValidStartUnix != nil { set["valid_start"] = time.Unix(*req.ValidStartUnix, 0) } if req.ValidEndUnix != nil { set["valid_end"] = time.Unix(*req.ValidEndUnix, 0) } if len(set) == 0 { ctx.Payload(simpleMessageResponse{Message: "操作成功"}) return } if _, err := h.writeDB.SystemItemCards.WithContext(ctx.RequestContext()).Where(h.writeDB.SystemItemCards.ID.Eq(id)).Updates(set); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error())) return } ctx.Payload(simpleMessageResponse{Message: "操作成功"}) } } // DeleteSystemItemCard 删除道具卡 // @Summary 删除道具卡 // @Description 管理员删除指定的道具卡 // @Tags 管理端.运营管理 // @Accept json // @Produce json // @Param item_card_id path integer true "道具卡ID" // @Success 200 {object} simpleMessageResponse // @Failure 400 {object} code.Failure "参数错误" // @Failure 401 {object} code.Failure "未授权" // @Failure 403 {object} code.Failure "无权限,仅超管可操作" // @Failure 500 {object} code.Failure "服务器内部错误" // @Router /api/admin/system_item_cards/{item_card_id} [delete] func (h *handler) DeleteSystemItemCard() core.HandlerFunc { return func(ctx core.Context) { idStr := ctx.Param("item_card_id") id, _ := strconv.ParseInt(idStr, 10, 64) if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作")) return } uid := int64(ctx.SessionUserInfo().Id) set := map[string]any{"deleted_at": time.Now(), "deleted_by": uid} if _, err := h.writeDB.SystemItemCards.WithContext(ctx.RequestContext()).Where(h.writeDB.SystemItemCards.ID.Eq(id)).Updates(set); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error())) return } ctx.Payload(simpleMessageResponse{Message: "操作成功"}) } } type listItemCardsRequest struct { Name string `form:"name"` Status int32 `form:"status"` CardType int32 `form:"card_type"` ScopeType int32 `form:"scope_type"` Page int `form:"page"` PageSize int `form:"page_size"` } type itemCardListItem struct { *model.SystemItemCards } type listItemCardsResponse struct { Page int `json:"page"` PageSize int `json:"page_size"` Total int64 `json:"total"` List []itemCardListItem `json:"list"` } // ListSystemItemCards 获取道具卡列表 // @Summary 获取道具卡列表 // @Description 管理员获取道具卡列表,支持按名称、状态、类型等条件筛选 // @Tags 管理端.运营管理 // @Accept json // @Produce json // @Param name query string false "道具卡名称" // @Param status query integer false "状态:1启用 2禁用" // @Param card_type query integer false "道具卡类型:1抽奖卡 2加成卡 3保底卡" // @Param scope_type query integer false "适用范围:1全局 2活动分类 3活动 4期次" // @Param page query integer false "页码,默认1" // @Param page_size query integer false "每页条数,默认10" // @Success 200 {object} listItemCardsResponse // @Failure 400 {object} code.Failure "参数错误" // @Failure 401 {object} code.Failure "未授权" // @Failure 500 {object} code.Failure "服务器内部错误" // @Router /api/admin/system_item_cards [get] func (h *handler) ListSystemItemCards() core.HandlerFunc { return func(ctx core.Context) { req := new(listItemCardsRequest) res := new(listItemCardsResponse) if err := ctx.ShouldBindForm(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } q := h.readDB.SystemItemCards.WithContext(ctx.RequestContext()).ReadDB() if req.Name != "" { q = q.Where(h.readDB.SystemItemCards.Name.Like("%" + req.Name + "%")) } if req.Status != 0 { q = q.Where(h.readDB.SystemItemCards.Status.Eq(req.Status)) } if req.CardType != 0 { q = q.Where(h.readDB.SystemItemCards.CardType.Eq(req.CardType)) } if req.ScopeType != 0 { q = q.Where(h.readDB.SystemItemCards.ScopeType.Eq(req.ScopeType)) } total, err := q.Count() if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ListActivitiesError, err.Error())) return } if req.Page <= 0 { req.Page = 1 } if req.PageSize <= 0 { req.PageSize = 20 } if req.PageSize > 100 { req.PageSize = 100 } rows, err := q.Order(h.readDB.SystemItemCards.ID.Desc()).Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Find() if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ListActivitiesError, err.Error())) return } res.Page = req.Page res.PageSize = req.PageSize res.Total = total res.List = make([]itemCardListItem, len(rows)) for i, r := range rows { res.List[i] = itemCardListItem{SystemItemCards: r} } ctx.Payload(res) } } type assignItemCardRequest struct { CardID int64 `json:"card_id" binding:"required"` Quantity int `json:"quantity"` } // AssignUserItemCard 给用户分配道具卡 // @Summary 给用户分配道具卡 // @Description 管理员给指定用户分配道具卡,可指定数量 // @Tags 管理端.运营管理 // @Accept json // @Produce json // @Param user_id path integer true "用户ID" // @Param RequestBody body assignItemCardRequest true "分配道具卡请求参数" // @Success 200 {object} simpleMessageResponse // @Failure 400 {object} code.Failure "参数错误" // @Failure 401 {object} code.Failure "未授权" // @Failure 403 {object} code.Failure "无权限,仅超管可操作" // @Failure 500 {object} code.Failure "服务器内部错误" // @Router /api/admin/users/{user_id}/item_cards [post] func (h *handler) AssignUserItemCard() core.HandlerFunc { return func(ctx core.Context) { req := new(assignItemCardRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) return } userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID")) return } if ctx.SessionUserInfo().IsSuper != 1 { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作")) return } if err := h.user.AddItemCard(ctx.RequestContext(), userID, req.CardID, req.Quantity); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error())) return } ctx.Payload(simpleMessageResponse{Message: "操作成功"}) } }