package handler import ( "crypto/rand" "encoding/hex" "encoding/json" "net/http" "strconv" "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"` Total int `json:"total,omitempty"` Page int `json:"page,omitempty"` PageSize int `json:"page_size,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) { // 获取分页参数 pageStr := r.URL.Query().Get("page") pageSizeStr := r.URL.Query().Get("page_size") page, _ := strconv.Atoi(pageStr) pageSize, _ := strconv.Atoi(pageSizeStr) // 默认值 if page <= 0 { page = 1 } if pageSize <= 0 { pageSize = 10 } if pageSize > 100 { pageSize = 100 } // 获取总数 total, err := h.repo.Count() if err != nil { respondJSON(w, http.StatusInternalServerError, CardKeyResponse{ Success: false, Message: "Failed to count card keys", }) return } // 获取分页数据 cardKeys, err := h.repo.FindAllPaginated(page, pageSize) 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, Total: total, Page: page, PageSize: pageSize, }) } // 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] } // Delete 删除单个卡密 (DELETE /api/cardkeys/delete?id=xxx) func (h *CardKeyHandler) Delete(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodDelete { respondJSON(w, http.StatusMethodNotAllowed, CardKeyResponse{ Success: false, Message: "Method not allowed", }) return } idStr := r.URL.Query().Get("id") id, err := strconv.Atoi(idStr) if err != nil { respondJSON(w, http.StatusBadRequest, CardKeyResponse{ Success: false, Message: "Invalid card key ID", }) return } if err := h.repo.Delete(id); err != nil { respondJSON(w, http.StatusInternalServerError, CardKeyResponse{ Success: false, Message: "Failed to delete card key", }) return } respondJSON(w, http.StatusOK, CardKeyResponse{ Success: true, Message: "Card key deleted successfully", }) } // BatchDeleteRequest 批量删除请求 type BatchDeleteRequest struct { IDs []int `json:"ids"` } // BatchDelete 批量删除卡密 (DELETE /api/cardkeys/batch) func (h *CardKeyHandler) BatchDelete(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodDelete { respondJSON(w, http.StatusMethodNotAllowed, CardKeyResponse{ Success: false, Message: "Method not allowed", }) return } var req BatchDeleteRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { respondJSON(w, http.StatusBadRequest, CardKeyResponse{ Success: false, Message: "Invalid request body", }) return } if len(req.IDs) == 0 { respondJSON(w, http.StatusBadRequest, CardKeyResponse{ Success: false, Message: "No IDs provided", }) return } if err := h.repo.BatchDelete(req.IDs); err != nil { respondJSON(w, http.StatusInternalServerError, CardKeyResponse{ Success: false, Message: "Failed to delete card keys", }) return } respondJSON(w, http.StatusOK, CardKeyResponse{ Success: true, Message: "Card keys deleted successfully", }) } // ToggleActiveRequest 切换激活状态请求 type ToggleActiveRequest struct { ID int `json:"id"` IsActive bool `json:"is_active"` } // ToggleActive 切换卡密激活状态 (POST /api/cardkeys/toggle) func (h *CardKeyHandler) ToggleActive(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 ToggleActiveRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { respondJSON(w, http.StatusBadRequest, CardKeyResponse{ Success: false, Message: "Invalid request body", }) return } if err := h.repo.ToggleActive(req.ID, req.IsActive); err != nil { respondJSON(w, http.StatusInternalServerError, CardKeyResponse{ Success: false, Message: "Failed to toggle card key status", }) return } respondJSON(w, http.StatusOK, CardKeyResponse{ Success: true, Message: "Card key status updated successfully", }) }