new
This commit is contained in:
@@ -0,0 +1,582 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"tyapi-server/internal/domains/statistics/entities"
|
||||
"tyapi-server/internal/domains/statistics/repositories"
|
||||
)
|
||||
|
||||
// StatisticsReportService 报告生成服务接口
|
||||
// 负责统计报告的生成和管理
|
||||
type StatisticsReportService interface {
|
||||
// 报告生成
|
||||
GenerateDashboardReport(ctx context.Context, userRole string, period string) (*entities.StatisticsReport, error)
|
||||
GenerateSummaryReport(ctx context.Context, period string, startDate, endDate time.Time) (*entities.StatisticsReport, error)
|
||||
GenerateDetailedReport(ctx context.Context, reportType string, startDate, endDate time.Time, filters map[string]interface{}) (*entities.StatisticsReport, error)
|
||||
|
||||
// 报告管理
|
||||
GetReport(ctx context.Context, reportID string) (*entities.StatisticsReport, error)
|
||||
GetReportsByUser(ctx context.Context, userID string, limit, offset int) ([]*entities.StatisticsReport, error)
|
||||
DeleteReport(ctx context.Context, reportID string) error
|
||||
|
||||
// 报告状态管理
|
||||
StartReportGeneration(ctx context.Context, reportID, generatedBy string) error
|
||||
CompleteReportGeneration(ctx context.Context, reportID string, content string) error
|
||||
FailReportGeneration(ctx context.Context, reportID string, reason string) error
|
||||
|
||||
// 报告清理
|
||||
CleanupExpiredReports(ctx context.Context) error
|
||||
}
|
||||
|
||||
// StatisticsReportServiceImpl 报告生成服务实现
|
||||
type StatisticsReportServiceImpl struct {
|
||||
reportRepo repositories.StatisticsReportRepository
|
||||
metricRepo repositories.StatisticsRepository
|
||||
calcService StatisticsCalculationService
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewStatisticsReportService 创建报告生成服务
|
||||
func NewStatisticsReportService(
|
||||
reportRepo repositories.StatisticsReportRepository,
|
||||
metricRepo repositories.StatisticsRepository,
|
||||
calcService StatisticsCalculationService,
|
||||
logger *zap.Logger,
|
||||
) StatisticsReportService {
|
||||
return &StatisticsReportServiceImpl{
|
||||
reportRepo: reportRepo,
|
||||
metricRepo: metricRepo,
|
||||
calcService: calcService,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateDashboardReport 生成仪表板报告
|
||||
func (s *StatisticsReportServiceImpl) GenerateDashboardReport(ctx context.Context, userRole string, period string) (*entities.StatisticsReport, error) {
|
||||
if userRole == "" {
|
||||
return nil, fmt.Errorf("用户角色不能为空")
|
||||
}
|
||||
if period == "" {
|
||||
return nil, fmt.Errorf("统计周期不能为空")
|
||||
}
|
||||
|
||||
// 创建报告实体
|
||||
title := fmt.Sprintf("%s仪表板报告 - %s", s.getRoleDisplayName(userRole), s.getPeriodDisplayName(period))
|
||||
report, err := entities.NewStatisticsReport("dashboard", title, period, userRole)
|
||||
if err != nil {
|
||||
s.logger.Error("创建仪表板报告失败",
|
||||
zap.String("user_role", userRole),
|
||||
zap.String("period", period),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("创建仪表板报告失败: %w", err)
|
||||
}
|
||||
|
||||
// 保存报告
|
||||
err = s.reportRepo.Save(ctx, report)
|
||||
if err != nil {
|
||||
s.logger.Error("保存仪表板报告失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("保存仪表板报告失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("仪表板报告创建成功",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.String("user_role", userRole),
|
||||
zap.String("period", period))
|
||||
|
||||
return report, nil
|
||||
}
|
||||
|
||||
// GenerateSummaryReport 生成汇总报告
|
||||
func (s *StatisticsReportServiceImpl) GenerateSummaryReport(ctx context.Context, period string, startDate, endDate time.Time) (*entities.StatisticsReport, error) {
|
||||
if period == "" {
|
||||
return nil, fmt.Errorf("统计周期不能为空")
|
||||
}
|
||||
|
||||
// 创建报告实体
|
||||
title := fmt.Sprintf("汇总报告 - %s (%s 至 %s)",
|
||||
s.getPeriodDisplayName(period),
|
||||
startDate.Format("2006-01-02"),
|
||||
endDate.Format("2006-01-02"))
|
||||
report, err := entities.NewStatisticsReport("summary", title, period, "admin")
|
||||
if err != nil {
|
||||
s.logger.Error("创建汇总报告失败",
|
||||
zap.String("period", period),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("创建汇总报告失败: %w", err)
|
||||
}
|
||||
|
||||
// 生成报告内容
|
||||
content, err := s.generateSummaryContent(ctx, startDate, endDate)
|
||||
if err != nil {
|
||||
s.logger.Error("生成汇总报告内容失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("生成汇总报告内容失败: %w", err)
|
||||
}
|
||||
|
||||
// 完成报告生成
|
||||
err = report.CompleteGeneration(content)
|
||||
if err != nil {
|
||||
s.logger.Error("完成汇总报告生成失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("完成汇总报告生成失败: %w", err)
|
||||
}
|
||||
|
||||
// 保存报告
|
||||
err = s.reportRepo.Save(ctx, report)
|
||||
if err != nil {
|
||||
s.logger.Error("保存汇总报告失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("保存汇总报告失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("汇总报告生成成功",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.String("period", period))
|
||||
|
||||
return report, nil
|
||||
}
|
||||
|
||||
// GenerateDetailedReport 生成详细报告
|
||||
func (s *StatisticsReportServiceImpl) GenerateDetailedReport(ctx context.Context, reportType string, startDate, endDate time.Time, filters map[string]interface{}) (*entities.StatisticsReport, error) {
|
||||
if reportType == "" {
|
||||
return nil, fmt.Errorf("报告类型不能为空")
|
||||
}
|
||||
|
||||
// 创建报告实体
|
||||
title := fmt.Sprintf("详细报告 - %s (%s 至 %s)",
|
||||
reportType,
|
||||
startDate.Format("2006-01-02"),
|
||||
endDate.Format("2006-01-02"))
|
||||
report, err := entities.NewStatisticsReport("detailed", title, "custom", "admin")
|
||||
if err != nil {
|
||||
s.logger.Error("创建详细报告失败",
|
||||
zap.String("report_type", reportType),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("创建详细报告失败: %w", err)
|
||||
}
|
||||
|
||||
// 生成报告内容
|
||||
content, err := s.generateDetailedContent(ctx, reportType, startDate, endDate, filters)
|
||||
if err != nil {
|
||||
s.logger.Error("生成详细报告内容失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("生成详细报告内容失败: %w", err)
|
||||
}
|
||||
|
||||
// 完成报告生成
|
||||
err = report.CompleteGeneration(content)
|
||||
if err != nil {
|
||||
s.logger.Error("完成详细报告生成失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("完成详细报告生成失败: %w", err)
|
||||
}
|
||||
|
||||
// 保存报告
|
||||
err = s.reportRepo.Save(ctx, report)
|
||||
if err != nil {
|
||||
s.logger.Error("保存详细报告失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("保存详细报告失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("详细报告生成成功",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.String("report_type", reportType))
|
||||
|
||||
return report, nil
|
||||
}
|
||||
|
||||
// GetReport 获取报告
|
||||
func (s *StatisticsReportServiceImpl) GetReport(ctx context.Context, reportID string) (*entities.StatisticsReport, error) {
|
||||
if reportID == "" {
|
||||
return nil, fmt.Errorf("报告ID不能为空")
|
||||
}
|
||||
|
||||
report, err := s.reportRepo.FindByID(ctx, reportID)
|
||||
if err != nil {
|
||||
s.logger.Error("查询报告失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("查询报告失败: %w", err)
|
||||
}
|
||||
|
||||
return report, nil
|
||||
}
|
||||
|
||||
// GetReportsByUser 获取用户的报告列表
|
||||
func (s *StatisticsReportServiceImpl) GetReportsByUser(ctx context.Context, userID string, limit, offset int) ([]*entities.StatisticsReport, error) {
|
||||
if userID == "" {
|
||||
return nil, fmt.Errorf("用户ID不能为空")
|
||||
}
|
||||
|
||||
reports, err := s.reportRepo.FindByUser(ctx, userID, limit, offset)
|
||||
if err != nil {
|
||||
s.logger.Error("查询用户报告失败",
|
||||
zap.String("user_id", userID),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("查询用户报告失败: %w", err)
|
||||
}
|
||||
|
||||
return reports, nil
|
||||
}
|
||||
|
||||
// DeleteReport 删除报告
|
||||
func (s *StatisticsReportServiceImpl) DeleteReport(ctx context.Context, reportID string) error {
|
||||
if reportID == "" {
|
||||
return fmt.Errorf("报告ID不能为空")
|
||||
}
|
||||
|
||||
err := s.reportRepo.Delete(ctx, reportID)
|
||||
if err != nil {
|
||||
s.logger.Error("删除报告失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("删除报告失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("报告删除成功", zap.String("report_id", reportID))
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartReportGeneration 开始报告生成
|
||||
func (s *StatisticsReportServiceImpl) StartReportGeneration(ctx context.Context, reportID, generatedBy string) error {
|
||||
if reportID == "" {
|
||||
return fmt.Errorf("报告ID不能为空")
|
||||
}
|
||||
if generatedBy == "" {
|
||||
return fmt.Errorf("生成者ID不能为空")
|
||||
}
|
||||
|
||||
report, err := s.reportRepo.FindByID(ctx, reportID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询报告失败: %w", err)
|
||||
}
|
||||
|
||||
err = report.StartGeneration(generatedBy)
|
||||
if err != nil {
|
||||
s.logger.Error("开始报告生成失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("开始报告生成失败: %w", err)
|
||||
}
|
||||
|
||||
err = s.reportRepo.Save(ctx, report)
|
||||
if err != nil {
|
||||
s.logger.Error("保存报告状态失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("保存报告状态失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("报告生成开始",
|
||||
zap.String("report_id", reportID),
|
||||
zap.String("generated_by", generatedBy))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CompleteReportGeneration 完成报告生成
|
||||
func (s *StatisticsReportServiceImpl) CompleteReportGeneration(ctx context.Context, reportID string, content string) error {
|
||||
if reportID == "" {
|
||||
return fmt.Errorf("报告ID不能为空")
|
||||
}
|
||||
if content == "" {
|
||||
return fmt.Errorf("报告内容不能为空")
|
||||
}
|
||||
|
||||
report, err := s.reportRepo.FindByID(ctx, reportID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询报告失败: %w", err)
|
||||
}
|
||||
|
||||
err = report.CompleteGeneration(content)
|
||||
if err != nil {
|
||||
s.logger.Error("完成报告生成失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("完成报告生成失败: %w", err)
|
||||
}
|
||||
|
||||
err = s.reportRepo.Save(ctx, report)
|
||||
if err != nil {
|
||||
s.logger.Error("保存报告内容失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("保存报告内容失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("报告生成完成", zap.String("report_id", reportID))
|
||||
return nil
|
||||
}
|
||||
|
||||
// FailReportGeneration 报告生成失败
|
||||
func (s *StatisticsReportServiceImpl) FailReportGeneration(ctx context.Context, reportID string, reason string) error {
|
||||
if reportID == "" {
|
||||
return fmt.Errorf("报告ID不能为空")
|
||||
}
|
||||
|
||||
report, err := s.reportRepo.FindByID(ctx, reportID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询报告失败: %w", err)
|
||||
}
|
||||
|
||||
err = report.FailGeneration(reason)
|
||||
if err != nil {
|
||||
s.logger.Error("标记报告生成失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("标记报告生成失败: %w", err)
|
||||
}
|
||||
|
||||
err = s.reportRepo.Save(ctx, report)
|
||||
if err != nil {
|
||||
s.logger.Error("保存报告状态失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("保存报告状态失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("报告生成失败",
|
||||
zap.String("report_id", reportID),
|
||||
zap.String("reason", reason))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupExpiredReports 清理过期报告
|
||||
func (s *StatisticsReportServiceImpl) CleanupExpiredReports(ctx context.Context) error {
|
||||
s.logger.Info("开始清理过期报告")
|
||||
|
||||
// 获取所有已完成的报告
|
||||
reports, err := s.reportRepo.FindByStatus(ctx, "completed")
|
||||
if err != nil {
|
||||
s.logger.Error("查询已完成报告失败", zap.Error(err))
|
||||
return fmt.Errorf("查询已完成报告失败: %w", err)
|
||||
}
|
||||
|
||||
var deletedCount int
|
||||
for _, report := range reports {
|
||||
if report.IsExpired() {
|
||||
err = report.MarkAsExpired()
|
||||
if err != nil {
|
||||
s.logger.Error("标记报告过期失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
err = s.reportRepo.Save(ctx, report)
|
||||
if err != nil {
|
||||
s.logger.Error("保存过期报告状态失败",
|
||||
zap.String("report_id", report.ID),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
deletedCount++
|
||||
}
|
||||
}
|
||||
|
||||
s.logger.Info("过期报告清理完成", zap.Int("deleted_count", deletedCount))
|
||||
return nil
|
||||
}
|
||||
|
||||
// generateSummaryContent 生成汇总报告内容
|
||||
func (s *StatisticsReportServiceImpl) generateSummaryContent(ctx context.Context, startDate, endDate time.Time) (string, error) {
|
||||
content := make(map[string]interface{})
|
||||
|
||||
// API调用统计
|
||||
apiCallsTotal, err := s.calcService.CalculateTotal(ctx, "api_calls", "total_count", startDate, endDate)
|
||||
if err != nil {
|
||||
s.logger.Warn("计算API调用总数失败", zap.Error(err))
|
||||
}
|
||||
apiCallsSuccess, err := s.calcService.CalculateTotal(ctx, "api_calls", "success_count", startDate, endDate)
|
||||
if err != nil {
|
||||
s.logger.Warn("计算API调用成功数失败", zap.Error(err))
|
||||
}
|
||||
|
||||
// 用户统计
|
||||
usersTotal, err := s.calcService.CalculateTotal(ctx, "users", "total_count", startDate, endDate)
|
||||
if err != nil {
|
||||
s.logger.Warn("计算用户总数失败", zap.Error(err))
|
||||
}
|
||||
usersCertified, err := s.calcService.CalculateTotal(ctx, "users", "certified_count", startDate, endDate)
|
||||
if err != nil {
|
||||
s.logger.Warn("计算认证用户数失败", zap.Error(err))
|
||||
}
|
||||
|
||||
// 财务统计
|
||||
financeTotal, err := s.calcService.CalculateTotal(ctx, "finance", "total_amount", startDate, endDate)
|
||||
if err != nil {
|
||||
s.logger.Warn("计算财务总额失败", zap.Error(err))
|
||||
}
|
||||
|
||||
content["api_calls"] = map[string]interface{}{
|
||||
"total": apiCallsTotal,
|
||||
"success": apiCallsSuccess,
|
||||
"rate": s.calculateRate(apiCallsSuccess, apiCallsTotal),
|
||||
}
|
||||
|
||||
content["users"] = map[string]interface{}{
|
||||
"total": usersTotal,
|
||||
"certified": usersCertified,
|
||||
"rate": s.calculateRate(usersCertified, usersTotal),
|
||||
}
|
||||
|
||||
content["finance"] = map[string]interface{}{
|
||||
"total_amount": financeTotal,
|
||||
}
|
||||
|
||||
content["period"] = map[string]interface{}{
|
||||
"start_date": startDate.Format("2006-01-02"),
|
||||
"end_date": endDate.Format("2006-01-02"),
|
||||
}
|
||||
|
||||
content["generated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
|
||||
// 转换为JSON字符串
|
||||
jsonContent, err := json.Marshal(content)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("序列化报告内容失败: %w", err)
|
||||
}
|
||||
|
||||
return string(jsonContent), nil
|
||||
}
|
||||
|
||||
// generateDetailedContent 生成详细报告内容
|
||||
func (s *StatisticsReportServiceImpl) generateDetailedContent(ctx context.Context, reportType string, startDate, endDate time.Time, filters map[string]interface{}) (string, error) {
|
||||
content := make(map[string]interface{})
|
||||
|
||||
// 根据报告类型生成不同的内容
|
||||
switch reportType {
|
||||
case "api_calls":
|
||||
content = s.generateApiCallsDetailedContent(ctx, startDate, endDate, filters)
|
||||
case "users":
|
||||
content = s.generateUsersDetailedContent(ctx, startDate, endDate, filters)
|
||||
case "finance":
|
||||
content = s.generateFinanceDetailedContent(ctx, startDate, endDate, filters)
|
||||
default:
|
||||
return "", fmt.Errorf("不支持的报告类型: %s", reportType)
|
||||
}
|
||||
|
||||
content["report_type"] = reportType
|
||||
content["period"] = map[string]interface{}{
|
||||
"start_date": startDate.Format("2006-01-02"),
|
||||
"end_date": endDate.Format("2006-01-02"),
|
||||
}
|
||||
content["generated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
|
||||
// 转换为JSON字符串
|
||||
jsonContent, err := json.Marshal(content)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("序列化报告内容失败: %w", err)
|
||||
}
|
||||
|
||||
return string(jsonContent), nil
|
||||
}
|
||||
|
||||
// generateApiCallsDetailedContent 生成API调用详细内容
|
||||
func (s *StatisticsReportServiceImpl) generateApiCallsDetailedContent(ctx context.Context, startDate, endDate time.Time, filters map[string]interface{}) map[string]interface{} {
|
||||
content := make(map[string]interface{})
|
||||
|
||||
// 获取API调用统计数据
|
||||
totalCalls, _ := s.calcService.CalculateTotal(ctx, "api_calls", "total_count", startDate, endDate)
|
||||
successCalls, _ := s.calcService.CalculateTotal(ctx, "api_calls", "success_count", startDate, endDate)
|
||||
failedCalls, _ := s.calcService.CalculateTotal(ctx, "api_calls", "failed_count", startDate, endDate)
|
||||
avgResponseTime, _ := s.calcService.CalculateAverage(ctx, "api_calls", "response_time", startDate, endDate)
|
||||
|
||||
content["total_calls"] = totalCalls
|
||||
content["success_calls"] = successCalls
|
||||
content["failed_calls"] = failedCalls
|
||||
content["success_rate"] = s.calculateRate(successCalls, totalCalls)
|
||||
content["avg_response_time"] = avgResponseTime
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
// generateUsersDetailedContent 生成用户详细内容
|
||||
func (s *StatisticsReportServiceImpl) generateUsersDetailedContent(ctx context.Context, startDate, endDate time.Time, filters map[string]interface{}) map[string]interface{} {
|
||||
content := make(map[string]interface{})
|
||||
|
||||
// 获取用户统计数据
|
||||
totalUsers, _ := s.calcService.CalculateTotal(ctx, "users", "total_count", startDate, endDate)
|
||||
certifiedUsers, _ := s.calcService.CalculateTotal(ctx, "users", "certified_count", startDate, endDate)
|
||||
activeUsers, _ := s.calcService.CalculateTotal(ctx, "users", "active_count", startDate, endDate)
|
||||
|
||||
content["total_users"] = totalUsers
|
||||
content["certified_users"] = certifiedUsers
|
||||
content["active_users"] = activeUsers
|
||||
content["certification_rate"] = s.calculateRate(certifiedUsers, totalUsers)
|
||||
content["retention_rate"] = s.calculateRate(activeUsers, totalUsers)
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
// generateFinanceDetailedContent 生成财务详细内容
|
||||
func (s *StatisticsReportServiceImpl) generateFinanceDetailedContent(ctx context.Context, startDate, endDate time.Time, filters map[string]interface{}) map[string]interface{} {
|
||||
content := make(map[string]interface{})
|
||||
|
||||
// 获取财务统计数据
|
||||
totalAmount, _ := s.calcService.CalculateTotal(ctx, "finance", "total_amount", startDate, endDate)
|
||||
rechargeAmount, _ := s.calcService.CalculateTotal(ctx, "finance", "recharge_amount", startDate, endDate)
|
||||
deductAmount, _ := s.calcService.CalculateTotal(ctx, "finance", "deduct_amount", startDate, endDate)
|
||||
|
||||
content["total_amount"] = totalAmount
|
||||
content["recharge_amount"] = rechargeAmount
|
||||
content["deduct_amount"] = deductAmount
|
||||
content["net_amount"] = rechargeAmount - deductAmount
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
// calculateRate 计算比率
|
||||
func (s *StatisticsReportServiceImpl) calculateRate(numerator, denominator float64) float64 {
|
||||
if denominator == 0 {
|
||||
return 0
|
||||
}
|
||||
return (numerator / denominator) * 100
|
||||
}
|
||||
|
||||
// getRoleDisplayName 获取角色显示名称
|
||||
func (s *StatisticsReportServiceImpl) getRoleDisplayName(role string) string {
|
||||
roleNames := map[string]string{
|
||||
"admin": "管理员",
|
||||
"user": "用户",
|
||||
"manager": "经理",
|
||||
"analyst": "分析师",
|
||||
}
|
||||
if name, exists := roleNames[role]; exists {
|
||||
return name
|
||||
}
|
||||
return role
|
||||
}
|
||||
|
||||
// getPeriodDisplayName 获取周期显示名称
|
||||
func (s *StatisticsReportServiceImpl) getPeriodDisplayName(period string) string {
|
||||
periodNames := map[string]string{
|
||||
"today": "今日",
|
||||
"week": "本周",
|
||||
"month": "本月",
|
||||
"quarter": "本季度",
|
||||
"year": "本年",
|
||||
}
|
||||
if name, exists := periodNames[period]; exists {
|
||||
return name
|
||||
}
|
||||
return period
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user