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{} } // ListTokenRecords 获取所有token记录 func (h *TokenHandler) ListTokenRecords(c *gin.Context) { records, err := service.GetAllTokenRecords() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // 获取每个token的生成任务统计 var enrichedRecords []map[string]interface{} for _, record := range records { // 统计该token的任务信息 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) // 解析JWT获取用户信息 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), }) } // UpdateTokenRecord 更新token记录配置 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"}) } // GetGenerationTasks 获取生成任务历史 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), }) } // TriggerGeneration 手动触发生成 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": "生成任务已触发"}) } // GetPoolStatus 获取号池状态 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) // 统计激活的token 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) } // DeleteTokenRecord 删除token记录 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 } // 删除token记录本身 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及其所有历史记录已删除"}) } // RefreshTokenRecord 刷新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 } // 调用service层的刷新函数 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刷新成功,相关账号刷新已启动"}) }