e63753a853
- 添加 GET /agent/apps/:id 接口 - 返回代理有权使用的卡类列表及其价格 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
334 lines
8.5 KiB
Go
334 lines
8.5 KiB
Go
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)
|
|
|
|
response.Success(c, gin.H{
|
|
"cards": cards,
|
|
"total": total,
|
|
})
|
|
}
|
|
|
|
func handleGenerateCards(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var req struct {
|
|
ApplicationID uint `json:"application_id"`
|
|
CardTypeID uint `json:"card_type_id"`
|
|
Quantity int `json:"quantity"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
var agentApp model.AgentApplication
|
|
if err := database.DB.Where("agent_id = ? AND application_id = ?", userID, req.ApplicationID).First(&agentApp).Error; err != nil {
|
|
response.Error(c, 403, "无权操作该应用")
|
|
return
|
|
}
|
|
|
|
cards := make([]model.Card, req.Quantity)
|
|
for i := 0; i < req.Quantity; i++ {
|
|
cards[i] = model.Card{
|
|
ApplicationID: req.ApplicationID,
|
|
CardTypeID: req.CardTypeID,
|
|
CardKey: generateCardCode(),
|
|
CreatorID: userID,
|
|
Status: "unused",
|
|
}
|
|
}
|
|
|
|
if err := database.DB.Create(&cards).Error; err != nil {
|
|
response.Error(c, 500, "生成卡密失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{
|
|
"count": req.Quantity,
|
|
})
|
|
}
|
|
|
|
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)
|
|
}
|