|
|
package handler |
|
|
|
|
|
import ( |
|
|
"net/http" |
|
|
"strconv" |
|
|
"strings" |
|
|
"time" |
|
|
|
|
|
"github.com/gin-gonic/gin" |
|
|
"zencoder-2api/internal/database" |
|
|
"zencoder-2api/internal/model" |
|
|
"zencoder-2api/internal/service" |
|
|
) |
|
|
|
|
|
type TokenHandler struct{} |
|
|
|
|
|
func NewTokenHandler() *TokenHandler { |
|
|
return &TokenHandler{} |
|
|
} |
|
|
|
|
|
|
|
|
func (h *TokenHandler) ListTokenRecords(c *gin.Context) { |
|
|
records, err := service.GetAllTokenRecords() |
|
|
if err != nil { |
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
|
|
|
var enrichedRecords []map[string]interface{} |
|
|
for _, record := range records { |
|
|
|
|
|
var taskStats struct { |
|
|
TotalTasks int64 `json:"total_tasks"` |
|
|
TotalSuccess int64 `json:"total_success"` |
|
|
TotalFail int64 `json:"total_fail"` |
|
|
RunningTasks int64 `json:"running_tasks"` |
|
|
} |
|
|
|
|
|
db := database.GetDB() |
|
|
db.Model(&model.GenerationTask{}).Where("token_record_id = ?", record.ID).Count(&taskStats.TotalTasks) |
|
|
db.Model(&model.GenerationTask{}).Where("token_record_id = ?", record.ID). |
|
|
Select("COALESCE(SUM(success_count), 0)").Scan(&taskStats.TotalSuccess) |
|
|
db.Model(&model.GenerationTask{}).Where("token_record_id = ?", record.ID). |
|
|
Select("COALESCE(SUM(fail_count), 0)").Scan(&taskStats.TotalFail) |
|
|
db.Model(&model.GenerationTask{}).Where("token_record_id = ? AND status = ?", record.ID, "running"). |
|
|
Count(&taskStats.RunningTasks) |
|
|
|
|
|
|
|
|
var email string |
|
|
var planType string |
|
|
var subscriptionStartDate time.Time |
|
|
if record.Token != "" { |
|
|
if payload, err := service.ParseJWT(record.Token); err == nil { |
|
|
email = payload.Email |
|
|
planType = payload.CustomClaims.Plan |
|
|
if planType != "" { |
|
|
planType = strings.ToUpper(planType[:1]) + planType[1:] |
|
|
} |
|
|
|
|
|
subscriptionStartDate = service.GetSubscriptionDate(payload) |
|
|
} |
|
|
} |
|
|
|
|
|
enrichedRecord := map[string]interface{}{ |
|
|
"id": record.ID, |
|
|
"description": record.Description, |
|
|
"generated_count": record.GeneratedCount, |
|
|
"last_generated_at": record.LastGeneratedAt, |
|
|
"auto_generate": record.AutoGenerate, |
|
|
"threshold": record.Threshold, |
|
|
"generate_batch": record.GenerateBatch, |
|
|
"is_active": record.IsActive, |
|
|
"created_at": record.CreatedAt, |
|
|
"updated_at": record.UpdatedAt, |
|
|
"token_expiry": record.TokenExpiry, |
|
|
"status": record.Status, |
|
|
"ban_reason": record.BanReason, |
|
|
"email": email, |
|
|
"plan_type": planType, |
|
|
"subscription_start_date": subscriptionStartDate, |
|
|
"has_refresh_token": record.RefreshToken != "", |
|
|
"total_tasks": taskStats.TotalTasks, |
|
|
"total_success": taskStats.TotalSuccess, |
|
|
"total_fail": taskStats.TotalFail, |
|
|
"running_tasks": taskStats.RunningTasks, |
|
|
} |
|
|
enrichedRecords = append(enrichedRecords, enrichedRecord) |
|
|
} |
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{ |
|
|
"items": enrichedRecords, |
|
|
"total": len(enrichedRecords), |
|
|
}) |
|
|
} |
|
|
|
|
|
|
|
|
func (h *TokenHandler) UpdateTokenRecord(c *gin.Context) { |
|
|
id := c.Param("id") |
|
|
tokenID, err := strconv.ParseUint(id, 10, 32) |
|
|
if err != nil { |
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"}) |
|
|
return |
|
|
} |
|
|
|
|
|
var req struct { |
|
|
AutoGenerate *bool `json:"auto_generate"` |
|
|
Threshold *int `json:"threshold"` |
|
|
GenerateBatch *int `json:"generate_batch"` |
|
|
IsActive *bool `json:"is_active"` |
|
|
Description string `json:"description"` |
|
|
} |
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil { |
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
updates := make(map[string]interface{}) |
|
|
if req.AutoGenerate != nil { |
|
|
updates["auto_generate"] = *req.AutoGenerate |
|
|
} |
|
|
if req.Threshold != nil { |
|
|
updates["threshold"] = *req.Threshold |
|
|
} |
|
|
if req.GenerateBatch != nil { |
|
|
updates["generate_batch"] = *req.GenerateBatch |
|
|
} |
|
|
if req.IsActive != nil { |
|
|
updates["is_active"] = *req.IsActive |
|
|
} |
|
|
if req.Description != "" { |
|
|
updates["description"] = req.Description |
|
|
} |
|
|
|
|
|
if err := service.UpdateTokenRecord(uint(tokenID), updates); err != nil { |
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "updated"}) |
|
|
} |
|
|
|
|
|
|
|
|
func (h *TokenHandler) GetGenerationTasks(c *gin.Context) { |
|
|
tokenRecordID := c.Query("token_record_id") |
|
|
var tokenID uint |
|
|
if tokenRecordID != "" { |
|
|
id, err := strconv.ParseUint(tokenRecordID, 10, 32) |
|
|
if err != nil { |
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid token_record_id"}) |
|
|
return |
|
|
} |
|
|
tokenID = uint(id) |
|
|
} |
|
|
|
|
|
tasks, err := service.GetGenerationTasks(tokenID) |
|
|
if err != nil { |
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{ |
|
|
"items": tasks, |
|
|
"total": len(tasks), |
|
|
}) |
|
|
} |
|
|
|
|
|
|
|
|
func (h *TokenHandler) TriggerGeneration(c *gin.Context) { |
|
|
id := c.Param("id") |
|
|
tokenID, err := strconv.ParseUint(id, 10, 32) |
|
|
if err != nil { |
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"}) |
|
|
return |
|
|
} |
|
|
|
|
|
if err := service.ManualTriggerGeneration(uint(tokenID)); err != nil { |
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "生成任务已触发"}) |
|
|
} |
|
|
|
|
|
|
|
|
func (h *TokenHandler) GetPoolStatus(c *gin.Context) { |
|
|
db := database.GetDB() |
|
|
|
|
|
var stats struct { |
|
|
TotalAccounts int64 `json:"total_accounts"` |
|
|
NormalAccounts int64 `json:"normal_accounts"` |
|
|
CoolingAccounts int64 `json:"cooling_accounts"` |
|
|
BannedAccounts int64 `json:"banned_accounts"` |
|
|
ErrorAccounts int64 `json:"error_accounts"` |
|
|
DisabledAccounts int64 `json:"disabled_accounts"` |
|
|
ActiveTokens int64 `json:"active_tokens"` |
|
|
RunningTasks int64 `json:"running_tasks"` |
|
|
} |
|
|
|
|
|
|
|
|
db.Model(&model.Account{}).Count(&stats.TotalAccounts) |
|
|
db.Model(&model.Account{}).Where("status = ?", "normal").Count(&stats.NormalAccounts) |
|
|
db.Model(&model.Account{}).Where("status = ?", "cooling").Count(&stats.CoolingAccounts) |
|
|
db.Model(&model.Account{}).Where("status = ?", "banned").Count(&stats.BannedAccounts) |
|
|
db.Model(&model.Account{}).Where("status = ?", "error").Count(&stats.ErrorAccounts) |
|
|
db.Model(&model.Account{}).Where("status = ?", "disabled").Count(&stats.DisabledAccounts) |
|
|
|
|
|
|
|
|
db.Model(&model.TokenRecord{}).Where("is_active = ?", true).Count(&stats.ActiveTokens) |
|
|
|
|
|
|
|
|
db.Model(&model.GenerationTask{}).Where("status = ?", "running").Count(&stats.RunningTasks) |
|
|
|
|
|
c.JSON(http.StatusOK, stats) |
|
|
} |
|
|
|
|
|
|
|
|
func (h *TokenHandler) DeleteTokenRecord(c *gin.Context) { |
|
|
id := c.Param("id") |
|
|
tokenID, err := strconv.ParseUint(id, 10, 32) |
|
|
if err != nil { |
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"}) |
|
|
return |
|
|
} |
|
|
|
|
|
|
|
|
db := database.GetDB() |
|
|
tx := db.Begin() |
|
|
|
|
|
|
|
|
if err := tx.Where("token_record_id = ?", tokenID).Delete(&model.GenerationTask{}).Error; err != nil { |
|
|
tx.Rollback() |
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "删除关联任务失败: " + err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
|
|
|
if err := tx.Delete(&model.TokenRecord{}, tokenID).Error; err != nil { |
|
|
tx.Rollback() |
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "删除token记录失败: " + err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
|
|
|
if err := tx.Commit().Error; err != nil { |
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "提交事务失败: " + err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "token及其所有历史记录已删除"}) |
|
|
} |
|
|
|
|
|
|
|
|
func (h *TokenHandler) RefreshTokenRecord(c *gin.Context) { |
|
|
id := c.Param("id") |
|
|
tokenID, err := strconv.ParseUint(id, 10, 32) |
|
|
if err != nil { |
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"}) |
|
|
return |
|
|
} |
|
|
|
|
|
|
|
|
if err := service.RefreshTokenAndAccounts(uint(tokenID)); err != nil { |
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) |
|
|
return |
|
|
} |
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "Token刷新成功,相关账号刷新已启动"}) |
|
|
} |