558 lines
16 KiB
Go
558 lines
16 KiB
Go
|
|
package handler
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"dianshang/internal/service"
|
|||
|
|
"dianshang/pkg/logger"
|
|||
|
|
"dianshang/pkg/response"
|
|||
|
|
"time"
|
|||
|
|
|
|||
|
|
"github.com/gin-gonic/gin"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// AdminStatsHandler 管理后台数据统计处理器
|
|||
|
|
type AdminStatsHandler struct {
|
|||
|
|
orderService *service.OrderService
|
|||
|
|
userService *service.UserService
|
|||
|
|
productService *service.ProductService
|
|||
|
|
refundService *service.RefundService
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewAdminStatsHandler 创建管理后台数据统计处理器
|
|||
|
|
func NewAdminStatsHandler(orderService *service.OrderService, userService *service.UserService, productService *service.ProductService, refundService *service.RefundService) *AdminStatsHandler {
|
|||
|
|
return &AdminStatsHandler{
|
|||
|
|
orderService: orderService,
|
|||
|
|
userService: userService,
|
|||
|
|
productService: productService,
|
|||
|
|
refundService: refundService,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetDashboardStats 获取仪表盘统计数据
|
|||
|
|
func (h *AdminStatsHandler) GetDashboardStats(c *gin.Context) {
|
|||
|
|
// 获取今日统计
|
|||
|
|
today := time.Now().Format("2006-01-02")
|
|||
|
|
|
|||
|
|
// 获取昨日统计用于对比
|
|||
|
|
yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
|
|||
|
|
|
|||
|
|
// 获取本月统计
|
|||
|
|
thisMonth := time.Now().Format("2006-01")
|
|||
|
|
|
|||
|
|
// 获取上月统计用于对比
|
|||
|
|
lastMonth := time.Now().AddDate(0, -1, 0).Format("2006-01")
|
|||
|
|
|
|||
|
|
// 今日订单统计
|
|||
|
|
todayOrderStats, err := h.orderService.GetOrderStatisticsWithDateRange(today, today)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取今日订单统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 昨日订单统计
|
|||
|
|
yesterdayOrderStats, err := h.orderService.GetOrderStatisticsWithDateRange(yesterday, yesterday)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取昨日订单统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 本月订单统计
|
|||
|
|
thisMonthOrderStats, err := h.orderService.GetOrderStatisticsWithDateRange(thisMonth+"-01", today)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取本月订单统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 上月订单统计
|
|||
|
|
lastMonthStart := time.Now().AddDate(0, -1, 0)
|
|||
|
|
lastMonthEnd := time.Date(lastMonthStart.Year(), lastMonthStart.Month()+1, 0, 0, 0, 0, 0, lastMonthStart.Location())
|
|||
|
|
lastMonthOrderStats, err := h.orderService.GetOrderStatisticsWithDateRange(lastMonth+"-01", lastMonthEnd.Format("2006-01-02"))
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取上月订单统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 今日用户统计
|
|||
|
|
todayUserStats, err := h.userService.GetUserStatistics(today, today)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取今日用户统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 昨日用户统计
|
|||
|
|
yesterdayUserStats, err := h.userService.GetUserStatistics(yesterday, yesterday)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取昨日用户统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 上月用户统计
|
|||
|
|
lastMonthUserStats, err := h.userService.GetUserStatistics(lastMonth+"-01", lastMonthEnd.Format("2006-01-02"))
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取上月用户统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 商品统计
|
|||
|
|
productStats, err := h.productService.GetProductStatistics()
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取商品统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 计算增长率的辅助函数
|
|||
|
|
calculateGrowthRate := func(current, previous interface{}) float64 {
|
|||
|
|
var currentVal, previousVal float64
|
|||
|
|
|
|||
|
|
switch v := current.(type) {
|
|||
|
|
case int64:
|
|||
|
|
currentVal = float64(v)
|
|||
|
|
case float64:
|
|||
|
|
currentVal = v
|
|||
|
|
case int:
|
|||
|
|
currentVal = float64(v)
|
|||
|
|
default:
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
switch v := previous.(type) {
|
|||
|
|
case int64:
|
|||
|
|
previousVal = float64(v)
|
|||
|
|
case float64:
|
|||
|
|
previousVal = v
|
|||
|
|
case int:
|
|||
|
|
previousVal = float64(v)
|
|||
|
|
default:
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if previousVal == 0 {
|
|||
|
|
if currentVal > 0 {
|
|||
|
|
return 100 // 如果之前为0,现在有值,则为100%增长
|
|||
|
|
}
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return ((currentVal - previousVal) / previousVal) * 100
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 计算各项增长率
|
|||
|
|
orderGrowthRate := calculateGrowthRate(todayOrderStats["total_orders"], yesterdayOrderStats["total_orders"])
|
|||
|
|
revenueGrowthRate := calculateGrowthRate(todayOrderStats["total_amount"], yesterdayOrderStats["total_amount"])
|
|||
|
|
userGrowthRate := calculateGrowthRate(todayUserStats["new_users"], yesterdayUserStats["new_users"])
|
|||
|
|
|
|||
|
|
// 月度增长率
|
|||
|
|
monthlyOrderGrowthRate := calculateGrowthRate(thisMonthOrderStats["total_orders"], lastMonthOrderStats["total_orders"])
|
|||
|
|
monthlyRevenueGrowthRate := calculateGrowthRate(thisMonthOrderStats["total_amount"], lastMonthOrderStats["total_amount"])
|
|||
|
|
|
|||
|
|
// 构建响应数据
|
|||
|
|
dashboardStats := gin.H{
|
|||
|
|
"overview": gin.H{
|
|||
|
|
"total_users": gin.H{
|
|||
|
|
"value": todayUserStats["total_users"],
|
|||
|
|
"growth_rate": userGrowthRate,
|
|||
|
|
"trend": getTrend(userGrowthRate),
|
|||
|
|
},
|
|||
|
|
"total_products": gin.H{
|
|||
|
|
"value": productStats["total_products"],
|
|||
|
|
"online": productStats["online_products"],
|
|||
|
|
"offline": productStats["offline_products"],
|
|||
|
|
"low_stock": productStats["low_stock_products"],
|
|||
|
|
},
|
|||
|
|
"total_orders": gin.H{
|
|||
|
|
"value": thisMonthOrderStats["total_orders"],
|
|||
|
|
"growth_rate": monthlyOrderGrowthRate,
|
|||
|
|
"trend": getTrend(monthlyOrderGrowthRate),
|
|||
|
|
},
|
|||
|
|
"total_revenue": gin.H{
|
|||
|
|
"value": thisMonthOrderStats["total_amount"],
|
|||
|
|
"growth_rate": monthlyRevenueGrowthRate,
|
|||
|
|
"trend": getTrend(monthlyRevenueGrowthRate),
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
"today_stats": gin.H{
|
|||
|
|
"orders": gin.H{
|
|||
|
|
"total": todayOrderStats["total_orders"],
|
|||
|
|
"paid": todayOrderStats["paid_orders"],
|
|||
|
|
"amount": todayOrderStats["total_amount"],
|
|||
|
|
"paid_amount": todayOrderStats["paid_amount"],
|
|||
|
|
"growth_rate": orderGrowthRate,
|
|||
|
|
"trend": getTrend(orderGrowthRate),
|
|||
|
|
},
|
|||
|
|
"users": gin.H{
|
|||
|
|
"new_users": todayUserStats["new_users"],
|
|||
|
|
"active_users": todayUserStats["active_users"],
|
|||
|
|
"growth_rate": userGrowthRate,
|
|||
|
|
"trend": getTrend(userGrowthRate),
|
|||
|
|
},
|
|||
|
|
"revenue": gin.H{
|
|||
|
|
"amount": todayOrderStats["total_amount"],
|
|||
|
|
"paid_amount": todayOrderStats["paid_amount"],
|
|||
|
|
"growth_rate": revenueGrowthRate,
|
|||
|
|
"trend": getTrend(revenueGrowthRate),
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
"comparison": gin.H{
|
|||
|
|
"yesterday": gin.H{
|
|||
|
|
"orders": yesterdayOrderStats["total_orders"],
|
|||
|
|
"amount": yesterdayOrderStats["total_amount"],
|
|||
|
|
"new_users": yesterdayUserStats["new_users"],
|
|||
|
|
},
|
|||
|
|
"last_month": gin.H{
|
|||
|
|
"orders": lastMonthOrderStats["total_orders"],
|
|||
|
|
"amount": lastMonthOrderStats["total_amount"],
|
|||
|
|
"new_users": lastMonthUserStats["new_users"],
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
"product_stats": productStats,
|
|||
|
|
"update_time": time.Now().Format("2006-01-02 15:04:05"),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, dashboardStats)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// getTrend 根据增长率获取趋势标识
|
|||
|
|
func getTrend(growthRate float64) string {
|
|||
|
|
if growthRate > 0 {
|
|||
|
|
return "up"
|
|||
|
|
} else if growthRate < 0 {
|
|||
|
|
return "down"
|
|||
|
|
}
|
|||
|
|
return "stable"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetOrderTrend 获取订单趋势
|
|||
|
|
func (h *AdminStatsHandler) GetOrderTrend(c *gin.Context) {
|
|||
|
|
days := c.DefaultQuery("days", "7")
|
|||
|
|
|
|||
|
|
var startDate string
|
|||
|
|
switch days {
|
|||
|
|
case "7":
|
|||
|
|
startDate = time.Now().AddDate(0, 0, -7).Format("2006-01-02")
|
|||
|
|
case "30":
|
|||
|
|
startDate = time.Now().AddDate(0, 0, -30).Format("2006-01-02")
|
|||
|
|
case "90":
|
|||
|
|
startDate = time.Now().AddDate(0, 0, -90).Format("2006-01-02")
|
|||
|
|
default:
|
|||
|
|
startDate = time.Now().AddDate(0, 0, -7).Format("2006-01-02")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
endDate := time.Now().Format("2006-01-02")
|
|||
|
|
|
|||
|
|
trend, err := h.orderService.GetDailyOrderStatisticsWithDateRange(startDate, endDate)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, trend)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetUserTrend 获取用户增长趋势
|
|||
|
|
func (h *AdminStatsHandler) GetUserTrend(c *gin.Context) {
|
|||
|
|
days := c.DefaultQuery("days", "7")
|
|||
|
|
|
|||
|
|
var startDate string
|
|||
|
|
switch days {
|
|||
|
|
case "7":
|
|||
|
|
startDate = time.Now().AddDate(0, 0, -7).Format("2006-01-02")
|
|||
|
|
case "30":
|
|||
|
|
startDate = time.Now().AddDate(0, 0, -30).Format("2006-01-02")
|
|||
|
|
case "90":
|
|||
|
|
startDate = time.Now().AddDate(0, 0, -90).Format("2006-01-02")
|
|||
|
|
default:
|
|||
|
|
startDate = time.Now().AddDate(0, 0, -7).Format("2006-01-02")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
endDate := time.Now().Format("2006-01-02")
|
|||
|
|
|
|||
|
|
trend, err := h.userService.GetDailyUserStatistics(startDate, endDate)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, trend)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetSalesRanking 获取销售排行
|
|||
|
|
func (h *AdminStatsHandler) GetSalesRanking(c *gin.Context) {
|
|||
|
|
rankType := c.DefaultQuery("type", "product") // product, category, user
|
|||
|
|
limit := c.DefaultQuery("limit", "10")
|
|||
|
|
startDate := c.Query("start_date")
|
|||
|
|
endDate := c.Query("end_date")
|
|||
|
|
|
|||
|
|
// 如果没有提供日期,默认查询最近30天
|
|||
|
|
if startDate == "" || endDate == "" {
|
|||
|
|
now := time.Now()
|
|||
|
|
endDate = now.Format("2006-01-02")
|
|||
|
|
startDate = now.AddDate(0, 0, -30).Format("2006-01-02")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var ranking interface{}
|
|||
|
|
var err error
|
|||
|
|
|
|||
|
|
switch rankType {
|
|||
|
|
case "product":
|
|||
|
|
ranking, err = h.productService.GetProductSalesRanking(startDate, endDate, limit)
|
|||
|
|
case "category":
|
|||
|
|
ranking, err = h.productService.GetCategorySalesRanking(startDate, endDate, limit)
|
|||
|
|
case "user":
|
|||
|
|
ranking, err = h.userService.GetUserPurchaseRanking(startDate, endDate, limit)
|
|||
|
|
default:
|
|||
|
|
response.BadRequest(c, "不支持的排行类型")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, ranking)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetRegionStats 获取地区统计
|
|||
|
|
func (h *AdminStatsHandler) GetRegionStats(c *gin.Context) {
|
|||
|
|
startDate := c.Query("start_date")
|
|||
|
|
endDate := c.Query("end_date")
|
|||
|
|
|
|||
|
|
// 如果没有提供日期,默认查询最近30天
|
|||
|
|
if startDate == "" || endDate == "" {
|
|||
|
|
now := time.Now()
|
|||
|
|
endDate = now.Format("2006-01-02")
|
|||
|
|
startDate = now.AddDate(0, 0, -30).Format("2006-01-02")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
regionStats, err := h.orderService.GetRegionStatistics(startDate, endDate)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, regionStats)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetPaymentStats 获取支付方式统计
|
|||
|
|
func (h *AdminStatsHandler) GetPaymentStats(c *gin.Context) {
|
|||
|
|
startDate := c.Query("start_date")
|
|||
|
|
endDate := c.Query("end_date")
|
|||
|
|
|
|||
|
|
// 如果没有提供日期,默认查询最近30天
|
|||
|
|
if startDate == "" || endDate == "" {
|
|||
|
|
now := time.Now()
|
|||
|
|
endDate = now.Format("2006-01-02")
|
|||
|
|
startDate = now.AddDate(0, 0, -30).Format("2006-01-02")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
paymentStats, err := h.orderService.GetPaymentMethodStatistics(startDate, endDate)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, paymentStats)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetRefundStats 获取退款统计
|
|||
|
|
func (h *AdminStatsHandler) GetRefundStats(c *gin.Context) {
|
|||
|
|
startDate := c.Query("start_date")
|
|||
|
|
endDate := c.Query("end_date")
|
|||
|
|
|
|||
|
|
// 如果没有提供日期,默认查询最近30天
|
|||
|
|
if startDate == "" || endDate == "" {
|
|||
|
|
now := time.Now()
|
|||
|
|
endDate = now.Format("2006-01-02")
|
|||
|
|
startDate = now.AddDate(0, 0, -30).Format("2006-01-02")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 解析日期
|
|||
|
|
startTime, err := time.Parse("2006-01-02", startDate)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "开始日期格式错误")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
endTime, err := time.Parse("2006-01-02", endDate)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "结束日期格式错误")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置时间范围到一天的结束
|
|||
|
|
endTime = endTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
|
|||
|
|
|
|||
|
|
// 使用退款服务获取真实统计数据
|
|||
|
|
refundStats, err := h.refundService.GetRefundStatistics(c.Request.Context(), startTime, endTime)
|
|||
|
|
if err != nil {
|
|||
|
|
logger.Error("获取退款统计失败", "error", err)
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取退款统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, refundStats)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetRealTimeStats 获取实时统计
|
|||
|
|
func (h *AdminStatsHandler) GetRealTimeStats(c *gin.Context) {
|
|||
|
|
// 获取今日实时数据
|
|||
|
|
today := time.Now().Format("2006-01-02")
|
|||
|
|
|
|||
|
|
// 今日订单数
|
|||
|
|
todayOrders, err := h.orderService.GetOrderStatisticsWithDateRange(today, today)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取今日订单统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 今日新增用户
|
|||
|
|
todayUsers, err := h.userService.GetUserStatistics(today, today)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取今日用户统计失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 在线用户数(这里简化处理,实际应该从Redis或其他缓存中获取)
|
|||
|
|
onlineUsers := 0
|
|||
|
|
|
|||
|
|
// 待处理订单数
|
|||
|
|
pendingOrders, err := h.orderService.GetPendingOrdersCount()
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, "获取待处理订单数失败")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
realTimeStats := gin.H{
|
|||
|
|
"today_orders": todayOrders["total_orders"],
|
|||
|
|
"today_amount": todayOrders["total_amount"],
|
|||
|
|
"today_new_users": todayUsers["new_users"],
|
|||
|
|
"online_users": onlineUsers,
|
|||
|
|
"pending_orders": pendingOrders,
|
|||
|
|
"update_time": time.Now().Format("2006-01-02 15:04:05"),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, realTimeStats)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetUserGrowthTrend 获取用户增长趋势详细数据
|
|||
|
|
func (h *AdminStatsHandler) GetUserGrowthTrend(c *gin.Context) {
|
|||
|
|
days := c.DefaultQuery("days", "30")
|
|||
|
|
|
|||
|
|
var daysInt int
|
|||
|
|
switch days {
|
|||
|
|
case "7":
|
|||
|
|
daysInt = 7
|
|||
|
|
case "30":
|
|||
|
|
daysInt = 30
|
|||
|
|
case "90":
|
|||
|
|
daysInt = 90
|
|||
|
|
default:
|
|||
|
|
daysInt = 30
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
trend, err := h.userService.GetUserGrowthTrend(daysInt)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, trend)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetUserActivityAnalysis 获取用户活跃度分析
|
|||
|
|
func (h *AdminStatsHandler) GetUserActivityAnalysis(c *gin.Context) {
|
|||
|
|
startDate := c.Query("start_date")
|
|||
|
|
endDate := c.Query("end_date")
|
|||
|
|
|
|||
|
|
// 如果没有提供日期,默认查询最近30天
|
|||
|
|
if startDate == "" || endDate == "" {
|
|||
|
|
now := time.Now()
|
|||
|
|
endDate = now.Format("2006-01-02")
|
|||
|
|
startDate = now.AddDate(0, 0, -30).Format("2006-01-02")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
analysis, err := h.userService.GetUserActivityAnalysis(startDate, endDate)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, analysis)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetUserRetentionRate 获取用户留存率
|
|||
|
|
func (h *AdminStatsHandler) GetUserRetentionRate(c *gin.Context) {
|
|||
|
|
days := c.DefaultQuery("days", "30")
|
|||
|
|
|
|||
|
|
var daysInt int
|
|||
|
|
switch days {
|
|||
|
|
case "7":
|
|||
|
|
daysInt = 7
|
|||
|
|
case "30":
|
|||
|
|
daysInt = 30
|
|||
|
|
case "90":
|
|||
|
|
daysInt = 90
|
|||
|
|
default:
|
|||
|
|
daysInt = 30
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
retention, err := h.userService.GetUserRetentionRate(daysInt)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, retention)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetUserLevelDistribution 获取用户等级分布
|
|||
|
|
func (h *AdminStatsHandler) GetUserLevelDistribution(c *gin.Context) {
|
|||
|
|
distribution, err := h.userService.GetUserLevelDistribution()
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, distribution)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetUserGeographicDistribution 获取用户地域分布
|
|||
|
|
func (h *AdminStatsHandler) GetUserGeographicDistribution(c *gin.Context) {
|
|||
|
|
distribution, err := h.userService.GetUserGeographicDistribution()
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, distribution)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetUserAgeDistribution 获取用户年龄分布
|
|||
|
|
func (h *AdminStatsHandler) GetUserAgeDistribution(c *gin.Context) {
|
|||
|
|
distribution, err := h.userService.GetUserAgeDistribution()
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, distribution)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetUserEngagementMetrics 获取用户参与度指标
|
|||
|
|
func (h *AdminStatsHandler) GetUserEngagementMetrics(c *gin.Context) {
|
|||
|
|
startDate := c.Query("start_date")
|
|||
|
|
endDate := c.Query("end_date")
|
|||
|
|
|
|||
|
|
// 如果没有提供日期,默认查询最近30天
|
|||
|
|
if startDate == "" || endDate == "" {
|
|||
|
|
now := time.Now()
|
|||
|
|
endDate = now.Format("2006-01-02")
|
|||
|
|
startDate = now.AddDate(0, 0, -30).Format("2006-01-02")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
metrics, err := h.userService.GetUserEngagementMetrics(startDate, endDate)
|
|||
|
|
if err != nil {
|
|||
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response.Success(c, metrics)
|
|||
|
|
}
|