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} }