package model import ( "encoding/json" "errors" "time" ) // DiseaseEvent 独立发病事件,作为处置、会诊、溯源和效果评估主线。 type DiseaseEvent struct { ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"` SourceKey string `gorm:"column:source_key;size:128;uniqueIndex" json:"sourceKey,omitempty"` RoomID *string `gorm:"column:room_id;type:uuid;index" json:"roomId,omitempty"` BatchID *string `gorm:"column:batch_id;type:uuid;index" json:"batchId,omitempty"` DetectionTaskID *string `gorm:"column:detection_task_id;type:uuid;index" json:"detectionTaskId,omitempty"` LampTestID *string `gorm:"column:lamp_test_id;type:uuid;index" json:"lampTestId,omitempty"` ConsultationID *string `gorm:"column:consultation_id;type:uuid;index" json:"consultationId,omitempty"` InspectionID *string `gorm:"column:inspection_id;type:uuid;index" json:"inspectionId,omitempty"` Disease string `gorm:"size:64" json:"disease"` Status string `gorm:"size:16;default:suspected;index" json:"status"` Evidence json.RawMessage `gorm:"type:jsonb" json:"evidence,omitempty"` ConfirmedAt *time.Time `gorm:"column:confirmed_at;type:timestamptz" json:"confirmedAt,omitempty"` ConfirmedBy *string `gorm:"column:confirmed_by;type:uuid" json:"confirmedBy,omitempty"` LossSummary *string `gorm:"column:loss_summary;type:text" json:"lossSummary,omitempty"` Measure *string `gorm:"type:text" json:"measure,omitempty"` Note *string `gorm:"type:text" json:"note,omitempty"` CreatedAt time.Time `gorm:"type:timestamptz" json:"createdAt"` UpdatedAt time.Time `gorm:"type:timestamptz" json:"updatedAt"` RoomName *string `gorm:"-" json:"roomName,omitempty"` } func (DiseaseEvent) TableName() string { return "disease_events" } // ValidDiseaseEventTransition 状态机:suspected/confirmed/controlled/closed/reopened。 func ValidDiseaseEventTransition(from, to string) bool { switch from { case "suspected": return to == "confirmed" || to == "closed" case "confirmed": return to == "controlled" || to == "closed" case "controlled": return to == "closed" || to == "reopened" case "closed": return to == "reopened" case "reopened": return to == "confirmed" || to == "controlled" || to == "closed" default: return false } } // ValidateDiseaseEventEvidence 确诊必须有证据,不能仅凭状态字段确认。 func ValidateDiseaseEventEvidence(event DiseaseEvent) error { if event.Status == "confirmed" && len(event.Evidence) == 0 { return errors.New("确诊发病事件必须提供证据") } return nil }