基本功能复刻完成
All checks were successful
build / build (api, amd64, linux) (push) Successful in -47s
build / build (api, arm64, linux) (push) Successful in -47s
build / build (api.exe, amd64, windows) (push) Successful in -48s

This commit is contained in:
CN-JS-HuiBai
2026-04-17 12:24:00 +08:00
parent 06da23fbbc
commit 981ee4f406
37 changed files with 11737 additions and 770 deletions

View File

@@ -0,0 +1,107 @@
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) {
id := c.Query("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 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])
}