124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"math/rand"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
"xboard-go/internal/database"
|
|
"xboard-go/internal/model"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// AdminGiftCardFetch handles fetching of gift card templates and batch info.
|
|
func AdminGiftCardFetch(c *gin.Context) {
|
|
params := getFetchParams(c)
|
|
id := params["id"]
|
|
if id != "" {
|
|
var template model.GiftCardTemplate
|
|
if err := database.DB.Where("id = ?", id).First(&template).Error; err != nil {
|
|
Fail(c, http.StatusNotFound, "Template not found")
|
|
return
|
|
}
|
|
Success(c, template)
|
|
return
|
|
}
|
|
|
|
var data []model.GiftCardTemplate
|
|
database.DB.Order("sort ASC, id DESC").Find(&data)
|
|
Success(c, data)
|
|
}
|
|
|
|
// AdminGiftCardSave creates or updates a gift card template.
|
|
func AdminGiftCardSave(c *gin.Context) {
|
|
var payload model.GiftCardTemplate
|
|
if err := c.ShouldBindJSON(&payload); err != nil {
|
|
Fail(c, http.StatusBadRequest, "invalid request body")
|
|
return
|
|
}
|
|
|
|
if payload.ID > 0 {
|
|
if err := database.DB.Model(&model.GiftCardTemplate{}).Where("id = ?", payload.ID).Updates(payload).Error; err != nil {
|
|
Fail(c, http.StatusInternalServerError, "failed to update template")
|
|
return
|
|
}
|
|
} else {
|
|
payload.Status = true
|
|
if err := database.DB.Create(&payload).Error; err != nil {
|
|
Fail(c, http.StatusInternalServerError, "failed to create template")
|
|
return
|
|
}
|
|
}
|
|
|
|
Success(c, true)
|
|
}
|
|
|
|
// AdminGiftCardGenerate batches generation of codes for a template.
|
|
func AdminGiftCardGenerate(c *gin.Context) {
|
|
var payload struct {
|
|
TemplateID int `json:"template_id"`
|
|
Count int `json:"count"`
|
|
Prefix string `json:"prefix"`
|
|
ExpiresAt int64 `json:"expires_at"`
|
|
}
|
|
if err := c.ShouldBindJSON(&payload); err != nil || payload.TemplateID <= 0 || payload.Count <= 0 {
|
|
Fail(c, http.StatusBadRequest, "template_id and count are required")
|
|
return
|
|
}
|
|
|
|
batchID := fmt.Sprintf("batch_%d", time.Now().Unix())
|
|
prefix := payload.Prefix
|
|
if prefix == "" {
|
|
prefix = "GC"
|
|
}
|
|
|
|
tx := database.DB.Begin()
|
|
for i := 0; i < payload.Count; i++ {
|
|
code := generateGiftCode(prefix)
|
|
item := model.GiftCardCode{
|
|
TemplateID: payload.TemplateID,
|
|
Code: code,
|
|
BatchID: batchID,
|
|
Status: 0, // Unused
|
|
MaxUsage: 1,
|
|
ExpiresAt: &payload.ExpiresAt,
|
|
}
|
|
if payload.ExpiresAt == 0 {
|
|
item.ExpiresAt = nil
|
|
}
|
|
if err := tx.Create(&item).Error; err != nil {
|
|
tx.Rollback()
|
|
Fail(c, http.StatusInternalServerError, "failed to generate codes")
|
|
return
|
|
}
|
|
}
|
|
tx.Commit()
|
|
|
|
Success(c, gin.H{"batch_id": batchID})
|
|
}
|
|
|
|
func AdminGiftCardDeleteTemplate(c *gin.Context) {
|
|
var payload struct {
|
|
ID int `json:"id"`
|
|
}
|
|
if err := c.ShouldBindJSON(&payload); err != nil || payload.ID <= 0 {
|
|
Fail(c, http.StatusBadRequest, "template id is required")
|
|
return
|
|
}
|
|
if err := database.DB.Delete(&model.GiftCardTemplate{}, payload.ID).Error; err != nil {
|
|
Fail(c, http.StatusInternalServerError, "failed to delete template")
|
|
return
|
|
}
|
|
Success(c, true)
|
|
}
|
|
|
|
func generateGiftCode(prefix string) string {
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
hash := md5.Sum([]byte(fmt.Sprintf("%d%d", time.Now().UnixNano(), r.Int63())))
|
|
return prefix + strings.ToUpper(hex.EncodeToString(hash[:])[:12])
|
|
}
|