package developer import ( "fmt" "verification-platform-backend/internal/database" "verification-platform-backend/internal/model" "verification-platform-backend/internal/service" "verification-platform-backend/pkg/response" "github.com/gin-gonic/gin" "golang.org/x/crypto/bcrypt" ) func SetupAgentsRoutes(r *gin.RouterGroup) { agents := r.Group("/agents") { agents.GET("", handleGetAgents) agents.GET("/tree", handleGetAgentsTree) agents.POST("", handleCreateAgent) agents.GET("/:id", handleGetAgentDetail) agents.PUT("/:id", handleUpdateAgent) agents.PUT("/:id/status", handleUpdateAgentStatus) agents.DELETE("/:id", handleDeleteAgent) agents.GET("/:id/cards", handleGetAgentCards) agents.PUT("/:id/cards", handleUpdateAgentCards) } } type AgentTreeNode struct { ID uint `json:"id"` Username string `json:"username"` Email string `json:"email"` Avatar string `json:"avatar"` Status string `json:"status"` Role string `json:"role"` ParentAgentID *uint `json:"parent_agent_id"` ParentAgentName string `json:"parent_agent_name"` CreatedAt string `json:"created_at"` LastLoginAt string `json:"last_login_at"` Balance float64 `json:"balance"` Commission float64 `json:"commission"` CanCreateAgent bool `json:"can_create_agent"` CardsCount int `json:"cards_count"` ChildAgentsCount int `json:"child_agents_count"` Children []AgentTreeNode `json:"children,omitempty"` } func handleGetAgents(c *gin.Context) { var users []model.User if err := database.DB.Where("role = ?", "agent"). Preload("ParentAgent"). Order("created_at DESC"). Find(&users).Error; err != nil { response.Error(c, 500, "获取代理列表失败") return } type AgentResponse struct { ID uint `json:"id"` Username string `json:"username"` Email string `json:"email"` Avatar string `json:"avatar"` Status string `json:"status"` Role string `json:"role"` ParentAgentID *uint `json:"parent_agent_id"` ParentAgentName string `json:"parent_agent_name"` CreatedAt string `json:"created_at"` LastLoginAt string `json:"last_login_at"` Balance float64 `json:"balance"` Commission float64 `json:"commission"` CanCreateAgent bool `json:"can_create_agent"` CardsCount int `json:"cards_count"` ChildAgentsCount int `json:"child_agents_count"` } var result []AgentResponse for _, user := range users { var parentAgentName string if user.ParentAgent != nil { parentAgentName = user.ParentAgent.Username } var childAgentsCount int64 database.DB.Model(&model.User{}).Where("parent_agent_id = ?", user.ID).Count(&childAgentsCount) var cardsCount int64 database.DB.Model(&model.Card{}).Where("creator_id = ?", user.ID).Count(&cardsCount) var lastLoginAt string if user.LastLoginAt != nil { lastLoginAt = user.LastLoginAt.Format("2006-01-02 15:04:05") } email := "" if user.Email != nil { email = *user.Email } result = append(result, AgentResponse{ ID: user.ID, Username: user.Username, Email: email, Avatar: user.Avatar, Status: user.Status, Role: user.Role, ParentAgentID: user.ParentAgentID, ParentAgentName: parentAgentName, CreatedAt: user.CreatedAt.Format("2006-01-02 15:04:05"), LastLoginAt: lastLoginAt, Balance: user.Balance, Commission: user.Commission, CanCreateAgent: user.CanCreateAgent, CardsCount: int(cardsCount), ChildAgentsCount: int(childAgentsCount), }) } response.Success(c, gin.H{ "agents": result, "total": len(result), }) } func handleGetAgentsTree(c *gin.Context) { var users []model.User if err := database.DB.Where("role = ?", "agent"). Preload("ParentAgent"). Order("created_at DESC"). Find(&users).Error; err != nil { response.Error(c, 500, "获取代理列表失败") return } userMap := make(map[uint]model.User) for _, user := range users { userMap[user.ID] = user } childrenMap := make(map[uint][]uint) var rootUsers []uint for _, user := range users { if user.ParentAgentID != nil { childrenMap[*user.ParentAgentID] = append(childrenMap[*user.ParentAgentID], user.ID) } else { rootUsers = append(rootUsers, user.ID) } } var buildTree func(userID uint) AgentTreeNode buildTree = func(userID uint) AgentTreeNode { user := userMap[userID] var parentAgentName string if user.ParentAgent != nil { parentAgentName = user.ParentAgent.Username } var cardsCount int64 database.DB.Model(&model.Card{}).Where("creator_id = ?", user.ID).Count(&cardsCount) var childAgentsCount int64 database.DB.Model(&model.User{}).Where("parent_agent_id = ?", user.ID).Count(&childAgentsCount) var lastLoginAt string if user.LastLoginAt != nil { lastLoginAt = user.LastLoginAt.Format("2006-01-02 15:04:05") } email := "" if user.Email != nil { email = *user.Email } node := AgentTreeNode{ ID: user.ID, Username: user.Username, Email: email, Avatar: user.Avatar, Status: user.Status, Role: user.Role, ParentAgentID: user.ParentAgentID, ParentAgentName: parentAgentName, CreatedAt: user.CreatedAt.Format("2006-01-02 15:04:05"), LastLoginAt: lastLoginAt, Balance: user.Balance, Commission: user.Commission, CanCreateAgent: user.CanCreateAgent, CardsCount: int(cardsCount), ChildAgentsCount: int(childAgentsCount), } if childIDs, exists := childrenMap[userID]; exists { for _, childID := range childIDs { node.Children = append(node.Children, buildTree(childID)) } } return node } var tree []AgentTreeNode for _, rootID := range rootUsers { tree = append(tree, buildTree(rootID)) } response.Success(c, gin.H{ "tree": tree, "total": len(users), }) } func handleCreateAgent(c *gin.Context) { var req struct { Username string `json:"username" binding:"required"` Email string `json:"email"` Password string `json:"password" binding:"required"` ParentAgentID *uint `json:"parent_agent_id"` Commission float64 `json:"commission"` CanCreateAgent bool `json:"can_create_agent"` Balance float64 `json:"balance"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } var existingUser model.User if err := database.DB.Where("username = ?", req.Username).First(&existingUser).Error; err == nil { response.Error(c, 400, "用户名已存在") return } if req.Email != "" { if err := database.DB.Where("email = ?", req.Email).First(&existingUser).Error; err == nil { response.Error(c, 400, "邮箱已被使用") return } } if req.ParentAgentID != nil { var parentAgent model.User if err := database.DB.Where("id = ? AND role = ?", *req.ParentAgentID, "agent").First(&parentAgent).Error; err != nil { response.Error(c, 404, "上级代理不存在") return } } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { response.Error(c, 500, "密码加密失败") return } user := model.User{ Username: req.Username, Password: string(hashedPassword), Role: "agent", Status: "active", ParentAgentID: req.ParentAgentID, Commission: req.Commission, CanCreateAgent: req.CanCreateAgent, Balance: req.Balance, } if req.Email != "" { user.Email = &req.Email } if err := database.DB.Create(&user).Error; err != nil { response.Error(c, 500, "创建代理失败") return } service.LogOperation(c, "create", "agent", &user.ID, fmt.Sprintf("创建代理: %s", user.Username), nil) response.Success(c, gin.H{ "id": user.ID, "username": user.Username, }) } func handleGetAgentDetail(c *gin.Context) { agentID := c.Param("id") var user model.User if err := database.DB.Where("id = ? AND role = ?", agentID, "agent"). Preload("ParentAgent"). First(&user).Error; err != nil { response.Error(c, 404, "代理不存在") return } var agentApps []model.AgentApplication database.DB.Where("agent_id = ?", user.ID). Preload("Application"). Find(&agentApps) var childAgents []model.User database.DB.Where("parent_agent_id = ?", user.ID).Find(&childAgents) var cards []model.Card database.DB.Where("creator_id = ?", user.ID). Preload("Application"). Preload("CardType"). Find(&cards) type CardResponse struct { ID uint `json:"id"` CardKey string `json:"card_key"` ApplicationID uint `json:"application_id"` AppName string `json:"app_name"` CardTypeID uint `json:"card_type_id"` CardTypeName string `json:"card_type_name"` Price float64 `json:"price"` Status string `json:"status"` CreatedAt string `json:"created_at"` } var cardsResponse []CardResponse for _, card := range cards { appName := "" if card.Application != nil { appName = card.Application.Name } cardTypeName := "" if card.CardType.ID != 0 { cardTypeName = card.CardType.Name } cardsResponse = append(cardsResponse, CardResponse{ ID: card.ID, CardKey: card.CardKey, ApplicationID: card.ApplicationID, AppName: appName, CardTypeID: card.CardTypeID, CardTypeName: cardTypeName, Price: card.CardType.Price, Status: card.Status, CreatedAt: card.CreatedAt.Format("2006-01-02 15:04:05"), }) } var lastLoginAt string if user.LastLoginAt != nil { lastLoginAt = user.LastLoginAt.Format("2006-01-02 15:04:05") } email := "" if user.Email != nil { email = *user.Email } var parentAgentName string if user.ParentAgent != nil { parentAgentName = user.ParentAgent.Username } response.Success(c, gin.H{ "id": user.ID, "username": user.Username, "email": email, "avatar": user.Avatar, "status": user.Status, "role": user.Role, "parent_agent_id": user.ParentAgentID, "parent_agent_name": parentAgentName, "commission": user.Commission, "can_create_agent": user.CanCreateAgent, "balance": user.Balance, "created_at": user.CreatedAt.Format("2006-01-02 15:04:05"), "last_login_at": lastLoginAt, "cards": cardsResponse, "cards_count": len(cardsResponse), "child_agents_count": len(childAgents), }) } func handleUpdateAgent(c *gin.Context) { agentID := c.Param("id") var user model.User if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil { response.Error(c, 404, "代理不存在") return } var req struct { ParentAgentID *uint `json:"parent_agent_id"` Commission *float64 `json:"commission"` Email *string `json:"email"` Password *string `json:"password"` CanCreateAgent *bool `json:"can_create_agent"` Balance *float64 `json:"balance"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } if req.ParentAgentID != nil { if *req.ParentAgentID == user.ID { response.Error(c, 400, "不能将自己设为上级代理") return } var parentAgent model.User if err := database.DB.Where("id = ? AND role = ?", *req.ParentAgentID, "agent").First(&parentAgent).Error; err != nil { response.Error(c, 404, "上级代理不存在") return } user.ParentAgentID = req.ParentAgentID } if req.Email != nil { user.Email = req.Email } if req.Commission != nil { user.Commission = *req.Commission } if req.Password != nil && *req.Password != "" { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(*req.Password), bcrypt.DefaultCost) if err != nil { response.Error(c, 500, "密码加密失败") return } user.Password = string(hashedPassword) } if req.CanCreateAgent != nil { user.CanCreateAgent = *req.CanCreateAgent } if req.Balance != nil { user.Balance = *req.Balance } if err := database.DB.Save(&user).Error; err != nil { response.Error(c, 500, "更新失败") return } service.LogOperation(c, "update", "agent", &user.ID, fmt.Sprintf("更新代理: %s", user.Username), nil) response.Success(c, gin.H{ "id": user.ID, }) } func handleUpdateAgentStatus(c *gin.Context) { agentID := c.Param("id") var user model.User if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil { response.Error(c, 404, "代理不存在") return } var req struct { Status string `json:"status" binding:"required,oneof=active inactive banned"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } user.Status = req.Status if err := database.DB.Save(&user).Error; err != nil { response.Error(c, 500, "更新状态失败") return } service.LogOperation(c, "update_status", "agent", &user.ID, fmt.Sprintf("更新代理状态: %s -> %s", user.Username, user.Status), nil) response.Success(c, gin.H{ "id": user.ID, "status": user.Status, }) } func handleDeleteAgent(c *gin.Context) { agentID := c.Param("id") var user model.User if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil { response.Error(c, 404, "代理不存在") return } database.DB.Model(&model.User{}).Where("parent_agent_id = ?", user.ID).Update("parent_agent_id", nil) if err := database.DB.Delete(&user).Error; err != nil { response.Error(c, 500, "删除失败") return } service.LogOperation(c, "delete", "agent", &user.ID, fmt.Sprintf("删除代理: %s", user.Username), nil) response.Success(c, gin.H{ "id": user.ID, }) } func handleGetAgentCards(c *gin.Context) { agentID := c.Param("id") var user model.User if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil { response.Error(c, 404, "代理不存在") return } var cards []model.Card database.DB.Where("creator_id = ?", user.ID). Preload("Application"). Preload("CardType"). Order("created_at DESC"). Find(&cards) type CardResponse struct { ID uint `json:"id"` CardKey string `json:"card_key"` ApplicationID uint `json:"application_id"` AppName string `json:"app_name"` CardTypeID uint `json:"card_type_id"` CardTypeName string `json:"card_type_name"` Price float64 `json:"price"` Status string `json:"status"` CreatedAt string `json:"created_at"` } var result []CardResponse for _, card := range cards { appName := "" if card.Application != nil { appName = card.Application.Name } cardTypeName := "" if card.CardType.ID != 0 { cardTypeName = card.CardType.Name } result = append(result, CardResponse{ ID: card.ID, CardKey: card.CardKey, ApplicationID: card.ApplicationID, AppName: appName, CardTypeID: card.CardTypeID, CardTypeName: cardTypeName, Price: card.CardType.Price, Status: card.Status, CreatedAt: card.CreatedAt.Format("2006-01-02 15:04:05"), }) } response.Success(c, gin.H{ "cards": result, "total": len(result), }) } func handleUpdateAgentCards(c *gin.Context) { agentID := c.Param("id") var user model.User if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil { response.Error(c, 404, "代理不存在") return } var req struct { Cards []struct { CardID uint `json:"card_id"` Status string `json:"status"` } `json:"cards"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } for _, cardReq := range req.Cards { database.DB.Model(&model.Card{}). Where("id = ? AND creator_id = ?", cardReq.CardID, user.ID). Update("status", cardReq.Status) } response.Success(c, gin.H{ "message": "更新成功", }) }