Files
ai_dianshang/server/internal/handler/admin_stats.go

558 lines
16 KiB
Go
Raw Permalink Normal View History

2025-11-17 14:11:46 +08:00
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)
}