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