Files
license-manager/backend/internal/service/dashboard_service.go
T

174 lines
5.3 KiB
Go

package service
import (
"context"
"fmt"
"time"
"license-manager/internal/models"
"license-manager/internal/repository"
pkgcontext "license-manager/pkg/context"
"license-manager/pkg/i18n"
)
type dashboardService struct {
dashboardRepo repository.DashboardRepository
}
// NewDashboardService 创建仪表盘服务实例
func NewDashboardService(dashboardRepo repository.DashboardRepository) DashboardService {
return &dashboardService{
dashboardRepo: dashboardRepo,
}
}
// GetAuthorizationTrend 获取授权趋势数据
func (s *dashboardService) GetAuthorizationTrend(ctx context.Context, req *models.DashboardAuthorizationTrendRequest) (*models.DashboardAuthorizationTrendResponse, error) {
lang := pkgcontext.GetLanguageFromContext(ctx)
// 业务逻辑:参数验证
if req == nil {
return nil, i18n.NewI18nError("900001", lang)
}
var startDate, endDate time.Time
var descriptionDisplay string
// 获取时区,默认使用本地时区
loc := time.Local
if req.Timezone != "" {
var err error
loc, err = time.LoadLocation(req.Timezone)
if err != nil {
// 时区解析失败,使用本地时区
loc = time.Local
}
}
now := time.Now().In(loc)
// 根据类型计算时间范围
switch req.Type {
case "week":
// 本周:从周一到周日
weekday := int(now.Weekday())
if weekday == 0 { // Sunday
weekday = 7
}
startDate = now.AddDate(0, 0, -(weekday-1))
startDate = time.Date(startDate.Year(), startDate.Month(), startDate.Day(), 0, 0, 0, 0, loc)
endDate = startDate.AddDate(0, 0, 6)
endDate = time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 23, 59, 59, 999999999, loc)
descriptionDisplay = i18n.GetEnumMessage("dashboard_period", "week", lang)
case "month":
// 本月:从1号到月末
startDate = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc)
endDate = startDate.AddDate(0, 1, -1)
endDate = time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 23, 59, 59, 999999999, loc)
descriptionDisplay = i18n.GetEnumMessage("dashboard_period", "month", lang)
case "custom":
// 自定义时间范围
if req.StartDate == "" || req.EndDate == "" {
return nil, i18n.NewI18nError("400002", lang) // 开始日期和结束日期都是必填的
}
var err error
startDate, err = time.ParseInLocation("2006-01-02", req.StartDate, loc)
if err != nil {
return nil, i18n.NewI18nError("400002", lang) // 开始日期格式错误
}
endDate, err = time.ParseInLocation("2006-01-02", req.EndDate, loc)
if err != nil {
return nil, i18n.NewI18nError("400003", lang) // 结束日期格式错误
}
// 验证时间范围
if startDate.After(endDate) {
return nil, i18n.NewI18nError("400005", lang) // 开始日期不能晚于结束日期
}
// 验证时间跨度不超过一年
if endDate.Sub(startDate) > 365*24*time.Hour {
return nil, i18n.NewI18nError("400004", lang) // 时间范围超过限制
}
// 设置为全天
startDate = time.Date(startDate.Year(), startDate.Month(), startDate.Day(), 0, 0, 0, 0, startDate.Location())
endDate = time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 23, 59, 59, 999999999, endDate.Location())
descriptionDisplay = fmt.Sprintf("%s - %s", req.StartDate, req.EndDate)
default:
return nil, i18n.NewI18nError("400001", lang) // 时间类型参数错误
}
// 获取趋势数据
trendData, err := s.dashboardRepo.GetAuthorizationTrendData(ctx, startDate, endDate)
if err != nil {
return nil, err
}
// 计算汇总信息
var totalCount, newCount, expiredCount int64
for _, data := range trendData {
newCount += data.NewAuthorizations
expiredCount += data.ExpiredAuthorizations
}
// 获取期间结束时的总授权数
if len(trendData) > 0 {
totalCount = trendData[len(trendData)-1].TotalAuthorizations
}
// 计算增长率(本期新增相对于期初的百分比)
var growthRate float64
if totalCount > 0 && newCount > 0 {
periodStartCount := totalCount - newCount
if periodStartCount > 0 {
growthRate = float64(newCount) / float64(periodStartCount) * 100
} else {
growthRate = 100.0 // 如果期初为0,则增长率为100%
}
}
return &models.DashboardAuthorizationTrendResponse{
Period: models.TrendPeriod{
Type: req.Type,
StartDate: startDate.Format("2006-01-02"),
EndDate: endDate.Format("2006-01-02"),
DescriptionDisplay: descriptionDisplay,
},
TrendData: trendData,
Summary: models.TrendSummary{
TotalCount: totalCount,
NewCount: newCount,
ExpiredCount: expiredCount,
GrowthRate: growthRate,
},
}, nil
}
// GetRecentAuthorizations 获取最近授权列表
func (s *dashboardService) GetRecentAuthorizations(ctx context.Context, req *models.DashboardRecentAuthorizationsRequest) (*models.DashboardRecentAuthorizationsResponse, error) {
lang := pkgcontext.GetLanguageFromContext(ctx)
// 业务逻辑:参数验证
if req == nil {
return nil, i18n.NewI18nError("900001", lang)
}
// 验证limit参数
if req.Limit < 0 || req.Limit > 100 {
return nil, i18n.NewI18nError("400006", lang) // 数量限制参数错误
}
// 验证status参数
if req.Status != "" && req.Status != "normal" && req.Status != "locked" && req.Status != "expired" {
return nil, i18n.NewI18nError("400001", lang) // 状态参数错误
}
// 调用repository获取数据
return s.dashboardRepo.GetRecentAuthorizations(ctx, req)
}