Files
Logan.LiandCursor 8cc2c83f9d feat: 通用授权后台、离线证、Waffo 支付页与仪表盘加强
支持多产品计划展示、LICOFF 离线签发、支付独立配置与调试,以及分析看板;同步更新 README 与集成文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 20:25:46 +08:00

123 lines
3.9 KiB
Go

package analytics
import (
analyticsservice "backend/internal/service/analytics"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// AnalyticsController 数据分析控制器 // Logan.Li
type AnalyticsController struct {
svc *analyticsservice.AnalyticsService
}
// NewAnalyticsController 创建控制器实例 // Logan.Li
func NewAnalyticsController(db *gorm.DB) *AnalyticsController {
return &AnalyticsController{svc: analyticsservice.NewAnalyticsService(db)}
}
// GetDashboardStats 仪表板统计 // Logan.Li
func (ctrl *AnalyticsController) GetDashboardStats(c *gin.Context) {
stats, err := ctrl.svc.GetDashboardStats()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats})
}
// GetExpiringLicenses 即将到期 License // Logan.Li
func (ctrl *AnalyticsController) GetExpiringLicenses(c *gin.Context) {
days, _ := strconv.Atoi(c.DefaultQuery("days", "30"))
licenses, err := ctrl.svc.GetExpiringLicenses(days)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": licenses})
}
// GetRecentActivities 最近活动 // Logan.Li
func (ctrl *AnalyticsController) GetRecentActivities(c *gin.Context) {
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
activities, err := ctrl.svc.GetRecentActivities(limit)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": activities})
}
// GetOnlineStats 在线统计 // Logan.Li
func (ctrl *AnalyticsController) GetOnlineStats(c *gin.Context) {
stats, err := ctrl.svc.GetOnlineStats()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats})
}
// GetRevenueStats 收入统计 // Logan.Li
func (ctrl *AnalyticsController) GetRevenueStats(c *gin.Context) {
stats, err := ctrl.svc.GetRevenueStats()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats})
}
// GetLicenseGrowth License 增长趋势 // Logan.Li
func (ctrl *AnalyticsController) GetLicenseGrowth(c *gin.Context) {
stats, err := ctrl.svc.GetLicenseGrowth()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats})
}
// GetProductDistribution 产品分布 // Logan.Li
func (ctrl *AnalyticsController) GetProductDistribution(c *gin.Context) {
stats, err := ctrl.svc.GetProductDistribution()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats})
}
// GetGeoDistribution 地理分布 // Logan.Li
func (ctrl *AnalyticsController) GetGeoDistribution(c *gin.Context) {
stats, err := ctrl.svc.GetGeoDistribution()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats})
}
// GetPlatformDistribution 客户端形态分布 // Logan.Li
func (ctrl *AnalyticsController) GetPlatformDistribution(c *gin.Context) {
stats, err := ctrl.svc.GetPlatformDistribution()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats})
}
// GetLicenseGrowthDetail 增长明细(累计+新增) // Logan.Li
func (ctrl *AnalyticsController) GetLicenseGrowthDetail(c *gin.Context) {
stats, err := ctrl.svc.GetLicenseGrowthDetail()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats})
}