313 lines
9.4 KiB
Go
313 lines
9.4 KiB
Go
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"
|
|
)
|
|
|
|
// ==================== 套餐管理 API ====================
|
|
|
|
type createGamePassPackageRequest struct {
|
|
Name string `json:"name" binding:"required"`
|
|
PassCount int32 `json:"pass_count" binding:"required,min=1"`
|
|
Price int64 `json:"price" binding:"required,min=0"`
|
|
OriginalPrice *int64 `json:"original_price"`
|
|
ActivityID *int64 `json:"activity_id"`
|
|
ValidDays *int32 `json:"valid_days"`
|
|
SortOrder *int32 `json:"sort_order"`
|
|
Status *int32 `json:"status"` // 1=上架 2=下架
|
|
}
|
|
|
|
type createGamePassPackageResponse struct {
|
|
ID int64 `json:"id"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// CreateGamePassPackage 创建次数卡套餐
|
|
// @Summary 创建次数卡套餐
|
|
// @Description 创建可购买的次数卡套餐
|
|
// @Tags 管理端.次数卡套餐
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param RequestBody body createGamePassPackageRequest true "请求参数"
|
|
// @Success 200 {object} createGamePassPackageResponse
|
|
// @Failure 400 {object} code.Failure
|
|
// @Router /api/admin/game-pass-packages [post]
|
|
// @Security LoginVerifyToken
|
|
func (h *handler) CreateGamePassPackage() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
req := new(createGamePassPackageRequest)
|
|
res := new(createGamePassPackageResponse)
|
|
if err := ctx.ShouldBindJSON(req); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
|
return
|
|
}
|
|
|
|
now := time.Now()
|
|
m := &model.GamePassPackages{
|
|
Name: req.Name,
|
|
PassCount: req.PassCount,
|
|
Price: req.Price,
|
|
Status: 1, // 默认上架
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
if req.OriginalPrice != nil {
|
|
m.OriginalPrice = *req.OriginalPrice
|
|
}
|
|
if req.ActivityID != nil && *req.ActivityID > 0 {
|
|
m.ActivityID = *req.ActivityID
|
|
}
|
|
if req.ValidDays != nil {
|
|
m.ValidDays = *req.ValidDays
|
|
}
|
|
if req.SortOrder != nil {
|
|
m.SortOrder = *req.SortOrder
|
|
}
|
|
if req.Status != nil {
|
|
m.Status = *req.Status
|
|
}
|
|
|
|
if err := h.writeDB.GamePassPackages.WithContext(ctx.RequestContext()).Create(m); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
|
|
res.ID = m.ID
|
|
res.Message = "创建成功"
|
|
ctx.Payload(res)
|
|
}
|
|
}
|
|
|
|
type modifyGamePassPackageRequest struct {
|
|
Name *string `json:"name"`
|
|
PassCount *int32 `json:"pass_count"`
|
|
Price *int64 `json:"price"`
|
|
OriginalPrice *int64 `json:"original_price"`
|
|
ActivityID *int64 `json:"activity_id"`
|
|
ValidDays *int32 `json:"valid_days"`
|
|
SortOrder *int32 `json:"sort_order"`
|
|
Status *int32 `json:"status"`
|
|
}
|
|
|
|
// ModifyGamePassPackage 修改次数卡套餐
|
|
// @Summary 修改次数卡套餐
|
|
// @Description 修改次数卡套餐配置
|
|
// @Tags 管理端.次数卡套餐
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param package_id path integer true "套餐ID"
|
|
// @Param RequestBody body modifyGamePassPackageRequest true "请求参数"
|
|
// @Success 200 {object} simpleMessageResponse
|
|
// @Failure 400 {object} code.Failure
|
|
// @Router /api/admin/game-pass-packages/{package_id} [put]
|
|
// @Security LoginVerifyToken
|
|
func (h *handler) ModifyGamePassPackage() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
req := new(modifyGamePassPackageRequest)
|
|
if err := ctx.ShouldBindJSON(req); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
|
return
|
|
}
|
|
idStr := ctx.Param("package_id")
|
|
id, _ := strconv.ParseInt(idStr, 10, 64)
|
|
if id <= 0 {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "套餐ID无效"))
|
|
return
|
|
}
|
|
|
|
set := map[string]any{}
|
|
if req.Name != nil {
|
|
set["name"] = *req.Name
|
|
}
|
|
if req.PassCount != nil {
|
|
set["pass_count"] = *req.PassCount
|
|
}
|
|
if req.Price != nil {
|
|
set["price"] = *req.Price
|
|
}
|
|
if req.OriginalPrice != nil {
|
|
set["original_price"] = *req.OriginalPrice
|
|
}
|
|
if req.ActivityID != nil {
|
|
set["activity_id"] = *req.ActivityID
|
|
}
|
|
if req.ValidDays != nil {
|
|
set["valid_days"] = *req.ValidDays
|
|
}
|
|
if req.SortOrder != nil {
|
|
set["sort_order"] = *req.SortOrder
|
|
}
|
|
if req.Status != nil {
|
|
set["status"] = *req.Status
|
|
}
|
|
if len(set) == 0 {
|
|
ctx.Payload(simpleMessageResponse{Message: "无修改"})
|
|
return
|
|
}
|
|
|
|
if _, err := h.writeDB.GamePassPackages.WithContext(ctx.RequestContext()).
|
|
Where(h.writeDB.GamePassPackages.ID.Eq(id)).Updates(set); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
ctx.Payload(simpleMessageResponse{Message: "修改成功"})
|
|
}
|
|
}
|
|
|
|
// DeleteGamePassPackage 删除次数卡套餐
|
|
// @Summary 删除次数卡套餐
|
|
// @Description 软删除次数卡套餐
|
|
// @Tags 管理端.次数卡套餐
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param package_id path integer true "套餐ID"
|
|
// @Success 200 {object} simpleMessageResponse
|
|
// @Failure 400 {object} code.Failure
|
|
// @Router /api/admin/game-pass-packages/{package_id} [delete]
|
|
// @Security LoginVerifyToken
|
|
func (h *handler) DeleteGamePassPackage() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
idStr := ctx.Param("package_id")
|
|
id, _ := strconv.ParseInt(idStr, 10, 64)
|
|
if id <= 0 {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "套餐ID无效"))
|
|
return
|
|
}
|
|
|
|
if _, err := h.writeDB.GamePassPackages.WithContext(ctx.RequestContext()).
|
|
Where(h.writeDB.GamePassPackages.ID.Eq(id)).Delete(); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
ctx.Payload(simpleMessageResponse{Message: "删除成功"})
|
|
}
|
|
}
|
|
|
|
// ==================== 套餐列表 ====================
|
|
|
|
type listGamePassPackagesRequest struct {
|
|
ActivityID *int64 `form:"activity_id"`
|
|
Status *int32 `form:"status"`
|
|
Page int `form:"page"`
|
|
PageSize int `form:"page_size"`
|
|
}
|
|
|
|
type gamePassPackageItem struct {
|
|
ID int64 `json:"id"`
|
|
Name string `json:"name"`
|
|
PassCount int32 `json:"pass_count"`
|
|
Price int64 `json:"price"`
|
|
OriginalPrice int64 `json:"original_price"`
|
|
ActivityID int64 `json:"activity_id"`
|
|
ActivityName string `json:"activity_name"`
|
|
ValidDays int32 `json:"valid_days"`
|
|
SortOrder int32 `json:"sort_order"`
|
|
Status int32 `json:"status"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
type listGamePassPackagesResponse struct {
|
|
Page int `json:"page"`
|
|
PageSize int `json:"page_size"`
|
|
Total int64 `json:"total"`
|
|
List []gamePassPackageItem `json:"list"`
|
|
}
|
|
|
|
// ListGamePassPackages 次数卡套餐列表
|
|
// @Summary 次数卡套餐列表
|
|
// @Description 查询次数卡套餐列表
|
|
// @Tags 管理端.次数卡套餐
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param activity_id query integer false "活动ID"
|
|
// @Param status query integer false "状态: 1=上架 2=下架"
|
|
// @Param page query integer false "页码"
|
|
// @Param page_size query integer false "每页条数"
|
|
// @Success 200 {object} listGamePassPackagesResponse
|
|
// @Failure 400 {object} code.Failure
|
|
// @Router /api/admin/game-pass-packages [get]
|
|
// @Security LoginVerifyToken
|
|
func (h *handler) ListGamePassPackages() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
req := new(listGamePassPackagesRequest)
|
|
res := new(listGamePassPackagesResponse)
|
|
if err := ctx.ShouldBindForm(req); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
|
return
|
|
}
|
|
if req.Page <= 0 {
|
|
req.Page = 1
|
|
}
|
|
if req.PageSize <= 0 {
|
|
req.PageSize = 20
|
|
}
|
|
|
|
q := h.readDB.GamePassPackages.WithContext(ctx.RequestContext()).ReadDB()
|
|
if req.ActivityID != nil && *req.ActivityID > 0 {
|
|
q = q.Where(h.readDB.GamePassPackages.ActivityID.Eq(*req.ActivityID))
|
|
}
|
|
if req.Status != nil {
|
|
q = q.Where(h.readDB.GamePassPackages.Status.Eq(*req.Status))
|
|
}
|
|
|
|
total, err := q.Count()
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
|
|
packages, err := q.Order(h.readDB.GamePassPackages.SortOrder.Desc(), h.readDB.GamePassPackages.ID.Desc()).
|
|
Limit(req.PageSize).
|
|
Offset((req.Page - 1) * req.PageSize).
|
|
Find()
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
|
|
// 获取活动名称
|
|
activityIDs := make([]int64, 0)
|
|
for _, p := range packages {
|
|
if p.ActivityID > 0 {
|
|
activityIDs = append(activityIDs, p.ActivityID)
|
|
}
|
|
}
|
|
activityMap := make(map[int64]string)
|
|
if len(activityIDs) > 0 {
|
|
activities, _ := h.readDB.Activities.WithContext(ctx.RequestContext()).Where(h.readDB.Activities.ID.In(activityIDs...)).Find()
|
|
for _, a := range activities {
|
|
activityMap[a.ID] = a.Name
|
|
}
|
|
}
|
|
|
|
res.Page = req.Page
|
|
res.PageSize = req.PageSize
|
|
res.Total = total
|
|
res.List = make([]gamePassPackageItem, len(packages))
|
|
for i, p := range packages {
|
|
res.List[i] = gamePassPackageItem{
|
|
ID: p.ID,
|
|
Name: p.Name,
|
|
PassCount: p.PassCount,
|
|
Price: p.Price,
|
|
OriginalPrice: p.OriginalPrice,
|
|
ActivityID: p.ActivityID,
|
|
ActivityName: activityMap[p.ActivityID],
|
|
ValidDays: p.ValidDays,
|
|
SortOrder: p.SortOrder,
|
|
Status: p.Status,
|
|
CreatedAt: p.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
}
|
|
}
|
|
ctx.Payload(res)
|
|
}
|
|
}
|