1502 lines
54 KiB
Go
1502 lines
54 KiB
Go
package handlers
|
||
|
||
import (
|
||
"strconv"
|
||
"time"
|
||
|
||
"tyapi-server/internal/application/statistics"
|
||
"tyapi-server/internal/shared/interfaces"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
// StatisticsHandler 统计处理器
|
||
type StatisticsHandler struct {
|
||
statisticsAppService statistics.StatisticsApplicationService
|
||
responseBuilder interfaces.ResponseBuilder
|
||
validator interfaces.RequestValidator
|
||
logger *zap.Logger
|
||
}
|
||
|
||
// NewStatisticsHandler 创建统计处理器
|
||
func NewStatisticsHandler(
|
||
statisticsAppService statistics.StatisticsApplicationService,
|
||
responseBuilder interfaces.ResponseBuilder,
|
||
validator interfaces.RequestValidator,
|
||
logger *zap.Logger,
|
||
) *StatisticsHandler {
|
||
return &StatisticsHandler{
|
||
statisticsAppService: statisticsAppService,
|
||
responseBuilder: responseBuilder,
|
||
validator: validator,
|
||
logger: logger,
|
||
}
|
||
}
|
||
|
||
// getIntQuery 获取整数查询参数
|
||
func (h *StatisticsHandler) getIntQuery(c *gin.Context, key string, defaultValue int) int {
|
||
if value := c.Query(key); value != "" {
|
||
if intValue, err := strconv.Atoi(value); err == nil && intValue > 0 {
|
||
return intValue
|
||
}
|
||
}
|
||
return defaultValue
|
||
}
|
||
|
||
// getCurrentUserID 获取当前用户ID
|
||
func (h *StatisticsHandler) getCurrentUserID(c *gin.Context) string {
|
||
if userID, exists := c.Get("user_id"); exists {
|
||
if id, ok := userID.(string); ok {
|
||
return id
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// GetPublicStatistics 获取公开统计信息
|
||
// @Summary 获取公开统计信息
|
||
// @Description 获取系统公开的统计信息,包括用户总数、认证用户数、认证比例等,无需认证
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.PublicStatisticsDTO} "获取成功"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/public [get]
|
||
func (h *StatisticsHandler) GetPublicStatistics(c *gin.Context) {
|
||
// 调用应用服务获取公开统计信息
|
||
result, err := h.statisticsAppService.GetPublicStatistics(c.Request.Context())
|
||
if err != nil {
|
||
h.logger.Error("获取公开统计信息失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取公开统计信息失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetUserStatistics 获取用户统计信息
|
||
// @Summary 获取用户统计信息
|
||
// @Description 获取当前用户的个人统计信息,包括API调用次数、认证状态、财务数据等
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param period query string false "时间周期" Enums(hour,day,week,month) default(day)
|
||
// @Param start_date query string false "开始日期" example("2024-01-01")
|
||
// @Param end_date query string false "结束日期" example("2024-01-31")
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.UserStatisticsDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/user [get]
|
||
func (h *StatisticsHandler) GetUserStatistics(c *gin.Context) {
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
// 调用应用服务获取用户统计信息
|
||
result, err := h.statisticsAppService.GetUserStatistics(c.Request.Context(), userID)
|
||
if err != nil {
|
||
h.logger.Error("获取用户统计信息失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取用户统计信息失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetMetrics 获取指标列表
|
||
// @Summary 获取指标列表
|
||
// @Description 获取可用的统计指标列表,支持按类型和名称筛选
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param metric_type query string false "指标类型" Enums(user,certification,finance,api,system)
|
||
// @Param metric_name query string false "指标名称" example("user_count")
|
||
// @Param page query int false "页码" default(1) minimum(1)
|
||
// @Param page_size query int false "每页数量" default(20) minimum(1) maximum(100)
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.MetricsListDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/metrics [get]
|
||
func (h *StatisticsHandler) GetMetrics(c *gin.Context) {
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
metricType := c.Query("metric_type")
|
||
metricName := c.Query("metric_name")
|
||
page := h.getIntQuery(c, "page", 1)
|
||
pageSize := h.getIntQuery(c, "page_size", 20)
|
||
|
||
query := &statistics.GetMetricsQuery{
|
||
MetricType: metricType,
|
||
MetricName: metricName,
|
||
Limit: pageSize,
|
||
Offset: (page - 1) * pageSize,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetMetrics(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("获取指标列表失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取指标列表失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetMetricDetail 获取指标详情
|
||
// @Summary 获取指标详情
|
||
// @Description 获取指定指标的详细信息,包括指标定义、计算方式、历史数据等
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param id path string true "指标ID" example("metric_001")
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.MetricDetailDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 404 {object} interfaces.APIResponse "指标不存在"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/metrics/{id} [get]
|
||
func (h *StatisticsHandler) GetMetricDetail(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
h.responseBuilder.BadRequest(c, "指标ID不能为空")
|
||
return
|
||
}
|
||
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
query := &statistics.GetMetricQuery{
|
||
MetricID: id,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetMetric(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("获取指标详情失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取指标详情失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetReports 获取报告列表
|
||
// @Summary 获取报告列表
|
||
// @Description 获取用户创建的统计报告列表,支持按类型和状态筛选
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param report_type query string false "报告类型" Enums(daily,weekly,monthly,custom)
|
||
// @Param status query string false "状态" Enums(pending,processing,completed,failed)
|
||
// @Param page query int false "页码" default(1) minimum(1)
|
||
// @Param page_size query int false "每页数量" default(20) minimum(1) maximum(100)
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.ReportsListDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/reports [get]
|
||
func (h *StatisticsHandler) GetReports(c *gin.Context) {
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
reportType := c.Query("report_type")
|
||
status := c.Query("status")
|
||
page := h.getIntQuery(c, "page", 1)
|
||
pageSize := h.getIntQuery(c, "page_size", 20)
|
||
|
||
query := &statistics.GetReportsQuery{
|
||
ReportType: reportType,
|
||
Status: status,
|
||
Limit: pageSize,
|
||
Offset: (page - 1) * pageSize,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetReports(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("获取报告列表失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取报告列表失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetReportDetail 获取报告详情
|
||
// @Summary 获取报告详情
|
||
// @Description 获取指定报告的详细信息,包括报告内容、生成时间、状态等
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param id path string true "报告ID" example("report_001")
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.ReportDetailDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 404 {object} interfaces.APIResponse "报告不存在"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/reports/{id} [get]
|
||
func (h *StatisticsHandler) GetReportDetail(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
h.responseBuilder.BadRequest(c, "报告ID不能为空")
|
||
return
|
||
}
|
||
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
query := &statistics.GetReportQuery{
|
||
ReportID: id,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetReport(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("获取报告详情失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取报告详情失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// CreateReport 创建报告
|
||
// @Summary 创建报告
|
||
// @Description 创建新的统计报告,支持自定义时间范围和指标选择
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param request body statistics.GenerateReportCommand true "创建报告请求"
|
||
// @Success 201 {object} interfaces.APIResponse{data=statistics.ReportDetailDTO} "创建成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/reports [post]
|
||
func (h *StatisticsHandler) CreateReport(c *gin.Context) {
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
var cmd statistics.GenerateReportCommand
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
h.responseBuilder.BadRequest(c, "请求参数错误")
|
||
return
|
||
}
|
||
|
||
cmd.GeneratedBy = userID
|
||
|
||
result, err := h.statisticsAppService.GenerateReport(c.Request.Context(), &cmd)
|
||
if err != nil {
|
||
h.logger.Error("创建报告失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "创建报告失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetDashboards 获取仪表板列表
|
||
// @Summary 获取仪表板列表
|
||
// @Description 获取可用的统计仪表板列表,支持按类型筛选
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param dashboard_type query string false "仪表板类型" Enums(overview,user,certification,finance,api)
|
||
// @Param page query int false "页码" default(1) minimum(1)
|
||
// @Param page_size query int false "每页数量" default(20) minimum(1) maximum(100)
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.DashboardsListDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/dashboards [get]
|
||
func (h *StatisticsHandler) GetDashboards(c *gin.Context) {
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
page := h.getIntQuery(c, "page", 1)
|
||
pageSize := h.getIntQuery(c, "page_size", 20)
|
||
|
||
// 获取查询参数
|
||
userRole := c.Query("user_role")
|
||
accessLevel := c.Query("access_level")
|
||
name := c.Query("name")
|
||
sortBy := c.DefaultQuery("sort_by", "created_at")
|
||
sortOrder := c.DefaultQuery("sort_order", "desc")
|
||
|
||
// 处理布尔参数
|
||
var isDefault *bool
|
||
if defaultStr := c.Query("is_default"); defaultStr != "" {
|
||
if defaultStr == "true" {
|
||
isDefault = &[]bool{true}[0]
|
||
} else if defaultStr == "false" {
|
||
isDefault = &[]bool{false}[0]
|
||
}
|
||
}
|
||
|
||
var isActive *bool
|
||
if activeStr := c.Query("is_active"); activeStr != "" {
|
||
if activeStr == "true" {
|
||
isActive = &[]bool{true}[0]
|
||
} else if activeStr == "false" {
|
||
isActive = &[]bool{false}[0]
|
||
}
|
||
}
|
||
|
||
query := &statistics.GetDashboardsQuery{
|
||
UserRole: userRole,
|
||
AccessLevel: accessLevel,
|
||
Name: name,
|
||
IsDefault: isDefault,
|
||
IsActive: isActive,
|
||
CreatedBy: "", // 不限制创建者,让应用服务层处理权限逻辑
|
||
Limit: pageSize,
|
||
Offset: (page - 1) * pageSize,
|
||
SortBy: sortBy,
|
||
SortOrder: sortOrder,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetDashboards(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("获取仪表板列表失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取仪表板列表失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetDashboardDetail 获取仪表板详情
|
||
// @Summary 获取仪表板详情
|
||
// @Description 获取指定仪表板的详细信息,包括布局配置、指标列表等
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param id path string true "仪表板ID" example("dashboard_001")
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.DashboardDetailDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 404 {object} interfaces.APIResponse "仪表板不存在"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/dashboards/{id} [get]
|
||
func (h *StatisticsHandler) GetDashboardDetail(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
h.responseBuilder.BadRequest(c, "仪表板ID不能为空")
|
||
return
|
||
}
|
||
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
query := &statistics.GetDashboardQuery{
|
||
DashboardID: id,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetDashboard(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("获取仪表板详情失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取仪表板详情失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetDashboardData 获取仪表板数据
|
||
// @Summary 获取仪表板数据
|
||
// @Description 获取指定仪表板的实时数据,支持自定义时间范围和周期
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param id path string true "仪表板ID" example("dashboard_001")
|
||
// @Param period query string false "时间周期" Enums(hour,day,week,month) default(day)
|
||
// @Param start_date query string false "开始日期" example("2024-01-01")
|
||
// @Param end_date query string false "结束日期" example("2024-01-31")
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.DashboardDataDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 404 {object} interfaces.APIResponse "仪表板不存在"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/dashboards/{id}/data [get]
|
||
func (h *StatisticsHandler) GetDashboardData(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
h.responseBuilder.BadRequest(c, "仪表板ID不能为空")
|
||
return
|
||
}
|
||
|
||
userID := h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
period := c.DefaultQuery("period", "day")
|
||
startDateStr := c.Query("start_date")
|
||
endDateStr := c.Query("end_date")
|
||
|
||
// 解析日期
|
||
var startDate, endDate time.Time
|
||
var err error
|
||
if startDateStr != "" {
|
||
startDate, err = time.Parse("2006-01-02", startDateStr)
|
||
if err != nil {
|
||
h.responseBuilder.BadRequest(c, "开始日期格式错误")
|
||
return
|
||
}
|
||
}
|
||
if endDateStr != "" {
|
||
endDate, err = time.Parse("2006-01-02", endDateStr)
|
||
if err != nil {
|
||
h.responseBuilder.BadRequest(c, "结束日期格式错误")
|
||
return
|
||
}
|
||
}
|
||
|
||
query := &statistics.GetDashboardDataQuery{
|
||
UserRole: "user", // 暂时硬编码,实际应该从用户信息获取
|
||
Period: period,
|
||
StartDate: startDate,
|
||
EndDate: endDate,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetDashboardData(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("获取仪表板数据失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取仪表板数据失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// ========== 管理员接口 ==========
|
||
|
||
// AdminGetMetrics 管理员获取指标列表
|
||
// @Summary 管理员获取指标列表
|
||
// @Description 管理员获取所有统计指标列表,包括系统指标和自定义指标
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param metric_type query string false "指标类型" Enums(user,certification,finance,api,system)
|
||
// @Param metric_name query string false "指标名称" example("user_count")
|
||
// @Param page query int false "页码" default(1) minimum(1)
|
||
// @Param page_size query int false "每页数量" default(20) minimum(1) maximum(100)
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.MetricsListDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/metrics [get]
|
||
func (h *StatisticsHandler) AdminGetMetrics(c *gin.Context) {
|
||
metricType := c.Query("metric_type")
|
||
metricName := c.Query("metric_name")
|
||
page := h.getIntQuery(c, "page", 1)
|
||
pageSize := h.getIntQuery(c, "page_size", 20)
|
||
|
||
query := &statistics.GetMetricsQuery{
|
||
MetricType: metricType,
|
||
MetricName: metricName,
|
||
Limit: pageSize,
|
||
Offset: (page - 1) * pageSize,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetMetrics(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("管理员获取指标列表失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取指标列表失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminCreateMetric 管理员创建指标
|
||
// @Summary 管理员创建指标
|
||
// @Description 管理员创建新的统计指标,支持自定义计算逻辑和显示配置
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param request body statistics.CreateMetricCommand true "创建指标请求"
|
||
// @Success 201 {object} interfaces.APIResponse{data=statistics.MetricDetailDTO} "创建成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/metrics [post]
|
||
func (h *StatisticsHandler) AdminCreateMetric(c *gin.Context) {
|
||
adminID := h.getCurrentUserID(c)
|
||
if adminID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
var cmd statistics.CreateMetricCommand
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
h.responseBuilder.BadRequest(c, "请求参数错误")
|
||
return
|
||
}
|
||
|
||
result, err := h.statisticsAppService.CreateMetric(c.Request.Context(), &cmd)
|
||
if err != nil {
|
||
h.logger.Error("管理员创建指标失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "创建指标失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminUpdateMetric 管理员更新指标
|
||
// @Summary 管理员更新指标
|
||
// @Description 管理员更新统计指标的配置信息,包括名称、描述、计算逻辑等
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param id path string true "指标ID" example("metric_001")
|
||
// @Param request body statistics.UpdateMetricCommand true "更新指标请求"
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.MetricDetailDTO} "更新成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 404 {object} interfaces.APIResponse "指标不存在"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/metrics/{id} [put]
|
||
func (h *StatisticsHandler) AdminUpdateMetric(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
h.responseBuilder.BadRequest(c, "指标ID不能为空")
|
||
return
|
||
}
|
||
|
||
adminID := h.getCurrentUserID(c)
|
||
if adminID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
var cmd statistics.UpdateMetricCommand
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
h.responseBuilder.BadRequest(c, "请求参数错误")
|
||
return
|
||
}
|
||
|
||
cmd.ID = id
|
||
|
||
result, err := h.statisticsAppService.UpdateMetric(c.Request.Context(), &cmd)
|
||
if err != nil {
|
||
h.logger.Error("管理员更新指标失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "更新指标失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminDeleteMetric 管理员删除指标
|
||
// @Summary 管理员删除指标
|
||
// @Description 管理员删除统计指标,删除后相关数据将无法恢复
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param id path string true "指标ID" example("metric_001")
|
||
// @Success 200 {object} interfaces.APIResponse "删除成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 404 {object} interfaces.APIResponse "指标不存在"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/metrics/{id} [delete]
|
||
func (h *StatisticsHandler) AdminDeleteMetric(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
h.responseBuilder.BadRequest(c, "指标ID不能为空")
|
||
return
|
||
}
|
||
|
||
adminID := h.getCurrentUserID(c)
|
||
if adminID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
cmd := &statistics.DeleteMetricCommand{
|
||
ID: id,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.DeleteMetric(c.Request.Context(), cmd)
|
||
if err != nil {
|
||
h.logger.Error("管理员删除指标失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "删除指标失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminGetReports 管理员获取报告列表
|
||
// @Summary 管理员获取报告列表
|
||
// @Description 管理员获取所有用户的统计报告列表,支持按类型和状态筛选
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param report_type query string false "报告类型" Enums(daily,weekly,monthly,custom)
|
||
// @Param status query string false "状态" Enums(pending,processing,completed,failed)
|
||
// @Param page query int false "页码" default(1) minimum(1)
|
||
// @Param page_size query int false "每页数量" default(20) minimum(1) maximum(100)
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.ReportsListDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/reports [get]
|
||
func (h *StatisticsHandler) AdminGetReports(c *gin.Context) {
|
||
reportType := c.Query("report_type")
|
||
status := c.Query("status")
|
||
page := h.getIntQuery(c, "page", 1)
|
||
pageSize := h.getIntQuery(c, "page_size", 20)
|
||
|
||
query := &statistics.GetReportsQuery{
|
||
ReportType: reportType,
|
||
Status: status,
|
||
Limit: pageSize,
|
||
Offset: (page - 1) * pageSize,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetReports(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("管理员获取报告列表失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取报告列表失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminGetDashboards 管理员获取仪表板列表
|
||
// @Summary 管理员获取仪表板列表
|
||
// @Description 管理员获取所有仪表板列表,包括系统默认和用户自定义仪表板
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param dashboard_type query string false "仪表板类型" Enums(overview,user,certification,finance,api,system)
|
||
// @Param page query int false "页码" default(1) minimum(1)
|
||
// @Param page_size query int false "每页数量" default(20) minimum(1) maximum(100)
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.DashboardsListDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/dashboards [get]
|
||
func (h *StatisticsHandler) AdminGetDashboards(c *gin.Context) {
|
||
page := h.getIntQuery(c, "page", 1)
|
||
pageSize := h.getIntQuery(c, "page_size", 20)
|
||
|
||
// 获取查询参数
|
||
userRole := c.Query("user_role")
|
||
accessLevel := c.Query("access_level")
|
||
name := c.Query("name")
|
||
sortBy := c.DefaultQuery("sort_by", "created_at")
|
||
sortOrder := c.DefaultQuery("sort_order", "desc")
|
||
|
||
// 处理布尔参数
|
||
var isDefault *bool
|
||
if defaultStr := c.Query("is_default"); defaultStr != "" {
|
||
if defaultStr == "true" {
|
||
isDefault = &[]bool{true}[0]
|
||
} else if defaultStr == "false" {
|
||
isDefault = &[]bool{false}[0]
|
||
}
|
||
}
|
||
|
||
var isActive *bool
|
||
if activeStr := c.Query("is_active"); activeStr != "" {
|
||
if activeStr == "true" {
|
||
isActive = &[]bool{true}[0]
|
||
} else if activeStr == "false" {
|
||
isActive = &[]bool{false}[0]
|
||
}
|
||
}
|
||
|
||
query := &statistics.GetDashboardsQuery{
|
||
UserRole: userRole,
|
||
AccessLevel: accessLevel,
|
||
Name: name,
|
||
IsDefault: isDefault,
|
||
IsActive: isActive,
|
||
CreatedBy: "", // 管理员可以查看所有仪表板
|
||
Limit: pageSize,
|
||
Offset: (page - 1) * pageSize,
|
||
SortBy: sortBy,
|
||
SortOrder: sortOrder,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.GetDashboards(c.Request.Context(), query)
|
||
if err != nil {
|
||
h.logger.Error("管理员获取仪表板列表失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取仪表板列表失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminCreateDashboard 管理员创建仪表板
|
||
// @Summary 管理员创建仪表板
|
||
// @Description 管理员创建新的统计仪表板,支持自定义布局和指标配置
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param request body statistics.CreateDashboardCommand true "创建仪表板请求"
|
||
// @Success 201 {object} interfaces.APIResponse{data=statistics.DashboardDetailDTO} "创建成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/dashboards [post]
|
||
func (h *StatisticsHandler) AdminCreateDashboard(c *gin.Context) {
|
||
adminID := h.getCurrentUserID(c)
|
||
if adminID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
var cmd statistics.CreateDashboardCommand
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
h.responseBuilder.BadRequest(c, "请求参数错误")
|
||
return
|
||
}
|
||
|
||
result, err := h.statisticsAppService.CreateDashboard(c.Request.Context(), &cmd)
|
||
if err != nil {
|
||
h.logger.Error("管理员创建仪表板失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "创建仪表板失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminUpdateDashboard 管理员更新仪表板
|
||
// @Summary 管理员更新仪表板
|
||
// @Description 管理员更新统计仪表板的配置信息,包括布局、指标、权限等
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param id path string true "仪表板ID" example("dashboard_001")
|
||
// @Param request body statistics.UpdateDashboardCommand true "更新仪表板请求"
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.DashboardDetailDTO} "更新成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 404 {object} interfaces.APIResponse "仪表板不存在"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/dashboards/{id} [put]
|
||
func (h *StatisticsHandler) AdminUpdateDashboard(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
h.responseBuilder.BadRequest(c, "仪表板ID不能为空")
|
||
return
|
||
}
|
||
|
||
adminID := h.getCurrentUserID(c)
|
||
if adminID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
var cmd statistics.UpdateDashboardCommand
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
h.responseBuilder.BadRequest(c, "请求参数错误")
|
||
return
|
||
}
|
||
|
||
cmd.ID = id
|
||
|
||
result, err := h.statisticsAppService.UpdateDashboard(c.Request.Context(), &cmd)
|
||
if err != nil {
|
||
h.logger.Error("管理员更新仪表板失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "更新仪表板失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminDeleteDashboard 管理员删除仪表板
|
||
// @Summary 管理员删除仪表板
|
||
// @Description 管理员删除统计仪表板,删除后相关数据将无法恢复
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param id path string true "仪表板ID" example("dashboard_001")
|
||
// @Success 200 {object} interfaces.APIResponse "删除成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 404 {object} interfaces.APIResponse "仪表板不存在"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/dashboards/{id} [delete]
|
||
func (h *StatisticsHandler) AdminDeleteDashboard(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
h.responseBuilder.BadRequest(c, "仪表板ID不能为空")
|
||
return
|
||
}
|
||
|
||
adminID := h.getCurrentUserID(c)
|
||
if adminID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
cmd := &statistics.DeleteDashboardCommand{
|
||
DashboardID: id,
|
||
DeletedBy: adminID,
|
||
}
|
||
|
||
result, err := h.statisticsAppService.DeleteDashboard(c.Request.Context(), cmd)
|
||
if err != nil {
|
||
h.logger.Error("管理员删除仪表板失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "删除仪表板失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminGetSystemStatistics 管理员获取系统统计
|
||
// @Summary 管理员获取系统统计
|
||
// @Description 管理员获取系统整体统计信息,包括用户统计、认证统计、财务统计、API调用统计等
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param period query string false "时间周期" Enums(hour,day,week,month) default(day)
|
||
// @Param start_date query string false "开始日期" example("2024-01-01")
|
||
// @Param end_date query string false "结束日期" example("2024-01-31")
|
||
// @Success 200 {object} interfaces.APIResponse{data=statistics.SystemStatisticsDTO} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/system [get]
|
||
func (h *StatisticsHandler) AdminGetSystemStatistics(c *gin.Context) {
|
||
period := c.DefaultQuery("period", "day")
|
||
startDate := c.Query("start_date")
|
||
endDate := c.Query("end_date")
|
||
|
||
// 调用应用服务获取系统统计
|
||
result, err := h.statisticsAppService.AdminGetSystemStatistics(c.Request.Context(), period, startDate, endDate)
|
||
if err != nil {
|
||
h.logger.Error("获取系统统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取系统统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminTriggerAggregation 管理员触发数据聚合
|
||
// @Summary 管理员触发数据聚合
|
||
// @Description 管理员手动触发数据聚合任务,用于重新计算统计数据
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param request body statistics.TriggerAggregationCommand true "触发聚合请求"
|
||
// @Success 200 {object} interfaces.APIResponse "触发成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/aggregation/trigger [post]
|
||
func (h *StatisticsHandler) AdminTriggerAggregation(c *gin.Context) {
|
||
adminID := h.getCurrentUserID(c)
|
||
if adminID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
var cmd statistics.TriggerAggregationCommand
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
h.responseBuilder.BadRequest(c, "请求参数错误")
|
||
return
|
||
}
|
||
|
||
// 设置触发者
|
||
cmd.TriggeredBy = adminID
|
||
|
||
// 调用应用服务触发聚合
|
||
result, err := h.statisticsAppService.AdminTriggerAggregation(c.Request.Context(), &cmd)
|
||
if err != nil {
|
||
h.logger.Error("触发数据聚合失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "触发数据聚合失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminGetUserStatistics 管理员获取单个用户统计
|
||
// @Summary 管理员获取单个用户统计
|
||
// @Description 管理员查看指定用户的详细统计信息,包括API调用、消费、充值等数据
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param user_id path string true "用户ID"
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/users/{user_id} [get]
|
||
func (h *StatisticsHandler) AdminGetUserStatistics(c *gin.Context) {
|
||
userID := c.Param("user_id")
|
||
if userID == "" {
|
||
h.responseBuilder.BadRequest(c, "用户ID不能为空")
|
||
return
|
||
}
|
||
|
||
// 调用应用服务获取用户统计
|
||
result, err := h.statisticsAppService.AdminGetUserStatistics(c.Request.Context(), userID)
|
||
if err != nil {
|
||
h.logger.Error("获取用户统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取用户统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// ================ 独立统计接口 ================
|
||
|
||
// GetApiCallsStatistics 获取API调用统计
|
||
// @Summary 获取API调用统计
|
||
// @Description 获取指定用户和时间范围的API调用统计数据
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param user_id query string false "用户ID,不传则查询当前用户"
|
||
// @Param start_date query string true "开始日期,格式:2006-01-02"
|
||
// @Param end_date query string true "结束日期,格式:2006-01-02"
|
||
// @Param unit query string true "时间单位" Enums(day,month)
|
||
// @Success 200 {object} response.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} response.APIResponse "请求参数错误"
|
||
// @Failure 500 {object} response.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/api-calls [get]
|
||
func (h *StatisticsHandler) GetApiCallsStatistics(c *gin.Context) {
|
||
// 获取查询参数
|
||
userID := c.Query("user_id")
|
||
startDateStr := c.Query("start_date")
|
||
endDateStr := c.Query("end_date")
|
||
unit := c.Query("unit")
|
||
|
||
// 参数验证
|
||
if startDateStr == "" || endDateStr == "" {
|
||
h.responseBuilder.BadRequest(c, "开始日期和结束日期不能为空")
|
||
return
|
||
}
|
||
|
||
if unit == "" {
|
||
h.responseBuilder.BadRequest(c, "时间单位不能为空")
|
||
return
|
||
}
|
||
|
||
if unit != "day" && unit != "month" {
|
||
h.responseBuilder.BadRequest(c, "时间单位只能是day或month")
|
||
return
|
||
}
|
||
|
||
// 解析日期
|
||
startDate, err := time.Parse("2006-01-02", startDateStr)
|
||
if err != nil {
|
||
h.responseBuilder.BadRequest(c, "开始日期格式错误")
|
||
return
|
||
}
|
||
|
||
endDate, err := time.Parse("2006-01-02", endDateStr)
|
||
if err != nil {
|
||
h.responseBuilder.BadRequest(c, "结束日期格式错误")
|
||
return
|
||
}
|
||
|
||
// 如果没有提供用户ID,从JWT中获取
|
||
if userID == "" {
|
||
userID = h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
}
|
||
|
||
// 调用应用服务
|
||
result, err := h.statisticsAppService.GetApiCallsStatistics(c.Request.Context(), userID, startDate, endDate, unit)
|
||
if err != nil {
|
||
h.logger.Error("获取API调用统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取API调用统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetConsumptionStatistics 获取消费统计
|
||
// @Summary 获取消费统计
|
||
// @Description 获取指定用户和时间范围的消费统计数据
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param user_id query string false "用户ID,不传则查询当前用户"
|
||
// @Param start_date query string true "开始日期,格式:2006-01-02"
|
||
// @Param end_date query string true "结束日期,格式:2006-01-02"
|
||
// @Param unit query string true "时间单位" Enums(day,month)
|
||
// @Success 200 {object} response.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} response.APIResponse "请求参数错误"
|
||
// @Failure 500 {object} response.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/consumption [get]
|
||
func (h *StatisticsHandler) GetConsumptionStatistics(c *gin.Context) {
|
||
// 获取查询参数
|
||
userID := c.Query("user_id")
|
||
startDateStr := c.Query("start_date")
|
||
endDateStr := c.Query("end_date")
|
||
unit := c.Query("unit")
|
||
|
||
// 参数验证
|
||
if startDateStr == "" || endDateStr == "" {
|
||
h.responseBuilder.BadRequest(c, "开始日期和结束日期不能为空")
|
||
return
|
||
}
|
||
|
||
if unit == "" {
|
||
h.responseBuilder.BadRequest(c, "时间单位不能为空")
|
||
return
|
||
}
|
||
|
||
if unit != "day" && unit != "month" {
|
||
h.responseBuilder.BadRequest(c, "时间单位只能是day或month")
|
||
return
|
||
}
|
||
|
||
// 解析日期
|
||
startDate, err := time.Parse("2006-01-02", startDateStr)
|
||
if err != nil {
|
||
h.responseBuilder.BadRequest(c, "开始日期格式错误")
|
||
return
|
||
}
|
||
|
||
endDate, err := time.Parse("2006-01-02", endDateStr)
|
||
if err != nil {
|
||
h.responseBuilder.BadRequest(c, "结束日期格式错误")
|
||
return
|
||
}
|
||
|
||
// 如果没有提供用户ID,从JWT中获取
|
||
if userID == "" {
|
||
userID = h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
}
|
||
|
||
// 调用应用服务
|
||
result, err := h.statisticsAppService.GetConsumptionStatistics(c.Request.Context(), userID, startDate, endDate, unit)
|
||
if err != nil {
|
||
h.logger.Error("获取消费统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取消费统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetRechargeStatistics 获取充值统计
|
||
// @Summary 获取充值统计
|
||
// @Description 获取指定用户和时间范围的充值统计数据
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param user_id query string false "用户ID,不传则查询当前用户"
|
||
// @Param start_date query string true "开始日期,格式:2006-01-02"
|
||
// @Param end_date query string true "结束日期,格式:2006-01-02"
|
||
// @Param unit query string true "时间单位" Enums(day,month)
|
||
// @Success 200 {object} response.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} response.APIResponse "请求参数错误"
|
||
// @Failure 500 {object} response.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/recharge [get]
|
||
func (h *StatisticsHandler) GetRechargeStatistics(c *gin.Context) {
|
||
// 获取查询参数
|
||
userID := c.Query("user_id")
|
||
startDateStr := c.Query("start_date")
|
||
endDateStr := c.Query("end_date")
|
||
unit := c.Query("unit")
|
||
|
||
// 参数验证
|
||
if startDateStr == "" || endDateStr == "" {
|
||
h.responseBuilder.BadRequest(c, "开始日期和结束日期不能为空")
|
||
return
|
||
}
|
||
|
||
if unit == "" {
|
||
h.responseBuilder.BadRequest(c, "时间单位不能为空")
|
||
return
|
||
}
|
||
|
||
if unit != "day" && unit != "month" {
|
||
h.responseBuilder.BadRequest(c, "时间单位只能是day或month")
|
||
return
|
||
}
|
||
|
||
// 解析日期
|
||
startDate, err := time.Parse("2006-01-02", startDateStr)
|
||
if err != nil {
|
||
h.responseBuilder.BadRequest(c, "开始日期格式错误")
|
||
return
|
||
}
|
||
|
||
endDate, err := time.Parse("2006-01-02", endDateStr)
|
||
if err != nil {
|
||
h.responseBuilder.BadRequest(c, "结束日期格式错误")
|
||
return
|
||
}
|
||
|
||
// 如果没有提供用户ID,从JWT中获取
|
||
if userID == "" {
|
||
userID = h.getCurrentUserID(c)
|
||
if userID == "" {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
}
|
||
|
||
// 调用应用服务
|
||
result, err := h.statisticsAppService.GetRechargeStatistics(c.Request.Context(), userID, startDate, endDate, unit)
|
||
if err != nil {
|
||
h.logger.Error("获取充值统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取充值统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// GetLatestProducts 获取最新产品推荐
|
||
// @Summary 获取最新产品推荐
|
||
// @Description 获取近一月内新增的产品,如果近一月内没有新增则返回最新的前10个产品
|
||
// @Tags 统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param limit query int false "返回数量限制" default(10)
|
||
// @Success 200 {object} response.APIResponse{data=object} "获取成功"
|
||
// @Failure 500 {object} response.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/statistics/latest-products [get]
|
||
func (h *StatisticsHandler) GetLatestProducts(c *gin.Context) {
|
||
// 获取查询参数
|
||
limit := h.getIntQuery(c, "limit", 10)
|
||
if limit > 20 {
|
||
limit = 20 // 限制最大返回数量
|
||
}
|
||
|
||
// 调用应用服务
|
||
result, err := h.statisticsAppService.GetLatestProducts(c.Request.Context(), limit)
|
||
if err != nil {
|
||
h.logger.Error("获取最新产品失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取最新产品失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// ================ 管理员独立域统计接口 ================
|
||
|
||
// AdminGetUserDomainStatistics 管理员获取用户域统计
|
||
// @Summary 管理员获取用户域统计
|
||
// @Description 管理员获取用户注册与认证趋势统计
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param period query string false "时间周期" Enums(day,month) default(day)
|
||
// @Param start_date query string false "开始日期" example("2024-01-01")
|
||
// @Param end_date query string false "结束日期" example("2024-01-31")
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/user-domain [get]
|
||
func (h *StatisticsHandler) AdminGetUserDomainStatistics(c *gin.Context) {
|
||
period := c.DefaultQuery("period", "day")
|
||
startDate := c.Query("start_date")
|
||
endDate := c.Query("end_date")
|
||
|
||
// 调用应用服务获取用户域统计
|
||
result, err := h.statisticsAppService.AdminGetUserDomainStatistics(c.Request.Context(), period, startDate, endDate)
|
||
if err != nil {
|
||
h.logger.Error("获取用户域统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取用户域统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminGetApiDomainStatistics 管理员获取API域统计
|
||
// @Summary 管理员获取API域统计
|
||
// @Description 管理员获取API调用趋势统计
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param period query string false "时间周期" Enums(day,month) default(day)
|
||
// @Param start_date query string false "开始日期" example("2024-01-01")
|
||
// @Param end_date query string false "结束日期" example("2024-01-31")
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/api-domain [get]
|
||
func (h *StatisticsHandler) AdminGetApiDomainStatistics(c *gin.Context) {
|
||
period := c.DefaultQuery("period", "day")
|
||
startDate := c.Query("start_date")
|
||
endDate := c.Query("end_date")
|
||
|
||
// 调用应用服务获取API域统计
|
||
result, err := h.statisticsAppService.AdminGetApiDomainStatistics(c.Request.Context(), period, startDate, endDate)
|
||
if err != nil {
|
||
h.logger.Error("获取API域统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取API域统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminGetConsumptionDomainStatistics 管理员获取消费域统计
|
||
// @Summary 管理员获取消费域统计
|
||
// @Description 管理员获取用户消费趋势统计
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param period query string false "时间周期" Enums(day,month) default(day)
|
||
// @Param start_date query string false "开始日期" example("2024-01-01")
|
||
// @Param end_date query string false "结束日期" example("2024-01-31")
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/consumption-domain [get]
|
||
func (h *StatisticsHandler) AdminGetConsumptionDomainStatistics(c *gin.Context) {
|
||
period := c.DefaultQuery("period", "day")
|
||
startDate := c.Query("start_date")
|
||
endDate := c.Query("end_date")
|
||
|
||
// 调用应用服务获取消费域统计
|
||
result, err := h.statisticsAppService.AdminGetConsumptionDomainStatistics(c.Request.Context(), period, startDate, endDate)
|
||
if err != nil {
|
||
h.logger.Error("获取消费域统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取消费域统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminGetRechargeDomainStatistics 管理员获取充值域统计
|
||
// @Summary 管理员获取充值域统计
|
||
// @Description 管理员获取充值趋势统计
|
||
// @Tags 统计管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param period query string false "时间周期" Enums(day,month) default(day)
|
||
// @Param start_date query string false "开始日期" example("2024-01-01")
|
||
// @Param end_date query string false "结束日期" example("2024-01-31")
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/recharge-domain [get]
|
||
func (h *StatisticsHandler) AdminGetRechargeDomainStatistics(c *gin.Context) {
|
||
period := c.DefaultQuery("period", "day")
|
||
startDate := c.Query("start_date")
|
||
endDate := c.Query("end_date")
|
||
|
||
// 调用应用服务获取充值域统计
|
||
result, err := h.statisticsAppService.AdminGetRechargeDomainStatistics(c.Request.Context(), period, startDate, endDate)
|
||
if err != nil {
|
||
h.logger.Error("获取充值域统计失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取充值域统计失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, result.Message)
|
||
}
|
||
|
||
// AdminGetUserCallRanking 获取用户调用排行榜
|
||
// @Summary 获取用户调用排行榜
|
||
// @Description 获取用户调用排行榜,支持按调用次数和消费金额排序,支持今日、本月、总排行
|
||
// @Tags 管理员统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param type query string false "排行类型" Enums(calls,consumption) default(calls)
|
||
// @Param period query string false "时间周期" Enums(today,month,total) default(today)
|
||
// @Param limit query int false "返回数量" default(10)
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/user-call-ranking [get]
|
||
func (h *StatisticsHandler) AdminGetUserCallRanking(c *gin.Context) {
|
||
rankingType := c.DefaultQuery("type", "calls")
|
||
period := c.DefaultQuery("period", "today")
|
||
limit := h.getIntQuery(c, "limit", 10)
|
||
|
||
// 调用应用服务获取用户调用排行榜
|
||
result, err := h.statisticsAppService.AdminGetUserCallRanking(c.Request.Context(), rankingType, period, limit)
|
||
if err != nil {
|
||
h.logger.Error("获取用户调用排行榜失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取用户调用排行榜失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, "获取用户调用排行榜成功")
|
||
}
|
||
|
||
// AdminGetRechargeRanking 获取充值排行榜
|
||
// @Summary 获取充值排行榜
|
||
// @Description 获取充值排行榜,支持今日、本月、总排行
|
||
// @Tags 管理员统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param period query string false "时间周期" Enums(today,month,total) default(today)
|
||
// @Param limit query int false "返回数量" default(10)
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/recharge-ranking [get]
|
||
func (h *StatisticsHandler) AdminGetRechargeRanking(c *gin.Context) {
|
||
period := c.DefaultQuery("period", "today")
|
||
limit := h.getIntQuery(c, "limit", 10)
|
||
|
||
// 调用应用服务获取充值排行榜
|
||
result, err := h.statisticsAppService.AdminGetRechargeRanking(c.Request.Context(), period, limit)
|
||
if err != nil {
|
||
h.logger.Error("获取充值排行榜失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取充值排行榜失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, "获取充值排行榜成功")
|
||
}
|
||
|
||
// AdminGetApiPopularityRanking 获取API受欢迎程度排行榜
|
||
// @Summary 获取API受欢迎程度排行榜
|
||
// @Description 获取API受欢迎程度排行榜,支持今日、本月、总排行
|
||
// @Tags 管理员统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param period query string false "时间周期" Enums(today,month,total) default(today)
|
||
// @Param limit query int false "返回数量" default(10)
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/api-popularity-ranking [get]
|
||
func (h *StatisticsHandler) AdminGetApiPopularityRanking(c *gin.Context) {
|
||
period := c.DefaultQuery("period", "today")
|
||
limit := h.getIntQuery(c, "limit", 10)
|
||
|
||
// 调用应用服务获取API受欢迎程度排行榜
|
||
result, err := h.statisticsAppService.AdminGetApiPopularityRanking(c.Request.Context(), period, limit)
|
||
if err != nil {
|
||
h.logger.Error("获取API受欢迎程度排行榜失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取API受欢迎程度排行榜失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, "获取API受欢迎程度排行榜成功")
|
||
}
|
||
|
||
// AdminGetTodayCertifiedEnterprises 获取今日认证企业列表
|
||
// @Summary 获取今日认证企业列表
|
||
// @Description 获取今日认证的企业列表,按认证完成时间排序
|
||
// @Tags 管理员统计
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security ApiKeyAuth
|
||
// @Param limit query int false "返回数量" default(20)
|
||
// @Success 200 {object} interfaces.APIResponse{data=object} "获取成功"
|
||
// @Failure 400 {object} interfaces.APIResponse "请求参数错误"
|
||
// @Failure 401 {object} interfaces.APIResponse "用户未登录"
|
||
// @Failure 403 {object} interfaces.APIResponse "权限不足"
|
||
// @Failure 500 {object} interfaces.APIResponse "服务器内部错误"
|
||
// @Router /api/v1/admin/statistics/today-certified-enterprises [get]
|
||
func (h *StatisticsHandler) AdminGetTodayCertifiedEnterprises(c *gin.Context) {
|
||
limit := h.getIntQuery(c, "limit", 20)
|
||
|
||
// 调用应用服务获取今日认证企业列表
|
||
result, err := h.statisticsAppService.AdminGetTodayCertifiedEnterprises(c.Request.Context(), limit)
|
||
if err != nil {
|
||
h.logger.Error("获取今日认证企业列表失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取今日认证企业列表失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, result.Data, "获取今日认证企业列表成功")
|
||
} |