Initial commit: 网络验证平台
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
package developer
|
||||
|
||||
import (
|
||||
"time"
|
||||
"verification-platform-backend/internal/database"
|
||||
"verification-platform-backend/internal/model"
|
||||
"verification-platform-backend/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func SetupDashboardRoutes(r *gin.RouterGroup) {
|
||||
r.GET("/dashboard", handleGetDashboard)
|
||||
}
|
||||
|
||||
func handleGetDashboard(c *gin.Context) {
|
||||
userID := c.GetUint("user_id")
|
||||
|
||||
var stats struct {
|
||||
TotalApplications int64 `json:"totalApplications"`
|
||||
TotalUsers int64 `json:"totalUsers"`
|
||||
TotalCards int64 `json:"totalCards"`
|
||||
MonthlyRevenue float64 `json:"monthlyRevenue"`
|
||||
}
|
||||
|
||||
database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Count(&stats.TotalApplications)
|
||||
|
||||
var appIDs []uint
|
||||
database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Pluck("id", &appIDs)
|
||||
if len(appIDs) > 0 {
|
||||
database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Count(&stats.TotalUsers)
|
||||
}
|
||||
|
||||
database.DB.Model(&model.Card{}).Where("creator_id = ?", userID).Count(&stats.TotalCards)
|
||||
|
||||
var monthlyRevenue float64
|
||||
if len(appIDs) > 0 {
|
||||
var appUserIDs []uint
|
||||
database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Pluck("id", &appUserIDs)
|
||||
if len(appUserIDs) > 0 {
|
||||
database.DB.Model(&model.RechargeRecord{}).
|
||||
Where("user_id IN ? AND status = ? AND created_at >= ?", appUserIDs, "success", time.Now().AddDate(0, -1, 0)).
|
||||
Select("COALESCE(SUM(amount), 0)").
|
||||
Scan(&monthlyRevenue)
|
||||
}
|
||||
}
|
||||
stats.MonthlyRevenue = monthlyRevenue
|
||||
|
||||
var subscription struct {
|
||||
Plan string `json:"plan"`
|
||||
Status string `json:"status"`
|
||||
ExpireDate string `json:"expireDate"`
|
||||
APIQuota int `json:"apiQuota"`
|
||||
APIUsed int `json:"apiUsed"`
|
||||
AppCount int `json:"appCount"`
|
||||
CanCreateAgent bool `json:"canCreateAgent"`
|
||||
StorageQuota int64 `json:"storageQuota"`
|
||||
StorageUsed int64 `json:"storageUsed"`
|
||||
}
|
||||
|
||||
var user model.User
|
||||
if err := database.DB.First(&user, userID).Error; err == nil {
|
||||
subscription.Plan = "基础版"
|
||||
if user.Role == "admin" {
|
||||
subscription.Plan = "管理员"
|
||||
}
|
||||
subscription.Status = "正常"
|
||||
if user.Status == "banned" {
|
||||
subscription.Status = "已禁用"
|
||||
}
|
||||
subscription.ExpireDate = "永久"
|
||||
}
|
||||
subscription.AppCount = int(stats.TotalApplications)
|
||||
subscription.APIQuota = 10000
|
||||
subscription.StorageQuota = 100 * 1024 * 1024
|
||||
|
||||
var apiUsed int64
|
||||
database.DB.Model(&model.ApiUsage{}).Where("user_id = ?", userID).Count(&apiUsed)
|
||||
subscription.APIUsed = int(apiUsed)
|
||||
|
||||
var storageUsed int64
|
||||
database.DB.Model(&model.StorageUsage{}).Where("user_id = ?", userID).Select("COALESCE(SUM(size), 0)").Scan(&storageUsed)
|
||||
subscription.StorageUsed = storageUsed
|
||||
|
||||
userDistribution := gin.H{
|
||||
"provinces": []gin.H{},
|
||||
"overseas": []gin.H{},
|
||||
}
|
||||
|
||||
if len(appIDs) > 0 {
|
||||
type DeviceCount struct {
|
||||
DeviceType string
|
||||
Count int
|
||||
}
|
||||
var deviceCounts []DeviceCount
|
||||
database.DB.Model(&model.UserDevice{}).
|
||||
Select("device_type, COUNT(*) as count").
|
||||
Where("application_id IN ?", appIDs).
|
||||
Group("device_type").
|
||||
Order("count DESC").
|
||||
Find(&deviceCounts)
|
||||
|
||||
provinces := make([]gin.H, 0, len(deviceCounts))
|
||||
for _, dc := range deviceCounts {
|
||||
provinces = append(provinces, gin.H{
|
||||
"name": dc.DeviceType,
|
||||
"count": dc.Count,
|
||||
})
|
||||
}
|
||||
userDistribution["provinces"] = provinces
|
||||
}
|
||||
|
||||
onlineTrend := make([]gin.H, 0, 30)
|
||||
for i := 29; i >= 0; i-- {
|
||||
date := time.Now().AddDate(0, 0, -i)
|
||||
dateStart := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
|
||||
dateEnd := dateStart.Add(24 * time.Hour)
|
||||
|
||||
var count int64
|
||||
if len(appIDs) > 0 {
|
||||
database.DB.Model(&model.DeviceSession{}).
|
||||
Joins("JOIN user_devices ON device_sessions.device_id = user_devices.id").
|
||||
Where("user_devices.application_id IN ? AND device_sessions.last_heartbeat >= ? AND device_sessions.last_heartbeat < ?", appIDs, dateStart, dateEnd).
|
||||
Count(&count)
|
||||
}
|
||||
|
||||
onlineTrend = append(onlineTrend, gin.H{
|
||||
"date": date.Format("01-02"),
|
||||
"value": count,
|
||||
})
|
||||
}
|
||||
|
||||
recentActivities := make([]gin.H, 0, 10)
|
||||
var logs []model.Log
|
||||
database.DB.Where("user_id = ?", userID).Order("created_at DESC").Limit(10).Find(&logs)
|
||||
for _, log := range logs {
|
||||
recentActivities = append(recentActivities, gin.H{
|
||||
"id": log.ID,
|
||||
"action": log.Action,
|
||||
"details": log.Details,
|
||||
"resource": log.Resource,
|
||||
"log_type": log.LogType,
|
||||
"status": log.Status,
|
||||
"created_at": log.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
recentTickets := make([]gin.H, 0, 5)
|
||||
var tickets []model.Ticket
|
||||
database.DB.Where("user_id = ?", userID).Order("created_at DESC").Limit(5).Find(&tickets)
|
||||
for _, ticket := range tickets {
|
||||
recentTickets = append(recentTickets, gin.H{
|
||||
"id": ticket.ID,
|
||||
"title": ticket.Title,
|
||||
"status": ticket.Status,
|
||||
"priority": ticket.Priority,
|
||||
"created_at": ticket.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
response.Success(c, gin.H{
|
||||
"stats": stats,
|
||||
"subscription": subscription,
|
||||
"userDistribution": userDistribution,
|
||||
"onlineTrend": onlineTrend,
|
||||
"recentActivities": recentActivities,
|
||||
"recentTickets": recentTickets,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user