feat: 数据分析

This commit is contained in:
Blizzard
2026-03-10 15:12:29 +08:00
parent bdcd96a058
commit e4b7ee04cc
17 changed files with 1315 additions and 17 deletions
+178
View File
@@ -0,0 +1,178 @@
package radio
import (
"sundynix-go/global"
"sundynix-go/model/commom/response"
"sundynix-go/model/radio/request"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AnalyticsApi struct{}
// GetListeningTrend 获取收听趋势
// @Tags 数据分析
// @Summary 获取收听趋势(折线图)
// @Produce application/json
// @Param startDate query string false "开始日期 2026-01-01"
// @Param endDate query string false "结束日期 2026-03-10"
// @Param channelId query string false "频道ID(可选筛选)"
// @Success 200 {object} response.Response
// @Router /radio/analytics/listening-trend [get]
func (a *AnalyticsApi) GetListeningTrend(c *gin.Context) {
var req request.TrendQuery
if err := c.ShouldBindQuery(&req); err != nil {
response.FailWithMsg("参数错误: "+err.Error(), c)
return
}
data, err := analyticsService.GetListeningTrend(req.StartDate, req.EndDate, req.ChannelId)
if err != nil {
global.Logger.Error("获取收听趋势失败!", zap.Error(err))
response.FailWithMsg(err.Error(), c)
return
}
response.OkWithData(data, c)
}
// GetSubscriptionTrend 获取订阅趋势
// @Tags 数据分析
// @Summary 获取订阅趋势(折线图)
// @Produce application/json
// @Param startDate query string false "开始日期"
// @Param endDate query string false "结束日期"
// @Param channelId query string false "频道ID"
// @Success 200 {object} response.Response
// @Router /radio/analytics/subscription-trend [get]
func (a *AnalyticsApi) GetSubscriptionTrend(c *gin.Context) {
var req request.TrendQuery
if err := c.ShouldBindQuery(&req); err != nil {
response.FailWithMsg("参数错误: "+err.Error(), c)
return
}
data, err := analyticsService.GetSubscriptionTrend(req.StartDate, req.EndDate, req.ChannelId)
if err != nil {
global.Logger.Error("获取订阅趋势失败!", zap.Error(err))
response.FailWithMsg(err.Error(), c)
return
}
response.OkWithData(data, c)
}
// GetRenewalTrend 获取续费趋势
// @Tags 数据分析
// @Summary 获取续费趋势(折线图)
// @Produce application/json
// @Param startDate query string false "开始日期"
// @Param endDate query string false "结束日期"
// @Param channelId query string false "频道ID"
// @Success 200 {object} response.Response
// @Router /radio/analytics/renewal-trend [get]
func (a *AnalyticsApi) GetRenewalTrend(c *gin.Context) {
var req request.TrendQuery
if err := c.ShouldBindQuery(&req); err != nil {
response.FailWithMsg("参数错误: "+err.Error(), c)
return
}
data, err := analyticsService.GetRenewalTrend(req.StartDate, req.EndDate, req.ChannelId)
if err != nil {
global.Logger.Error("获取续费趋势失败!", zap.Error(err))
response.FailWithMsg(err.Error(), c)
return
}
response.OkWithData(data, c)
}
// GetSubscriberStats 获取订阅用户统计
// @Tags 数据分析
// @Summary 获取订阅用户统计(折线图 + 概览)
// @Produce application/json
// @Param startDate query string false "开始日期"
// @Param endDate query string false "结束日期"
// @Param channelId query string false "频道ID"
// @Success 200 {object} response.Response
// @Router /radio/analytics/subscriber-stats [get]
func (a *AnalyticsApi) GetSubscriberStats(c *gin.Context) {
var req request.TrendQuery
if err := c.ShouldBindQuery(&req); err != nil {
response.FailWithMsg("参数错误: "+err.Error(), c)
return
}
data, err := analyticsService.GetSubscriberStats(req.StartDate, req.EndDate, req.ChannelId)
if err != nil {
global.Logger.Error("获取订阅用户统计失败!", zap.Error(err))
response.FailWithMsg(err.Error(), c)
return
}
response.OkWithData(data, c)
}
// GetContentQuality 获取内容质量分析
// @Tags 数据分析
// @Summary 获取内容质量分析(完播率等)
// @Param channelId query string false "频道ID"
// @Success 200 {object} response.Response
// @Router /radio/analytics/content-quality [get]
func (a *AnalyticsApi) GetContentQuality(c *gin.Context) {
channelId := c.Query("channelId")
data, err := analyticsService.GetContentQuality(channelId)
if err != nil {
global.Logger.Error("获取内容质量分析失败!", zap.Error(err))
response.FailWithMsg(err.Error(), c)
return
}
response.OkWithData(data, c)
}
// GetUserStickiness 获取用户留存分析
// @Tags 数据分析
// @Summary 获取用户留存分析 (Cohort)
// @Param startDate query string false "开始日期"
// @Param endDate query string false "结束日期"
// @Success 200 {object} response.Response
// @Router /radio/analytics/user-stickiness [get]
func (a *AnalyticsApi) GetUserStickiness(c *gin.Context) {
var req request.TrendQuery
c.ShouldBindQuery(&req)
data, err := analyticsService.GetUserStickiness(req.StartDate, req.EndDate)
if err != nil {
global.Logger.Error("获取用户留存分析失败!", zap.Error(err))
response.FailWithMsg(err.Error(), c)
return
}
response.OkWithData(data, c)
}
// GetBusinessConversion 获取商业转化分析
// @Tags 数据分析
// @Summary 获取商业转化分析 (Funnel & LTV)
// @Param startDate query string false "开始日期"
// @Param endDate query string false "结束日期"
// @Success 200 {object} response.Response
// @Router /radio/analytics/business-conversion [get]
func (a *AnalyticsApi) GetBusinessConversion(c *gin.Context) {
var req request.TrendQuery
c.ShouldBindQuery(&req)
data, err := analyticsService.GetBusinessConversion(req.StartDate, req.EndDate)
if err != nil {
global.Logger.Error("获取商业转化分析失败!", zap.Error(err))
response.FailWithMsg(err.Error(), c)
return
}
response.OkWithData(data, c)
}
// GetPreferenceAnalysis 获取品类偏好分析
// @Tags 数据分析
// @Summary 获取品类偏好分析
// @Success 200 {object} response.Response
// @Router /radio/analytics/preference [get]
func (a *AnalyticsApi) GetPreferenceAnalysis(c *gin.Context) {
data, err := analyticsService.GetPreferenceAnalysis()
if err != nil {
global.Logger.Error("获取品类偏好分析失败!", zap.Error(err))
response.FailWithMsg(err.Error(), c)
return
}
response.OkWithData(data, c)
}
+2
View File
@@ -10,6 +10,7 @@ type ApiGroup struct {
InteractionApi
PayApi
VipApi
AnalyticsApi
}
var ApiGroupApp = new(ApiGroup)
@@ -22,4 +23,5 @@ var (
interactionService = service.GroupApp.RadioServiceGroup.InteractionService
payService = service.GroupApp.RadioServiceGroup.PayService
vipService = service.GroupApp.RadioServiceGroup.VipService
analyticsService = service.GroupApp.RadioServiceGroup.AnalyticsService
)