- 添加用户认证模块 (JWT + 密码管理) - 添加 ChatGPT 账户管理功能 - 添加卡密管理功能 (创建、批量生成、查询) - 添加邀请功能 - 配置数据库迁移和路由系统
214 lines
5.2 KiB
Go
214 lines
5.2 KiB
Go
package handler
|
||
|
||
import (
|
||
"crypto/rand"
|
||
"encoding/hex"
|
||
"encoding/json"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
|
||
"gpt-manager-go/internal/middleware"
|
||
"gpt-manager-go/internal/models"
|
||
"gpt-manager-go/internal/repository"
|
||
)
|
||
|
||
// CardKeyHandler 卡密处理器
|
||
type CardKeyHandler struct {
|
||
repo *repository.CardKeyRepository
|
||
}
|
||
|
||
// NewCardKeyHandler 创建处理器
|
||
func NewCardKeyHandler(repo *repository.CardKeyRepository) *CardKeyHandler {
|
||
return &CardKeyHandler{repo: repo}
|
||
}
|
||
|
||
// CreateCardKeyRequest 创建卡密请求
|
||
type CreateCardKeyRequest struct {
|
||
ValidityDays int `json:"validity_days"` // 有效期天数,默认30
|
||
MaxUses int `json:"max_uses"` // 最大使用次数,默认1
|
||
}
|
||
|
||
// BatchCreateCardKeyRequest 批量创建卡密请求
|
||
type BatchCreateCardKeyRequest struct {
|
||
Count int `json:"count"` // 创建数量
|
||
ValidityDays int `json:"validity_days"` // 有效期天数,默认30
|
||
MaxUses int `json:"max_uses"` // 最大使用次数,默认1
|
||
}
|
||
|
||
// CardKeyResponse 卡密响应
|
||
type CardKeyResponse struct {
|
||
Success bool `json:"success"`
|
||
Message string `json:"message"`
|
||
Data *models.CardKey `json:"data,omitempty"`
|
||
Keys []*models.CardKey `json:"keys,omitempty"`
|
||
}
|
||
|
||
// Handle 处理卡密接口 (GET: 列表, POST: 创建)
|
||
func (h *CardKeyHandler) Handle(w http.ResponseWriter, r *http.Request) {
|
||
switch r.Method {
|
||
case http.MethodGet:
|
||
h.list(w, r)
|
||
case http.MethodPost:
|
||
h.create(w, r)
|
||
default:
|
||
respondJSON(w, http.StatusMethodNotAllowed, CardKeyResponse{
|
||
Success: false,
|
||
Message: "Method not allowed",
|
||
})
|
||
}
|
||
}
|
||
|
||
// create 创建单个卡密
|
||
func (h *CardKeyHandler) create(w http.ResponseWriter, r *http.Request) {
|
||
|
||
var req CreateCardKeyRequest
|
||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||
// 允许空请求体,使用默认值
|
||
req = CreateCardKeyRequest{}
|
||
}
|
||
|
||
// 设置默认值
|
||
if req.ValidityDays <= 0 {
|
||
req.ValidityDays = 30
|
||
}
|
||
if req.MaxUses <= 0 {
|
||
req.MaxUses = 1
|
||
}
|
||
|
||
// 获取当前用户
|
||
claims := middleware.GetUserFromContext(r.Context())
|
||
|
||
// 生成卡密
|
||
cardKey := &models.CardKey{
|
||
Key: generateCardKey(),
|
||
MaxUses: req.MaxUses,
|
||
UsedCount: 0,
|
||
ValidityType: "custom",
|
||
ExpiresAt: time.Now().AddDate(0, 0, req.ValidityDays),
|
||
IsActive: true,
|
||
CreatedByID: claims.UserID,
|
||
CreatedAt: time.Now(),
|
||
}
|
||
|
||
if err := h.repo.Create(cardKey); err != nil {
|
||
respondJSON(w, http.StatusInternalServerError, CardKeyResponse{
|
||
Success: false,
|
||
Message: "Failed to create card key: " + err.Error(),
|
||
})
|
||
return
|
||
}
|
||
|
||
respondJSON(w, http.StatusCreated, CardKeyResponse{
|
||
Success: true,
|
||
Message: "Card key created successfully",
|
||
Data: cardKey,
|
||
})
|
||
}
|
||
|
||
// BatchCreate 批量创建卡密 (POST /api/cardkeys/batch)
|
||
func (h *CardKeyHandler) BatchCreate(w http.ResponseWriter, r *http.Request) {
|
||
if r.Method != http.MethodPost {
|
||
respondJSON(w, http.StatusMethodNotAllowed, CardKeyResponse{
|
||
Success: false,
|
||
Message: "Method not allowed",
|
||
})
|
||
return
|
||
}
|
||
|
||
var req BatchCreateCardKeyRequest
|
||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||
respondJSON(w, http.StatusBadRequest, CardKeyResponse{
|
||
Success: false,
|
||
Message: "Invalid request body",
|
||
})
|
||
return
|
||
}
|
||
|
||
// 验证和设置默认值
|
||
if req.Count <= 0 {
|
||
respondJSON(w, http.StatusBadRequest, CardKeyResponse{
|
||
Success: false,
|
||
Message: "Count must be greater than 0",
|
||
})
|
||
return
|
||
}
|
||
if req.Count > 100 {
|
||
respondJSON(w, http.StatusBadRequest, CardKeyResponse{
|
||
Success: false,
|
||
Message: "Count cannot exceed 100",
|
||
})
|
||
return
|
||
}
|
||
if req.ValidityDays <= 0 {
|
||
req.ValidityDays = 30
|
||
}
|
||
if req.MaxUses <= 0 {
|
||
req.MaxUses = 1
|
||
}
|
||
|
||
// 获取当前用户
|
||
claims := middleware.GetUserFromContext(r.Context())
|
||
|
||
// 批量创建
|
||
var createdKeys []*models.CardKey
|
||
expiresAt := time.Now().AddDate(0, 0, req.ValidityDays)
|
||
|
||
for i := 0; i < req.Count; i++ {
|
||
cardKey := &models.CardKey{
|
||
Key: generateCardKey(),
|
||
MaxUses: req.MaxUses,
|
||
UsedCount: 0,
|
||
ValidityType: "custom",
|
||
ExpiresAt: expiresAt,
|
||
IsActive: true,
|
||
CreatedByID: claims.UserID,
|
||
CreatedAt: time.Now(),
|
||
}
|
||
|
||
if err := h.repo.Create(cardKey); err != nil {
|
||
// 如果创建失败,返回已创建的卡密
|
||
respondJSON(w, http.StatusInternalServerError, CardKeyResponse{
|
||
Success: false,
|
||
Message: "Failed to create some card keys",
|
||
Keys: createdKeys,
|
||
})
|
||
return
|
||
}
|
||
createdKeys = append(createdKeys, cardKey)
|
||
}
|
||
|
||
respondJSON(w, http.StatusCreated, CardKeyResponse{
|
||
Success: true,
|
||
Message: "Card keys created successfully",
|
||
Keys: createdKeys,
|
||
})
|
||
}
|
||
|
||
// list 获取卡密列表
|
||
func (h *CardKeyHandler) list(w http.ResponseWriter, r *http.Request) {
|
||
|
||
cardKeys, err := h.repo.FindAll()
|
||
if err != nil {
|
||
respondJSON(w, http.StatusInternalServerError, CardKeyResponse{
|
||
Success: false,
|
||
Message: "Failed to fetch card keys",
|
||
})
|
||
return
|
||
}
|
||
|
||
respondJSON(w, http.StatusOK, CardKeyResponse{
|
||
Success: true,
|
||
Message: "OK",
|
||
Keys: cardKeys,
|
||
})
|
||
}
|
||
|
||
// generateCardKey 生成卡密格式: XXXX-XXXX-XXXX-XXXX
|
||
func generateCardKey() string {
|
||
bytes := make([]byte, 8)
|
||
rand.Read(bytes)
|
||
hex := strings.ToUpper(hex.EncodeToString(bytes))
|
||
return hex[0:4] + "-" + hex[4:8] + "-" + hex[8:12] + "-" + hex[12:16]
|
||
}
|