Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 25s
feat(admin): 新增工会管理功能 feat(activity): 添加活动管理相关服务 feat(user): 实现用户道具卡和积分管理 feat(guild): 新增工会成员管理功能 fix: 修复数据库连接配置 fix: 修正jwtoken导入路径 fix: 解决端口冲突问题 style: 统一代码格式和注释风格 style: 更新项目常量命名 docs: 添加项目框架和开发规范文档 docs: 更新接口文档注释 chore: 移除无用代码和文件 chore: 更新Makefile和配置文件 chore: 清理日志文件 test: 添加道具卡测试脚本
266 lines
8.2 KiB
Go
266 lines
8.2 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"
|
|
)
|
|
|
|
type createSystemCouponRequest struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Status *int32 `json:"status"`
|
|
CouponType *int32 `json:"coupon_type"`
|
|
DiscountType *int32 `json:"discount_type"`
|
|
DiscountValue *int64 `json:"discount_value"`
|
|
MinAmount *int64 `json:"min_amount"`
|
|
ValidDays *int `json:"valid_days"`
|
|
TotalQuantity *int64 `json:"total_quantity"`
|
|
}
|
|
|
|
type createSystemCouponResponse struct {
|
|
ID int64 `json:"id"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
func (h *handler) CreateSystemCoupon() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
req := new(createSystemCouponRequest)
|
|
res := new(createSystemCouponResponse)
|
|
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
|
|
}
|
|
now := time.Now()
|
|
m := &model.SystemCoupons{
|
|
Name: req.Name,
|
|
ScopeType: getInt32OrDefault(req.CouponType, 1),
|
|
DiscountType: getInt32OrDefault(req.DiscountType, 1),
|
|
DiscountValue: getInt64OrDefault(req.DiscountValue, 0),
|
|
MinSpend: getInt64OrDefault(req.MinAmount, 0),
|
|
Status: getInt32OrDefault(req.Status, 1),
|
|
}
|
|
if req.ValidDays != nil && *req.ValidDays > 0 {
|
|
m.ValidStart = now
|
|
m.ValidEnd = now.Add(time.Duration(*req.ValidDays) * 24 * time.Hour)
|
|
}
|
|
if err := h.writeDB.SystemCoupons.WithContext(ctx.RequestContext()).Create(m); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
|
|
return
|
|
}
|
|
if req.TotalQuantity != nil {
|
|
if _, err := h.writeDB.SystemCoupons.WithContext(ctx.RequestContext()).Where(h.writeDB.SystemCoupons.ID.Eq(m.ID)).Updates(map[string]any{"total_quantity": *req.TotalQuantity}); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
|
|
return
|
|
}
|
|
}
|
|
res.ID = m.ID
|
|
res.Message = "操作成功"
|
|
ctx.Payload(res)
|
|
}
|
|
}
|
|
|
|
type modifySystemCouponRequest struct {
|
|
Name *string `json:"name"`
|
|
Status *int32 `json:"status"`
|
|
CouponType *int32 `json:"coupon_type"`
|
|
DiscountType *int32 `json:"discount_type"`
|
|
DiscountValue *int64 `json:"discount_value"`
|
|
MinAmount *int64 `json:"min_amount"`
|
|
ValidDays *int `json:"valid_days"`
|
|
TotalQuantity *int64 `json:"total_quantity"`
|
|
}
|
|
|
|
func (h *handler) ModifySystemCoupon() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
req := new(modifySystemCouponRequest)
|
|
if err := ctx.ShouldBindJSON(req); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
|
return
|
|
}
|
|
idStr := ctx.Param("coupon_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.CouponType != nil {
|
|
set["scope_type"] = *req.CouponType
|
|
}
|
|
if req.DiscountType != nil {
|
|
set["discount_type"] = *req.DiscountType
|
|
}
|
|
if req.DiscountValue != nil {
|
|
set["discount_value"] = *req.DiscountValue
|
|
}
|
|
if req.MinAmount != nil {
|
|
set["min_spend"] = *req.MinAmount
|
|
}
|
|
if req.ValidDays != nil && *req.ValidDays > 0 {
|
|
now := time.Now()
|
|
set["valid_start"] = now
|
|
set["valid_end"] = now.Add(time.Duration(*req.ValidDays) * 24 * time.Hour)
|
|
}
|
|
if req.TotalQuantity != nil {
|
|
set["total_quantity"] = *req.TotalQuantity
|
|
}
|
|
if len(set) == 0 {
|
|
ctx.Payload(pcSimpleMessage{Message: "操作成功"})
|
|
return
|
|
}
|
|
if _, err := h.writeDB.SystemCoupons.WithContext(ctx.RequestContext()).Where(h.writeDB.SystemCoupons.ID.Eq(id)).Updates(set); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
|
|
return
|
|
}
|
|
ctx.Payload(pcSimpleMessage{Message: "操作成功"})
|
|
}
|
|
}
|
|
|
|
func (h *handler) DeleteSystemCoupon() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
idStr := ctx.Param("coupon_id")
|
|
id, _ := strconv.ParseInt(idStr, 10, 64)
|
|
if ctx.SessionUserInfo().IsSuper != 1 {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
|
|
return
|
|
}
|
|
if _, err := h.writeDB.SystemCoupons.WithContext(ctx.RequestContext()).Where(h.writeDB.SystemCoupons.ID.Eq(id)).Delete(); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
|
|
return
|
|
}
|
|
ctx.Payload(pcSimpleMessage{Message: "操作成功"})
|
|
}
|
|
}
|
|
|
|
type listSystemCouponsRequest struct {
|
|
Name string `form:"name"`
|
|
Status *int32 `form:"status"`
|
|
Page int `form:"page"`
|
|
PageSize int `form:"page_size"`
|
|
}
|
|
|
|
type systemCouponItem struct {
|
|
ID int64 `json:"id"`
|
|
Name string `json:"name"`
|
|
Status int32 `json:"status"`
|
|
CouponType int32 `json:"coupon_type"`
|
|
DiscountType int32 `json:"discount_type"`
|
|
DiscountValue int64 `json:"discount_value"`
|
|
MinAmount int64 `json:"min_amount"`
|
|
MaxDiscount int64 `json:"max_discount"`
|
|
ValidDays int `json:"valid_days"`
|
|
TotalQuantity int64 `json:"total_quantity"`
|
|
UsedQuantity int64 `json:"used_quantity"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
type listSystemCouponsResponse struct {
|
|
Page int `json:"page"`
|
|
PageSize int `json:"page_size"`
|
|
Total int64 `json:"total"`
|
|
List []systemCouponItem `json:"list"`
|
|
}
|
|
|
|
func (h *handler) ListSystemCoupons() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
req := new(listSystemCouponsRequest)
|
|
res := new(listSystemCouponsResponse)
|
|
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.SystemCoupons.WithContext(ctx.RequestContext()).ReadDB()
|
|
if req.Name != "" {
|
|
q = q.Where(h.readDB.SystemCoupons.Name.Like("%" + req.Name + "%"))
|
|
}
|
|
if req.Status != nil {
|
|
q = q.Where(h.readDB.SystemCoupons.Status.Eq(*req.Status))
|
|
}
|
|
total, err := q.Count()
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
type dbRow struct {
|
|
ID int64
|
|
Name string
|
|
Status int32
|
|
ScopeType int32
|
|
DiscountType int32
|
|
DiscountValue int64
|
|
MinSpend int64
|
|
ValidStart time.Time
|
|
ValidEnd time.Time
|
|
CreatedAt time.Time
|
|
TotalQuantity int64
|
|
}
|
|
var rows []dbRow
|
|
if err := q.Order(h.readDB.SystemCoupons.ID.Desc()).Limit(req.PageSize).Offset((req.Page - 1) * req.PageSize).Scan(&rows); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
res.Page = req.Page
|
|
res.PageSize = req.PageSize
|
|
res.Total = total
|
|
res.List = make([]systemCouponItem, len(rows))
|
|
for i, v := range rows {
|
|
validDays := 0
|
|
if !v.ValidStart.IsZero() && !v.ValidEnd.IsZero() {
|
|
diff := v.ValidEnd.Sub(v.ValidStart)
|
|
validDays = int(diff.Hours() / 24)
|
|
}
|
|
// 统计已发放数量(用户持券数)
|
|
usedCnt, _ := h.readDB.UserCoupons.WithContext(ctx.RequestContext()).Where(h.readDB.UserCoupons.CouponID.Eq(v.ID)).Count()
|
|
res.List[i] = systemCouponItem{
|
|
ID: v.ID,
|
|
Name: v.Name,
|
|
Status: v.Status,
|
|
CouponType: v.ScopeType,
|
|
DiscountType: v.DiscountType,
|
|
DiscountValue: v.DiscountValue,
|
|
MinAmount: v.MinSpend,
|
|
MaxDiscount: 0,
|
|
ValidDays: validDays,
|
|
TotalQuantity: v.TotalQuantity,
|
|
UsedQuantity: usedCnt,
|
|
CreatedAt: v.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
}
|
|
}
|
|
ctx.Payload(res)
|
|
}
|
|
}
|
|
|
|
func getInt32OrDefault(v *int32, d int32) int32 {
|
|
if v != nil {
|
|
return *v
|
|
}
|
|
return d
|
|
}
|
|
func getInt64OrDefault(v *int64, d int64) int64 {
|
|
if v != nil {
|
|
return *v
|
|
}
|
|
return d
|
|
}
|