435 lines
11 KiB
Go
435 lines
11 KiB
Go
package entities
|
||
|
||
import (
|
||
"errors"
|
||
"time"
|
||
|
||
"github.com/google/uuid"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// StatisticsDashboard 仪表板配置实体
|
||
// 用于存储仪表板的配置信息
|
||
type StatisticsDashboard struct {
|
||
// 基础标识
|
||
ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"仪表板唯一标识"`
|
||
Name string `gorm:"type:varchar(100);not null" json:"name" comment:"仪表板名称"`
|
||
Description string `gorm:"type:text" json:"description" comment:"仪表板描述"`
|
||
UserRole string `gorm:"type:varchar(20);not null;index" json:"user_role" comment:"用户角色"`
|
||
IsDefault bool `gorm:"default:false" json:"is_default" comment:"是否为默认仪表板"`
|
||
IsActive bool `gorm:"default:true" json:"is_active" comment:"是否激活"`
|
||
|
||
// 仪表板配置
|
||
Layout string `gorm:"type:json" json:"layout" comment:"布局配置"`
|
||
Widgets string `gorm:"type:json" json:"widgets" comment:"组件配置"`
|
||
Settings string `gorm:"type:json" json:"settings" comment:"设置配置"`
|
||
RefreshInterval int `gorm:"default:300" json:"refresh_interval" comment:"刷新间隔(秒)"`
|
||
|
||
// 权限和访问控制
|
||
CreatedBy string `gorm:"type:varchar(36);not null" json:"created_by" comment:"创建者ID"`
|
||
AccessLevel string `gorm:"type:varchar(20);default:'private'" json:"access_level" 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 (StatisticsDashboard) TableName() string {
|
||
return "statistics_dashboards"
|
||
}
|
||
|
||
// BeforeCreate GORM钩子:创建前自动生成UUID
|
||
func (s *StatisticsDashboard) BeforeCreate(tx *gorm.DB) error {
|
||
if s.ID == "" {
|
||
s.ID = uuid.New().String()
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// 实现 Entity 接口 - 提供统一的实体管理接口
|
||
// GetID 获取实体唯一标识
|
||
func (s *StatisticsDashboard) GetID() string {
|
||
return s.ID
|
||
}
|
||
|
||
// GetCreatedAt 获取创建时间
|
||
func (s *StatisticsDashboard) GetCreatedAt() time.Time {
|
||
return s.CreatedAt
|
||
}
|
||
|
||
// GetUpdatedAt 获取更新时间
|
||
func (s *StatisticsDashboard) GetUpdatedAt() time.Time {
|
||
return s.UpdatedAt
|
||
}
|
||
|
||
// Validate 验证仪表板配置信息
|
||
// 检查仪表板必填字段是否完整,确保数据的有效性
|
||
func (s *StatisticsDashboard) Validate() error {
|
||
if s.Name == "" {
|
||
return NewValidationError("仪表板名称不能为空")
|
||
}
|
||
if s.UserRole == "" {
|
||
return NewValidationError("用户角色不能为空")
|
||
}
|
||
if s.CreatedBy == "" {
|
||
return NewValidationError("创建者ID不能为空")
|
||
}
|
||
|
||
// 验证用户角色
|
||
if !s.IsValidUserRole() {
|
||
return NewValidationError("无效的用户角色")
|
||
}
|
||
|
||
// 验证访问级别
|
||
if !s.IsValidAccessLevel() {
|
||
return NewValidationError("无效的访问级别")
|
||
}
|
||
|
||
// 验证刷新间隔
|
||
if s.RefreshInterval < 30 {
|
||
return NewValidationError("刷新间隔不能少于30秒")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// IsValidUserRole 检查用户角色是否有效
|
||
func (s *StatisticsDashboard) IsValidUserRole() bool {
|
||
validRoles := []string{
|
||
"admin", // 管理员
|
||
"user", // 普通用户
|
||
"manager", // 经理
|
||
"analyst", // 分析师
|
||
}
|
||
|
||
for _, validRole := range validRoles {
|
||
if s.UserRole == validRole {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// IsValidAccessLevel 检查访问级别是否有效
|
||
func (s *StatisticsDashboard) IsValidAccessLevel() bool {
|
||
validLevels := []string{
|
||
"private", // 私有
|
||
"public", // 公开
|
||
"shared", // 共享
|
||
}
|
||
|
||
for _, validLevel := range validLevels {
|
||
if s.AccessLevel == validLevel {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// GetUserRoleName 获取用户角色的中文名称
|
||
func (s *StatisticsDashboard) GetUserRoleName() string {
|
||
roleNames := map[string]string{
|
||
"admin": "管理员",
|
||
"user": "普通用户",
|
||
"manager": "经理",
|
||
"analyst": "分析师",
|
||
}
|
||
|
||
if name, exists := roleNames[s.UserRole]; exists {
|
||
return name
|
||
}
|
||
return s.UserRole
|
||
}
|
||
|
||
// GetAccessLevelName 获取访问级别的中文名称
|
||
func (s *StatisticsDashboard) GetAccessLevelName() string {
|
||
levelNames := map[string]string{
|
||
"private": "私有",
|
||
"public": "公开",
|
||
"shared": "共享",
|
||
}
|
||
|
||
if name, exists := levelNames[s.AccessLevel]; exists {
|
||
return name
|
||
}
|
||
return s.AccessLevel
|
||
}
|
||
|
||
// NewStatisticsDashboard 工厂方法 - 创建仪表板配置
|
||
func NewStatisticsDashboard(name, description, userRole, createdBy string) (*StatisticsDashboard, error) {
|
||
if name == "" {
|
||
return nil, errors.New("仪表板名称不能为空")
|
||
}
|
||
if userRole == "" {
|
||
return nil, errors.New("用户角色不能为空")
|
||
}
|
||
if createdBy == "" {
|
||
return nil, errors.New("创建者ID不能为空")
|
||
}
|
||
|
||
dashboard := &StatisticsDashboard{
|
||
Name: name,
|
||
Description: description,
|
||
UserRole: userRole,
|
||
CreatedBy: createdBy,
|
||
IsDefault: false,
|
||
IsActive: true,
|
||
AccessLevel: "private",
|
||
RefreshInterval: 300, // 默认5分钟
|
||
domainEvents: make([]interface{}, 0),
|
||
}
|
||
|
||
// 验证仪表板
|
||
if err := dashboard.Validate(); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 添加领域事件
|
||
dashboard.addDomainEvent(&StatisticsDashboardCreatedEvent{
|
||
DashboardID: dashboard.ID,
|
||
Name: name,
|
||
UserRole: userRole,
|
||
CreatedBy: createdBy,
|
||
CreatedAt: time.Now(),
|
||
})
|
||
|
||
return dashboard, nil
|
||
}
|
||
|
||
// SetAsDefault 设置为默认仪表板
|
||
func (s *StatisticsDashboard) SetAsDefault() error {
|
||
if !s.IsActive {
|
||
return NewValidationError("只有激活状态的仪表板才能设置为默认")
|
||
}
|
||
|
||
s.IsDefault = true
|
||
|
||
// 添加领域事件
|
||
s.addDomainEvent(&StatisticsDashboardSetAsDefaultEvent{
|
||
DashboardID: s.ID,
|
||
SetAt: time.Now(),
|
||
})
|
||
|
||
return nil
|
||
}
|
||
|
||
// RemoveAsDefault 取消默认状态
|
||
func (s *StatisticsDashboard) RemoveAsDefault() error {
|
||
if !s.IsDefault {
|
||
return NewValidationError("当前仪表板不是默认仪表板")
|
||
}
|
||
|
||
s.IsDefault = false
|
||
|
||
// 添加领域事件
|
||
s.addDomainEvent(&StatisticsDashboardRemovedAsDefaultEvent{
|
||
DashboardID: s.ID,
|
||
RemovedAt: time.Now(),
|
||
})
|
||
|
||
return nil
|
||
}
|
||
|
||
// Activate 激活仪表板
|
||
func (s *StatisticsDashboard) Activate() error {
|
||
if s.IsActive {
|
||
return NewValidationError("仪表板已经是激活状态")
|
||
}
|
||
|
||
s.IsActive = true
|
||
|
||
// 添加领域事件
|
||
s.addDomainEvent(&StatisticsDashboardActivatedEvent{
|
||
DashboardID: s.ID,
|
||
ActivatedAt: time.Now(),
|
||
})
|
||
|
||
return nil
|
||
}
|
||
|
||
// Deactivate 停用仪表板
|
||
func (s *StatisticsDashboard) Deactivate() error {
|
||
if !s.IsActive {
|
||
return NewValidationError("仪表板已经是停用状态")
|
||
}
|
||
|
||
s.IsActive = false
|
||
|
||
// 如果是默认仪表板,需要先取消默认状态
|
||
if s.IsDefault {
|
||
s.IsDefault = false
|
||
}
|
||
|
||
// 添加领域事件
|
||
s.addDomainEvent(&StatisticsDashboardDeactivatedEvent{
|
||
DashboardID: s.ID,
|
||
DeactivatedAt: time.Now(),
|
||
})
|
||
|
||
return nil
|
||
}
|
||
|
||
// UpdateLayout 更新布局配置
|
||
func (s *StatisticsDashboard) UpdateLayout(layout string) error {
|
||
if layout == "" {
|
||
return NewValidationError("布局配置不能为空")
|
||
}
|
||
|
||
s.Layout = layout
|
||
|
||
// 添加领域事件
|
||
s.addDomainEvent(&StatisticsDashboardLayoutUpdatedEvent{
|
||
DashboardID: s.ID,
|
||
UpdatedAt: time.Now(),
|
||
})
|
||
|
||
return nil
|
||
}
|
||
|
||
// UpdateWidgets 更新组件配置
|
||
func (s *StatisticsDashboard) UpdateWidgets(widgets string) error {
|
||
if widgets == "" {
|
||
return NewValidationError("组件配置不能为空")
|
||
}
|
||
|
||
s.Widgets = widgets
|
||
|
||
// 添加领域事件
|
||
s.addDomainEvent(&StatisticsDashboardWidgetsUpdatedEvent{
|
||
DashboardID: s.ID,
|
||
UpdatedAt: time.Now(),
|
||
})
|
||
|
||
return nil
|
||
}
|
||
|
||
// UpdateSettings 更新设置配置
|
||
func (s *StatisticsDashboard) UpdateSettings(settings string) error {
|
||
s.Settings = settings
|
||
|
||
// 添加领域事件
|
||
s.addDomainEvent(&StatisticsDashboardSettingsUpdatedEvent{
|
||
DashboardID: s.ID,
|
||
UpdatedAt: time.Now(),
|
||
})
|
||
|
||
return nil
|
||
}
|
||
|
||
// UpdateRefreshInterval 更新刷新间隔
|
||
func (s *StatisticsDashboard) UpdateRefreshInterval(interval int) error {
|
||
if interval < 30 {
|
||
return NewValidationError("刷新间隔不能少于30秒")
|
||
}
|
||
|
||
oldInterval := s.RefreshInterval
|
||
s.RefreshInterval = interval
|
||
|
||
// 添加领域事件
|
||
s.addDomainEvent(&StatisticsDashboardRefreshIntervalUpdatedEvent{
|
||
DashboardID: s.ID,
|
||
OldInterval: oldInterval,
|
||
NewInterval: interval,
|
||
UpdatedAt: time.Now(),
|
||
})
|
||
|
||
return nil
|
||
}
|
||
|
||
// CanBeModified 检查仪表板是否可以被修改
|
||
func (s *StatisticsDashboard) CanBeModified() bool {
|
||
return s.IsActive
|
||
}
|
||
|
||
// CanBeDeleted 检查仪表板是否可以被删除
|
||
func (s *StatisticsDashboard) CanBeDeleted() bool {
|
||
return !s.IsDefault && s.IsActive
|
||
}
|
||
|
||
// ================ 领域事件管理 ================
|
||
|
||
// addDomainEvent 添加领域事件
|
||
func (s *StatisticsDashboard) addDomainEvent(event interface{}) {
|
||
if s.domainEvents == nil {
|
||
s.domainEvents = make([]interface{}, 0)
|
||
}
|
||
s.domainEvents = append(s.domainEvents, event)
|
||
}
|
||
|
||
// GetDomainEvents 获取领域事件
|
||
func (s *StatisticsDashboard) GetDomainEvents() []interface{} {
|
||
return s.domainEvents
|
||
}
|
||
|
||
// ClearDomainEvents 清除领域事件
|
||
func (s *StatisticsDashboard) ClearDomainEvents() {
|
||
s.domainEvents = make([]interface{}, 0)
|
||
}
|
||
|
||
// ================ 领域事件定义 ================
|
||
|
||
// StatisticsDashboardCreatedEvent 仪表板创建事件
|
||
type StatisticsDashboardCreatedEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
Name string `json:"name"`
|
||
UserRole string `json:"user_role"`
|
||
CreatedBy string `json:"created_by"`
|
||
CreatedAt time.Time `json:"created_at"`
|
||
}
|
||
|
||
// StatisticsDashboardSetAsDefaultEvent 仪表板设置为默认事件
|
||
type StatisticsDashboardSetAsDefaultEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
SetAt time.Time `json:"set_at"`
|
||
}
|
||
|
||
// StatisticsDashboardRemovedAsDefaultEvent 仪表板取消默认事件
|
||
type StatisticsDashboardRemovedAsDefaultEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
RemovedAt time.Time `json:"removed_at"`
|
||
}
|
||
|
||
// StatisticsDashboardActivatedEvent 仪表板激活事件
|
||
type StatisticsDashboardActivatedEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
ActivatedAt time.Time `json:"activated_at"`
|
||
}
|
||
|
||
// StatisticsDashboardDeactivatedEvent 仪表板停用事件
|
||
type StatisticsDashboardDeactivatedEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
DeactivatedAt time.Time `json:"deactivated_at"`
|
||
}
|
||
|
||
// StatisticsDashboardLayoutUpdatedEvent 仪表板布局更新事件
|
||
type StatisticsDashboardLayoutUpdatedEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
UpdatedAt time.Time `json:"updated_at"`
|
||
}
|
||
|
||
// StatisticsDashboardWidgetsUpdatedEvent 仪表板组件更新事件
|
||
type StatisticsDashboardWidgetsUpdatedEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
UpdatedAt time.Time `json:"updated_at"`
|
||
}
|
||
|
||
// StatisticsDashboardSettingsUpdatedEvent 仪表板设置更新事件
|
||
type StatisticsDashboardSettingsUpdatedEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
UpdatedAt time.Time `json:"updated_at"`
|
||
}
|
||
|
||
// StatisticsDashboardRefreshIntervalUpdatedEvent 仪表板刷新间隔更新事件
|
||
type StatisticsDashboardRefreshIntervalUpdatedEvent struct {
|
||
DashboardID string `json:"dashboard_id"`
|
||
OldInterval int `json:"old_interval"`
|
||
NewInterval int `json:"new_interval"`
|
||
UpdatedAt time.Time `json:"updated_at"`
|
||
}
|
||
|