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