package developer import ( "fmt" "log" "time" "verification-platform-backend/internal/database" "verification-platform-backend/internal/model" "verification-platform-backend/pkg/response" "github.com/gin-gonic/gin" ) func SetupAgentAppRoutes(r *gin.RouterGroup) { agentApps := r.Group("/agent-apps") { agentApps.GET("", handleGetAgentApps) agentApps.GET("/requests", handleGetAgentRequests) agentApps.POST("/invite", handleInviteAgent) agentApps.PUT("/requests/:id/approve", handleApproveRequest) agentApps.PUT("/requests/:id/reject", handleRejectRequest) agentApps.GET("/:id", handleGetAgentAppDetail) agentApps.PUT("/:id", handleUpdateAgentApp) agentApps.PUT("/:id/card-types", handleUpdateAgentCardTypes) agentApps.DELETE("/:id", handleRemoveAgentApp) } } func SetupAgentAppRoutesWithoutPackage(r *gin.RouterGroup) { agentApps := r.Group("/agent-apps") { agentApps.GET("/my-requests", handleGetMyRequests) agentApps.POST("/request", handleRequestAuthorization) agentApps.DELETE("/requests/:id", handleCancelRequest) } } func checkAgentPermission(userID uint) bool { var user model.User if err := database.DB.First(&user, userID).Error; err != nil { return false } if user.CurrentPackageID == nil { return false } var userPackage model.UserPackage if err := database.DB.Where("user_id = ? AND package_id = ? AND status = ?", userID, user.CurrentPackageID, "active").First(&userPackage).Error; err != nil { return false } if userPackage.ExpiredAt != nil && userPackage.ExpiredAt.Before(time.Now()) { return false } var permission model.PackagePermission if err := database.DB.Where("package_id = ?", user.CurrentPackageID).First(&permission).Error; err != nil { return false } return permission.AllowAgent } func handleGetAgentApps(c *gin.Context) { userID := c.GetUint("user_id") log.Printf("[DEBUG] handleGetAgentApps called for developer %d\n", userID) var myAuthorizations []model.AgentApplication if err := database.DB.Where("developer_id = ?", userID). Preload("CardTypes.CardType"). Find(&myAuthorizations).Error; err != nil { response.Error(c, 500, "获取授权列表失败") return } var receivedAuthorizations []model.AgentApplication if err := database.DB.Where("agent_id = ?", userID). Preload("CardTypes.CardType"). Find(&receivedAuthorizations).Error; err != nil { response.Error(c, 500, "获取授权列表失败") return } log.Printf("[DEBUG] Found %d my authorizations and %d received authorizations for developer %d\n", len(myAuthorizations), len(receivedAuthorizations), userID) var allAgentApps []model.AgentApplication allAgentApps = append(allAgentApps, myAuthorizations...) allAgentApps = append(allAgentApps, receivedAuthorizations...) var agentIDs []uint var developerIDs []uint var applicationIDs []uint for _, aa := range allAgentApps { agentIDs = append(agentIDs, aa.AgentID) developerIDs = append(developerIDs, aa.DeveloperID) applicationIDs = append(applicationIDs, aa.ApplicationID) } var users []model.User if err := database.DB.Where("id IN ?", append(agentIDs, developerIDs...)).Find(&users).Error; err != nil { log.Printf("[ERROR] Failed to query users: %v\n", err) } else { log.Printf("[DEBUG] Found %d users\n", len(users)) } var applications []model.Application if err := database.DB.Where("id IN ?", applicationIDs).Find(&applications).Error; err != nil { log.Printf("[ERROR] Failed to query applications: %v\n", err) } userMap := make(map[uint]model.User) for _, user := range users { userMap[user.ID] = user } applicationMap := make(map[uint]model.Application) for _, app := range applications { applicationMap[app.ID] = app } type CardTypeResponse struct { ID uint `json:"id"` CardTypeID uint `json:"card_type_id"` Name string `json:"name"` CanGenerate bool `json:"can_generate"` } type AgentAppResponse struct { ID uint `json:"id"` AgentID uint `json:"agent_id"` AgentName string `json:"agent_name"` AgentEmail string `json:"agent_email"` ApplicationID uint `json:"application_id"` AppName string `json:"app_name"` Commission float64 `json:"commission"` Discount float64 `json:"discount"` Status string `json:"status"` CardTypes []CardTypeResponse `json:"card_types"` CreatedAt string `json:"created_at"` IsReceived bool `json:"is_received"` } var result []AgentAppResponse for _, aa := range allAgentApps { agentName := "" agentEmail := "" if user, exists := userMap[aa.AgentID]; exists { agentName = user.Username if user.Email != nil { agentEmail = *user.Email } } appName := "" if app, exists := applicationMap[aa.ApplicationID]; exists { appName = app.Name } var cardTypes []CardTypeResponse for _, ct := range aa.CardTypes { cardTypes = append(cardTypes, CardTypeResponse{ ID: ct.ID, CardTypeID: ct.CardTypeID, Name: ct.CardType.Name, CanGenerate: ct.CanGenerate, }) } log.Printf("[DEBUG] Processing AgentApp: ID=%d, AgentID=%d, ApplicationID=%d, CardTypes count=%d, IsReceived=%v\n", aa.ID, aa.AgentID, aa.ApplicationID, len(cardTypes), aa.AgentID == userID) result = append(result, AgentAppResponse{ ID: aa.ID, AgentID: aa.AgentID, AgentName: agentName, AgentEmail: agentEmail, ApplicationID: aa.ApplicationID, AppName: appName, Commission: aa.Commission, Discount: aa.Discount, Status: aa.Status, CardTypes: cardTypes, CreatedAt: aa.CreatedAt.Format("2006-01-02 15:04:05"), IsReceived: aa.AgentID == userID, }) } log.Printf("[DEBUG] Returning %d agent apps for user %d\n", len(result), userID) response.Success(c, gin.H{ "agent_apps": result, "total": len(result), }) } func handleGetAgentRequests(c *gin.Context) { userID := c.GetUint("user_id") requestType := c.Query("type") query := database.DB.Where("developer_id = ?", userID) if requestType == "invite" { query = query.Where("type = ?", "invite") } else if requestType == "request" { query = query.Where("type = ?", "request") } var requests []model.AgentApplicationRequest if err := query. Preload("Agent"). Preload("Application"). Order("created_at DESC"). Find(&requests).Error; err != nil { response.Error(c, 500, "获取申请列表失败") return } type RequestResponse struct { ID uint `json:"id"` AgentID uint `json:"agent_id"` AgentName string `json:"agent_name"` AgentEmail string `json:"agent_email"` DeveloperID uint `json:"developer_id"` ApplicationID uint `json:"application_id"` AppName string `json:"app_name"` Type string `json:"type"` Status string `json:"status"` Message string `json:"message"` RejectReason string `json:"reject_reason"` CreatedAt string `json:"created_at"` } var result []RequestResponse for _, req := range requests { agentName := "" agentEmail := "" if req.Agent.ID != 0 { agentName = req.Agent.Username if req.Agent.Email != nil { agentEmail = *req.Agent.Email } } appName := "" if req.Application.ID != 0 { appName = req.Application.Name } result = append(result, RequestResponse{ ID: req.ID, AgentID: req.AgentID, AgentName: agentName, AgentEmail: agentEmail, DeveloperID: req.DeveloperID, ApplicationID: req.ApplicationID, AppName: appName, Type: req.Type, Status: req.Status, Message: req.Message, RejectReason: req.RejectReason, CreatedAt: req.CreatedAt.Format("2006-01-02 15:04:05"), }) } response.Success(c, gin.H{ "requests": result, "total": len(result), }) } func handleGetMyRequests(c *gin.Context) { userID := c.GetUint("user_id") requestType := c.Query("type") query := database.DB.Where("agent_id = ?", userID) if requestType == "invite" { query = query.Where("type = ?", "invite") } else if requestType == "request" { query = query.Where("type = ?", "request") } var requests []model.AgentApplicationRequest if err := query. Preload("Developer"). Preload("Application"). Order("created_at DESC"). Find(&requests).Error; err != nil { response.Error(c, 500, "获取申请列表失败") return } type RequestResponse struct { ID uint `json:"id"` AgentID uint `json:"agent_id"` DeveloperID uint `json:"developer_id"` DeveloperName string `json:"developer_name"` ApplicationID uint `json:"application_id"` AppName string `json:"app_name"` Type string `json:"type"` Status string `json:"status"` Message string `json:"message"` RejectReason string `json:"reject_reason"` CreatedAt string `json:"created_at"` } var result []RequestResponse for _, req := range requests { developerName := "" if req.Developer.ID != 0 { developerName = req.Developer.Username } appName := "" if req.Application.ID != 0 { appName = req.Application.Name } result = append(result, RequestResponse{ ID: req.ID, AgentID: req.AgentID, DeveloperID: req.DeveloperID, DeveloperName: developerName, ApplicationID: req.ApplicationID, AppName: appName, Type: req.Type, Status: req.Status, Message: req.Message, RejectReason: req.RejectReason, CreatedAt: req.CreatedAt.Format("2006-01-02 15:04:05"), }) } response.Success(c, gin.H{ "requests": result, "total": len(result), }) } func handleInviteAgent(c *gin.Context) { userID := c.GetUint("user_id") if !checkAgentPermission(userID) { response.Error(c, 403, "您的套餐不支持代理功能,请升级套餐") return } var req struct { AgentID uint `json:"agent_id"` ApplicationID uint `json:"application_id"` Message string `json:"message"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } var agent model.User if err := database.DB.First(&agent, req.AgentID).Error; err != nil { response.Error(c, 404, "开发者不存在") return } if agent.Role != "agent" { response.Error(c, 400, "该用户不是代理商") return } var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", req.ApplicationID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var existing model.AgentApplication if err := database.DB.Where("agent_id = ? AND application_id = ?", req.AgentID, req.ApplicationID).First(&existing).Error; err == nil { response.Error(c, 400, "该开发者已获得此应用的授权") return } request := model.AgentApplicationRequest{ AgentID: req.AgentID, DeveloperID: userID, ApplicationID: req.ApplicationID, Type: "invite", Status: "pending", Message: req.Message, } if err := database.DB.Create(&request).Error; err != nil { fmt.Printf("创建邀请错误: %v\n", err) response.Error(c, 500, "创建邀请失败") return } response.Success(c, gin.H{ "id": request.ID, "agent_id": request.AgentID, "agent_name": agent.Username, "app_id": request.ApplicationID, "app_name": app.Name, "type": request.Type, "status": request.Status, }) } func handleRequestAuthorization(c *gin.Context) { userID := c.GetUint("user_id") var req struct { DeveloperID uint `json:"developer_id"` ApplicationID uint `json:"application_id"` Message string `json:"message"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } var developer model.User if err := database.DB.First(&developer, req.DeveloperID).Error; err != nil { response.Error(c, 404, "开发者不存在") return } if developer.Role != "admin" { response.Error(c, 400, "该用户不是管理员") return } var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", req.ApplicationID, req.DeveloperID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var existing model.AgentApplication if err := database.DB.Where("agent_id = ? AND application_id = ?", userID, req.ApplicationID).First(&existing).Error; err == nil { response.Error(c, 400, "您已获得此应用的授权") return } var existingRequest model.AgentApplicationRequest if err := database.DB.Where("agent_id = ? AND developer_id = ? AND application_id = ? AND status = ?", userID, req.DeveloperID, req.ApplicationID, "pending").First(&existingRequest).Error; err == nil { response.Error(c, 400, "您已有待处理的申请") return } request := model.AgentApplicationRequest{ AgentID: userID, DeveloperID: req.DeveloperID, ApplicationID: req.ApplicationID, Type: "request", Status: "pending", Message: req.Message, } if err := database.DB.Create(&request).Error; err != nil { fmt.Printf("创建申请错误: %v\n", err) response.Error(c, 500, "创建申请失败") return } response.Success(c, gin.H{ "id": request.ID, "developer_id": request.DeveloperID, "developer_name": developer.Username, "app_id": request.ApplicationID, "app_name": app.Name, "type": request.Type, "status": request.Status, }) } func handleApproveRequest(c *gin.Context) { userID := c.GetUint("user_id") requestID := c.Param("id") if !checkAgentPermission(userID) { response.Error(c, 403, "您的套餐不支持代理功能,请升级套餐") return } var req model.AgentApplicationRequest if err := database.DB.Where("id = ? AND developer_id = ?", requestID, userID).First(&req).Error; err != nil { response.Error(c, 404, "申请不存在") return } if req.Status != "pending" { response.Error(c, 400, "该申请已处理") return } tx := database.DB.Begin() agentApp := model.AgentApplication{ AgentID: req.AgentID, ApplicationID: req.ApplicationID, DeveloperID: userID, Commission: 0.1, Discount: 1.0, Status: "active", IsReceived: true, } if err := tx.Create(&agentApp).Error; err != nil { tx.Rollback() fmt.Printf("创建授权错误: %v\n", err) response.Error(c, 500, "创建授权失败") return } var cardTypes []model.CardType database.DB.Where("application_id = ? OR application_id IS NULL", req.ApplicationID).Find(&cardTypes) for _, ct := range cardTypes { agentCardType := model.AgentApplicationCardType{ AgentApplicationID: agentApp.ID, CardTypeID: ct.ID, CanGenerate: false, } tx.Create(&agentCardType) } req.Status = "approved" if err := tx.Save(&req).Error; err != nil { tx.Rollback() response.Error(c, 500, "更新申请状态失败") return } tx.Commit() response.Success(c, gin.H{ "id": agentApp.ID, "status": "approved", }) } func handleRejectRequest(c *gin.Context) { userID := c.GetUint("user_id") requestID := c.Param("id") var reqBody struct { RejectReason string `json:"reject_reason"` } if err := c.ShouldBindJSON(&reqBody); err != nil { response.Error(c, 400, "参数错误") return } var req model.AgentApplicationRequest if err := database.DB.Where("id = ? AND developer_id = ?", requestID, userID).First(&req).Error; err != nil { response.Error(c, 404, "申请不存在") return } if req.Status != "pending" { response.Error(c, 400, "该申请已处理") return } req.Status = "rejected" req.RejectReason = reqBody.RejectReason if err := database.DB.Save(&req).Error; err != nil { response.Error(c, 500, "更新申请状态失败") return } response.Success(c, gin.H{ "id": req.ID, "status": "rejected", }) } func handleGetAgentAppDetail(c *gin.Context) { userID := c.GetUint("user_id") agentAppID := c.Param("id") var agentApp model.AgentApplication if err := database.DB.Where("id = ? AND developer_id = ?", agentAppID, userID). Preload("CardTypes.CardType"). First(&agentApp).Error; err != nil { response.Error(c, 404, "授权记录不存在") return } var agent model.User if err := database.DB.Where("id = ?", agentApp.AgentID).First(&agent).Error; err != nil { log.Printf("[ERROR] Failed to query agent: %v\n", err) } var application model.Application if err := database.DB.Where("id = ?", agentApp.ApplicationID).First(&application).Error; err != nil { log.Printf("[ERROR] Failed to query application: %v\n", err) } type CardTypeResponse struct { ID uint `json:"id"` Name string `json:"name"` Price float64 `json:"price"` CanGenerate bool `json:"can_generate"` } type AgentAppDetailResponse struct { ID uint `json:"id"` AgentID uint `json:"agent_id"` AgentName string `json:"agent_name"` AgentEmail string `json:"agent_email"` ApplicationID uint `json:"application_id"` AppName string `json:"app_name"` Commission float64 `json:"commission"` Discount float64 `json:"discount"` Status string `json:"status"` CardTypes []CardTypeResponse `json:"card_types"` CreatedAt string `json:"created_at"` } var cardTypes []CardTypeResponse for _, ct := range agentApp.CardTypes { cardTypes = append(cardTypes, CardTypeResponse{ ID: ct.CardTypeID, Name: ct.CardType.Name, Price: ct.CardType.Price, CanGenerate: ct.CanGenerate, }) } result := AgentAppDetailResponse{ ID: agentApp.ID, AgentID: agentApp.AgentID, AgentName: agent.Username, ApplicationID: agentApp.ApplicationID, AppName: application.Name, Commission: agentApp.Commission, Discount: agentApp.Discount, Status: agentApp.Status, CardTypes: cardTypes, CreatedAt: agentApp.CreatedAt.Format("2006-01-02 15:04:05"), } if agent.Email != nil { result.AgentEmail = *agent.Email } response.Success(c, result) } func handleUpdateAgentApp(c *gin.Context) { userID := c.GetUint("user_id") agentAppID := c.Param("id") var reqBody struct { Commission *float64 `json:"commission"` Discount *float64 `json:"discount"` Status *string `json:"status"` } if err := c.ShouldBindJSON(&reqBody); err != nil { response.Error(c, 400, "参数错误") return } var agentApp model.AgentApplication if err := database.DB.Where("id = ? AND developer_id = ?", agentAppID, userID).First(&agentApp).Error; err != nil { response.Error(c, 404, "授权记录不存在") return } updates := make(map[string]interface{}) if reqBody.Commission != nil { updates["commission"] = *reqBody.Commission } if reqBody.Discount != nil { updates["discount"] = *reqBody.Discount } if reqBody.Status != nil { updates["status"] = *reqBody.Status } if len(updates) > 0 { if err := database.DB.Model(&agentApp).Updates(updates).Error; err != nil { response.Error(c, 500, "更新失败") return } } response.Success(c, gin.H{ "id": agentApp.ID, }) } func handleUpdateAgentCardTypes(c *gin.Context) { userID := c.GetUint("user_id") agentAppID := c.Param("id") var reqBody struct { CardTypes []struct { CardTypeID uint `json:"card_type_id"` CanGenerate bool `json:"can_generate"` } `json:"card_types"` } if err := c.ShouldBindJSON(&reqBody); err != nil { response.Error(c, 400, "参数错误") return } var agentApp model.AgentApplication if err := database.DB.Where("id = ? AND developer_id = ?", agentAppID, userID).First(&agentApp).Error; err != nil { response.Error(c, 404, "授权记录不存在") return } tx := database.DB.Begin() if err := tx.Where("agent_application_id = ?", agentAppID).Delete(&model.AgentApplicationCardType{}).Error; err != nil { tx.Rollback() response.Error(c, 500, "清除旧权限失败") return } for _, ct := range reqBody.CardTypes { agentCardType := model.AgentApplicationCardType{ AgentApplicationID: agentApp.ID, CardTypeID: ct.CardTypeID, CanGenerate: ct.CanGenerate, } if err := tx.Create(&agentCardType).Error; err != nil { tx.Rollback() response.Error(c, 500, "创建权限失败") return } } tx.Commit() response.Success(c, gin.H{ "id": agentApp.ID, }) } func handleRemoveAgentApp(c *gin.Context) { userID := c.GetUint("user_id") agentAppID := c.Param("id") var agentApp model.AgentApplication if err := database.DB.Where("id = ? AND developer_id = ?", agentAppID, userID).First(&agentApp).Error; err != nil { response.Error(c, 404, "授权记录不存在") return } if err := database.DB.Delete(&agentApp).Error; err != nil { response.Error(c, 500, "删除失败") return } response.Success(c, gin.H{ "id": agentApp.ID, }) } func handleCancelRequest(c *gin.Context) { userID := c.GetUint("user_id") requestID := c.Param("id") var req model.AgentApplicationRequest if err := database.DB.Where("id = ? AND agent_id = ? AND status = ?", requestID, userID, "pending").First(&req).Error; err != nil { response.Error(c, 404, "申请不存在或已处理") return } if err := database.DB.Delete(&req).Error; err != nil { response.Error(c, 500, "取消失败") return } response.Success(c, gin.H{ "id": req.ID, }) }