Files
verify/backend/internal/router/developer/agent_apps.go
T

777 lines
21 KiB
Go

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,
})
}