245 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			245 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package entities | |||
|  | 
 | |||
|  | import ( | |||
|  | 	"errors" | |||
|  | 	"fmt" | |||
|  | 	"time" | |||
|  | 
 | |||
|  | 	"github.com/google/uuid" | |||
|  | 	"gorm.io/gorm" | |||
|  | ) | |||
|  | 
 | |||
|  | // StatisticsMetric 统计指标实体 | |||
|  | // 用于存储各种统计指标数据,支持多维度统计 | |||
|  | type StatisticsMetric struct { | |||
|  | 	// 基础标识 | |||
|  | 	ID         string    `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"统计指标唯一标识"` | |||
|  | 	MetricType string    `gorm:"type:varchar(50);not null;index" json:"metric_type" comment:"指标类型"` | |||
|  | 	MetricName string    `gorm:"type:varchar(100);not null" json:"metric_name" comment:"指标名称"` | |||
|  | 	Dimension  string    `gorm:"type:varchar(50)" json:"dimension" comment:"统计维度"` | |||
|  | 	Value      float64   `gorm:"type:decimal(20,4);not null" json:"value" comment:"指标值"` | |||
|  | 	Metadata   string    `gorm:"type:json" json:"metadata" comment:"额外维度信息"` | |||
|  | 	Date       time.Time `gorm:"type:date;index" json:"date" comment:"统计日期"` | |||
|  | 
 | |||
|  | 	// 时间戳字段 | |||
|  | 	CreatedAt time.Time      `gorm:"autoCreateTime" json:"created_at" comment:"创建时间"` | |||
|  | 	UpdatedAt time.Time      `gorm:"autoUpdateTime" json:"updated_at" comment:"更新时间"` | |||
|  | 	DeletedAt gorm.DeletedAt `gorm:"index" json:"-" comment:"软删除时间"` | |||
|  | 
 | |||
|  | 	// 领域事件 (不持久化) | |||
|  | 	domainEvents []interface{} `gorm:"-" json:"-"` | |||
|  | } | |||
|  | 
 | |||
|  | // TableName 指定数据库表名 | |||
|  | func (StatisticsMetric) TableName() string { | |||
|  | 	return "statistics_metrics" | |||
|  | } | |||
|  | 
 | |||
|  | // BeforeCreate GORM钩子:创建前自动生成UUID | |||
|  | func (s *StatisticsMetric) BeforeCreate(tx *gorm.DB) error { | |||
|  | 	if s.ID == "" { | |||
|  | 		s.ID = uuid.New().String() | |||
|  | 	} | |||
|  | 	return nil | |||
|  | } | |||
|  | 
 | |||
|  | // 实现 Entity 接口 - 提供统一的实体管理接口 | |||
|  | // GetID 获取实体唯一标识 | |||
|  | func (s *StatisticsMetric) GetID() string { | |||
|  | 	return s.ID | |||
|  | } | |||
|  | 
 | |||
|  | // GetCreatedAt 获取创建时间 | |||
|  | func (s *StatisticsMetric) GetCreatedAt() time.Time { | |||
|  | 	return s.CreatedAt | |||
|  | } | |||
|  | 
 | |||
|  | // GetUpdatedAt 获取更新时间 | |||
|  | func (s *StatisticsMetric) GetUpdatedAt() time.Time { | |||
|  | 	return s.UpdatedAt | |||
|  | } | |||
|  | 
 | |||
|  | // Validate 验证统计指标信息 | |||
|  | // 检查统计指标必填字段是否完整,确保数据的有效性 | |||
|  | func (s *StatisticsMetric) Validate() error { | |||
|  | 	if s.MetricType == "" { | |||
|  | 		return NewValidationError("指标类型不能为空") | |||
|  | 	} | |||
|  | 	if s.MetricName == "" { | |||
|  | 		return NewValidationError("指标名称不能为空") | |||
|  | 	} | |||
|  | 	if s.Value < 0 { | |||
|  | 		return NewValidationError("指标值不能为负数") | |||
|  | 	} | |||
|  | 	if s.Date.IsZero() { | |||
|  | 		return NewValidationError("统计日期不能为空") | |||
|  | 	} | |||
|  | 
 | |||
|  | 	// 验证指标类型 | |||
|  | 	if !s.IsValidMetricType() { | |||
|  | 		return NewValidationError("无效的指标类型") | |||
|  | 	} | |||
|  | 
 | |||
|  | 	return nil | |||
|  | } | |||
|  | 
 | |||
|  | // IsValidMetricType 检查指标类型是否有效 | |||
|  | func (s *StatisticsMetric) IsValidMetricType() bool { | |||
|  | 	validTypes := []string{ | |||
|  | 		"api_calls",      // API调用统计 | |||
|  | 		"users",          // 用户统计 | |||
|  | 		"finance",        // 财务统计 | |||
|  | 		"products",       // 产品统计 | |||
|  | 		"certification",  // 认证统计 | |||
|  | 	} | |||
|  | 
 | |||
|  | 	for _, validType := range validTypes { | |||
|  | 		if s.MetricType == validType { | |||
|  | 			return true | |||
|  | 		} | |||
|  | 	} | |||
|  | 	return false | |||
|  | } | |||
|  | 
 | |||
|  | // GetMetricTypeName 获取指标类型的中文名称 | |||
|  | func (s *StatisticsMetric) GetMetricTypeName() string { | |||
|  | 	typeNames := map[string]string{ | |||
|  | 		"api_calls":     "API调用统计", | |||
|  | 		"users":          "用户统计", | |||
|  | 		"finance":        "财务统计", | |||
|  | 		"products":       "产品统计", | |||
|  | 		"certification":  "认证统计", | |||
|  | 	} | |||
|  | 
 | |||
|  | 	if name, exists := typeNames[s.MetricType]; exists { | |||
|  | 		return name | |||
|  | 	} | |||
|  | 	return s.MetricType | |||
|  | } | |||
|  | 
 | |||
|  | // GetFormattedValue 获取格式化的指标值 | |||
|  | func (s *StatisticsMetric) GetFormattedValue() string { | |||
|  | 	// 根据指标类型格式化数值 | |||
|  | 	switch s.MetricType { | |||
|  | 	case "api_calls", "users": | |||
|  | 		return fmt.Sprintf("%.0f", s.Value) | |||
|  | 	case "finance": | |||
|  | 		return fmt.Sprintf("%.2f", s.Value) | |||
|  | 	default: | |||
|  | 		return fmt.Sprintf("%.4f", s.Value) | |||
|  | 	} | |||
|  | } | |||
|  | 
 | |||
|  | // NewStatisticsMetric 工厂方法 - 创建统计指标 | |||
|  | func NewStatisticsMetric(metricType, metricName, dimension string, value float64, date time.Time) (*StatisticsMetric, error) { | |||
|  | 	if metricType == "" { | |||
|  | 		return nil, errors.New("指标类型不能为空") | |||
|  | 	} | |||
|  | 	if metricName == "" { | |||
|  | 		return nil, errors.New("指标名称不能为空") | |||
|  | 	} | |||
|  | 	if value < 0 { | |||
|  | 		return nil, errors.New("指标值不能为负数") | |||
|  | 	} | |||
|  | 	if date.IsZero() { | |||
|  | 		return nil, errors.New("统计日期不能为空") | |||
|  | 	} | |||
|  | 
 | |||
|  | 	metric := &StatisticsMetric{ | |||
|  | 		MetricType: metricType, | |||
|  | 		MetricName: metricName, | |||
|  | 		Dimension:  dimension, | |||
|  | 		Value:      value, | |||
|  | 		Date:       date, | |||
|  | 		domainEvents: make([]interface{}, 0), | |||
|  | 	} | |||
|  | 
 | |||
|  | 	// 验证指标 | |||
|  | 	if err := metric.Validate(); err != nil { | |||
|  | 		return nil, err | |||
|  | 	} | |||
|  | 
 | |||
|  | 	// 添加领域事件 | |||
|  | 	metric.addDomainEvent(&StatisticsMetricCreatedEvent{ | |||
|  | 		MetricID:   metric.ID, | |||
|  | 		MetricType: metricType, | |||
|  | 		MetricName: metricName, | |||
|  | 		Value:      value, | |||
|  | 		CreatedAt:  time.Now(), | |||
|  | 	}) | |||
|  | 
 | |||
|  | 	return metric, nil | |||
|  | } | |||
|  | 
 | |||
|  | // UpdateValue 更新指标值 | |||
|  | func (s *StatisticsMetric) UpdateValue(newValue float64) error { | |||
|  | 	if newValue < 0 { | |||
|  | 		return NewValidationError("指标值不能为负数") | |||
|  | 	} | |||
|  | 
 | |||
|  | 	oldValue := s.Value | |||
|  | 	s.Value = newValue | |||
|  | 
 | |||
|  | 	// 添加领域事件 | |||
|  | 	s.addDomainEvent(&StatisticsMetricUpdatedEvent{ | |||
|  | 		MetricID:  s.ID, | |||
|  | 		OldValue:  oldValue, | |||
|  | 		NewValue:  newValue, | |||
|  | 		UpdatedAt: time.Now(), | |||
|  | 	}) | |||
|  | 
 | |||
|  | 	return nil | |||
|  | } | |||
|  | 
 | |||
|  | // ================ 领域事件管理 ================ | |||
|  | 
 | |||
|  | // addDomainEvent 添加领域事件 | |||
|  | func (s *StatisticsMetric) addDomainEvent(event interface{}) { | |||
|  | 	if s.domainEvents == nil { | |||
|  | 		s.domainEvents = make([]interface{}, 0) | |||
|  | 	} | |||
|  | 	s.domainEvents = append(s.domainEvents, event) | |||
|  | } | |||
|  | 
 | |||
|  | // GetDomainEvents 获取领域事件 | |||
|  | func (s *StatisticsMetric) GetDomainEvents() []interface{} { | |||
|  | 	return s.domainEvents | |||
|  | } | |||
|  | 
 | |||
|  | // ClearDomainEvents 清除领域事件 | |||
|  | func (s *StatisticsMetric) ClearDomainEvents() { | |||
|  | 	s.domainEvents = make([]interface{}, 0) | |||
|  | } | |||
|  | 
 | |||
|  | // ================ 领域事件定义 ================ | |||
|  | 
 | |||
|  | // StatisticsMetricCreatedEvent 统计指标创建事件 | |||
|  | type StatisticsMetricCreatedEvent struct { | |||
|  | 	MetricID   string    `json:"metric_id"` | |||
|  | 	MetricType string    `json:"metric_type"` | |||
|  | 	MetricName string    `json:"metric_name"` | |||
|  | 	Value      float64   `json:"value"` | |||
|  | 	CreatedAt  time.Time `json:"created_at"` | |||
|  | } | |||
|  | 
 | |||
|  | // StatisticsMetricUpdatedEvent 统计指标更新事件 | |||
|  | type StatisticsMetricUpdatedEvent struct { | |||
|  | 	MetricID  string    `json:"metric_id"` | |||
|  | 	OldValue  float64   `json:"old_value"` | |||
|  | 	NewValue  float64   `json:"new_value"` | |||
|  | 	UpdatedAt time.Time `json:"updated_at"` | |||
|  | } | |||
|  | 
 | |||
|  | // ValidationError 验证错误 | |||
|  | type ValidationError struct { | |||
|  | 	Message string | |||
|  | } | |||
|  | 
 | |||
|  | func (e *ValidationError) Error() string { | |||
|  | 	return e.Message | |||
|  | } | |||
|  | 
 | |||
|  | func NewValidationError(message string) *ValidationError { | |||
|  | 	return &ValidationError{Message: message} | |||
|  | } |