package controller import ( "errors" "strings" "time" "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/model" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type validatePromoCodeRequest struct { Code string `json:"code"` Amount int `json:"amount"` } type validatePromoCodeResponse struct { Valid bool `json:"valid"` Reason string `json:"reason"` PromoCodeId int `json:"promo_code_id"` BonusAmount int `json:"bonus_amount"` Code string `json:"code"` } func ValidatePromoCode(c *gin.Context) { var req validatePromoCodeRequest if err := c.ShouldBindJSON(&req); err != nil { common.ApiError(c, err) return } code := normalizeUserPromoCode(req.Code) if code == "" { common.ApiErrorMsg(c, "优惠码不能为空") return } promoCode, err := model.GetPromoCodeByCode(code) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { common.ApiSuccess(c, newInvalidPromoCodeResponse(code, "not_found")) return } common.ApiError(c, err) return } if promoCode.Status != 1 { common.ApiSuccess(c, newInvalidPromoCodeResponse(code, "disabled")) return } if promoCode.ExpiresAt != nil && promoCode.ExpiresAt.Before(time.Now()) { common.ApiSuccess(c, newInvalidPromoCodeResponse(code, "expired")) return } if promoCode.MaxUses > 0 && promoCode.UsedCount >= promoCode.MaxUses { common.ApiSuccess(c, newInvalidPromoCodeResponse(code, "max_uses_reached")) return } if req.Amount < promoCode.MinRechargeAmount { common.ApiSuccess(c, newInvalidPromoCodeResponse(code, "below_min_recharge")) return } userId := c.GetInt("id") if _, err := model.GetPromoCodeUsageByCodeAndUser(promoCode.Id, userId); err == nil { common.ApiSuccess(c, newInvalidPromoCodeResponse(code, "already_used")) return } else if !errors.Is(err, gorm.ErrRecordNotFound) { common.ApiError(c, err) return } common.ApiSuccess(c, validatePromoCodeResponse{ Valid: true, Reason: "", PromoCodeId: promoCode.Id, BonusAmount: promoCode.BonusAmount, Code: promoCode.Code, }) } func normalizeUserPromoCode(code string) string { return strings.ToUpper(strings.TrimSpace(code)) } func newInvalidPromoCodeResponse(code string, reason string) validatePromoCodeResponse { return validatePromoCodeResponse{ Valid: false, Reason: reason, Code: code, } }