Files
SingBox-Gopanel/internal/handler/admin_gift_card_api.go
CN-JS-HuiBai b3435e5ef8
Some checks failed
build / build (api, amd64, linux) (push) Has been cancelled
build / build (api, arm64, linux) (push) Has been cancelled
build / build (api.exe, amd64, windows) (push) Has been cancelled
基本功能已初步完善
2026-04-17 20:41:47 +08:00

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])
}