package agent import ( "math/rand" "strconv" "time" "verification-platform-backend/internal/database" "verification-platform-backend/internal/model" "verification-platform-backend/pkg/response" "github.com/gin-gonic/gin" ) func SetupAgentRoutes(r *gin.RouterGroup) { r.GET("/stats", handleGetStats) r.GET("/apps", handleGetApps) r.GET("/apps/:id", handleGetAppDetail) r.GET("/cards", handleGetCards) r.POST("/cards/generate", handleGenerateCards) r.GET("/users", handleGetUsers) r.GET("/finance", handleGetFinance) r.GET("/profile", handleGetProfile) r.PUT("/profile", handleUpdateProfile) } func handleGetStats(c *gin.Context) { userID := c.GetUint("user_id") var totalApps int64 database.DB.Model(&model.AgentApplication{}).Where("agent_id = ?", userID).Count(&totalApps) var totalCards int64 database.DB.Model(&model.Card{}).Where("agent_id = ?", userID).Count(&totalCards) var totalUsers int64 var agentApps []model.AgentApplication database.DB.Where("agent_id = ?", userID).Find(&agentApps) appIDs := make([]uint, 0) for _, app := range agentApps { appIDs = append(appIDs, app.ApplicationID) } if len(appIDs) > 0 { database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Count(&totalUsers) } var totalRevenue float64 database.DB.Model(&model.Card{}).Where("agent_id = ?", userID).Select("COALESCE(SUM(price), 0)").Scan(&totalRevenue) today := time.Now().Format("2006-01-02") var todayCards int64 database.DB.Model(&model.Card{}).Where("agent_id = ? AND DATE(created_at) = ?", userID, today).Count(&todayCards) var todayRevenue float64 database.DB.Model(&model.Card{}).Where("agent_id = ? AND DATE(created_at) = ?", userID, today).Select("COALESCE(SUM(price), 0)").Scan(&todayRevenue) response.Success(c, gin.H{ "totalApps": totalApps, "totalCards": totalCards, "totalUsers": totalUsers, "totalRevenue": totalRevenue, "todayCards": todayCards, "todayRevenue": todayRevenue, }) } func handleGetApps(c *gin.Context) { userID := c.GetUint("user_id") var agentApps []model.AgentApplication if err := database.DB.Where("agent_id = ?", userID).Preload("Application").Find(&agentApps).Error; err != nil { response.Error(c, 500, "获取应用列表失败") return } apps := make([]gin.H, 0) for _, aa := range agentApps { if aa.Application.ID > 0 { apps = append(apps, gin.H{ "id": aa.Application.ID, "name": aa.Application.Name, "description": aa.Application.Description, "status": aa.Application.Status, "authorized_at": aa.CreatedAt, }) } } response.Success(c, gin.H{ "apps": apps, }) } func handleGetAppDetail(c *gin.Context) { userID := c.GetUint("user_id") appID := c.Param("id") // 检查代理是否有该应用的授权 var agentApp model.AgentApplication if err := database.DB.Where("agent_id = ? AND application_id = ?", userID, appID).Preload("Application").First(&agentApp).Error; err != nil { response.Error(c, 404, "应用不存在或无权访问") return } // 获取该应用可用的卡类 var cardTypes []model.CardType if err := database.DB.Where("application_id = ?", appID).Find(&cardTypes).Error; err != nil { response.Error(c, 500, "获取卡类列表失败") return } // 获取代理对该应用的卡类权限和价格 var agentCardTypes []model.AgentApplicationCardType database.DB.Where("agent_application_id = ?", agentApp.ID).Find(&agentCardTypes) // 构建卡类列表,包含代理权限信息 cardTypesList := make([]gin.H, 0) for _, ct := range cardTypes { // 查找代理是否有该卡类的权限 var agentPrice float64 var canGenerate bool for _, act := range agentCardTypes { if act.CardTypeID == ct.ID { agentPrice = act.Price canGenerate = act.CanGenerate break } } // 只返回代理有权限的卡类 if canGenerate { cardTypesList = append(cardTypesList, gin.H{ "id": ct.ID, "name": ct.Name, "billing_type": ct.RechargeType, "price": agentPrice, "value": ct.Value, "duration_days": ct.Value, }) } } response.Success(c, gin.H{ "app": gin.H{ "id": agentApp.Application.ID, "name": agentApp.Application.Name, "description": agentApp.Application.Description, "status": agentApp.Application.Status, }, "cardTypes": cardTypesList, }) } func handleGetCards(c *gin.Context) { userID := c.GetUint("user_id") page := c.DefaultQuery("page", "1") pageSize := c.DefaultQuery("page_size", "20") var total int64 database.DB.Model(&model.Card{}).Where("agent_id = ?", userID).Count(&total) var cards []model.Card offset := 0 if pageInt, err := strconv.Atoi(page); err == nil && pageInt > 1 { offset = (pageInt - 1) * 20 } limit := 20 if pageSizeInt, err := strconv.Atoi(pageSize); err == nil && pageSizeInt > 0 { limit = pageSizeInt } database.DB.Where("agent_id = ?", userID).Order("created_at DESC").Limit(limit).Offset(offset).Find(&cards) // 获取关联数据 cardTypeIDs := make([]uint, 0) appIDs := make([]uint, 0) for _, card := range cards { cardTypeIDs = append(cardTypeIDs, card.CardTypeID) appIDs = append(appIDs, card.ApplicationID) } cardTypeMap := make(map[uint]model.CardType) if len(cardTypeIDs) > 0 { var cardTypes []model.CardType database.DB.Where("id IN ?", cardTypeIDs).Find(&cardTypes) for _, ct := range cardTypes { cardTypeMap[ct.ID] = ct } } appMap := make(map[uint]model.Application) if len(appIDs) > 0 { var apps []model.Application database.DB.Where("id IN ?", appIDs).Find(&apps) for _, app := range apps { appMap[app.ID] = app } } // 构建返回数据 cardList := make([]gin.H, 0) for _, card := range cards { ct := cardTypeMap[card.CardTypeID] app := appMap[card.ApplicationID] cardList = append(cardList, gin.H{ "id": card.ID, "code": card.CardKey, "app_name": app.Name, "card_type_name": ct.Name, "status": card.Status, "created_at": card.CreatedAt, "used_at": card.UsedAt, }) } response.Success(c, gin.H{ "cards": cardList, "total": total, }) } func handleGenerateCards(c *gin.Context) { userID := c.GetUint("user_id") var req struct { ApplicationID uint `json:"application_id"` AppID uint `json:"app_id"` // 兼容前端传的app_id CardTypeID uint `json:"card_type_id"` Quantity int `json:"quantity"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } // 兼容 app_id 和 application_id appID := req.ApplicationID if appID == 0 { appID = req.AppID } var agentApp model.AgentApplication if err := database.DB.Where("agent_id = ? AND application_id = ?", userID, appID).First(&agentApp).Error; err != nil { response.Error(c, 403, "无权操作该应用") return } // 检查代理是否有该卡类的生成权限 var agentCardType model.AgentApplicationCardType if err := database.DB.Where("agent_application_id = ? AND card_type_id = ? AND can_generate = ?", agentApp.ID, req.CardTypeID, true).First(&agentCardType).Error; err != nil { response.Error(c, 403, "无权生成该卡类") return } // 获取卡类信息以计算价格 var cardType model.CardType if err := database.DB.First(&cardType, req.CardTypeID).Error; err != nil { response.Error(c, 404, "卡类不存在") return } cards := make([]model.Card, req.Quantity) for i := 0; i < req.Quantity; i++ { cards[i] = model.Card{ ApplicationID: appID, CardTypeID: req.CardTypeID, CardKey: generateCardCode(), CreatorID: userID, AgentID: &userID, Status: "unused", } } if err := database.DB.Create(&cards).Error; err != nil { response.Error(c, 500, "生成卡密失败") return } // 返回生成的卡号 codes := make([]string, req.Quantity) for i, card := range cards { codes[i] = card.CardKey } response.Success(c, gin.H{ "count": req.Quantity, "codes": codes, }) } func generateCardCode() string { const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" b := make([]byte, 16) for i := range b { b[i] = charset[rand.Intn(len(charset))] } return string(b) } func handleGetUsers(c *gin.Context) { userID := c.GetUint("user_id") var agentApps []model.AgentApplication database.DB.Where("agent_id = ?", userID).Find(&agentApps) appIDs := make([]uint, 0) for _, app := range agentApps { appIDs = append(appIDs, app.ApplicationID) } if len(appIDs) == 0 { response.Success(c, gin.H{ "users": []interface{}{}, "total": 0, }) return } page := c.DefaultQuery("page", "1") pageSize := c.DefaultQuery("page_size", "20") var total int64 database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Count(&total) var users []model.AppUser offset := 0 if pageInt, err := strconv.Atoi(page); err == nil && pageInt > 1 { offset = (pageInt - 1) * 20 } limit := 20 if pageSizeInt, err := strconv.Atoi(pageSize); err == nil && pageSizeInt > 0 { limit = pageSizeInt } database.DB.Where("application_id IN ?", appIDs).Order("created_at DESC").Limit(limit).Offset(offset).Find(&users) response.Success(c, gin.H{ "users": users, "total": total, }) } func handleGetFinance(c *gin.Context) { userID := c.GetUint("user_id") var user model.User if err := database.DB.First(&user, userID).Error; err != nil { response.Error(c, 404, "用户不存在") return } var records []model.RechargeRecord database.DB.Where("user_id = ?", userID).Order("created_at DESC").Limit(20).Find(&records) response.Success(c, gin.H{ "balance": user.Balance, "records": records, }) } func handleGetProfile(c *gin.Context) { userID := c.GetUint("user_id") var user model.User if err := database.DB.First(&user, userID).Error; err != nil { response.Error(c, 404, "用户不存在") return } response.Success(c, gin.H{ "id": user.ID, "username": user.Username, "email": user.Email, "avatar": user.Avatar, "balance": user.Balance, "can_create_agent": user.CanCreateAgent, }) } func handleUpdateProfile(c *gin.Context) { userID := c.GetUint("user_id") var req struct { Email string `json:"email"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } var user model.User if err := database.DB.First(&user, userID).Error; err != nil { response.Error(c, 404, "用户不存在") return } if req.Email != "" { user.Email = &req.Email } database.DB.Save(&user) response.Success(c, nil) }