Files

75 lines
3.5 KiB
Go

package model
import (
"encoding/json"
"time"
)
// Consultation 专家会诊单
type Consultation struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
RoomID *string `gorm:"column:room_id;type:uuid;index" json:"roomId,omitempty"`
BatchID *string `gorm:"column:batch_id;type:uuid;index" json:"batchId,omitempty"`
LampTestID *string `gorm:"column:lamp_test_id;type:uuid;index" json:"lampTestId,omitempty"`
Title string `gorm:"size:128" json:"title"`
Summary *string `gorm:"type:text" json:"summary,omitempty"`
Snapshot json.RawMessage `gorm:"type:jsonb" json:"snapshot,omitempty"`
Status string `gorm:"size:16;default:pending" json:"status"` // pending/consulting/resolved/archived
ExpertID *string `gorm:"column:expert_id;type:uuid" json:"expertId,omitempty"`
AssigneeID *string `gorm:"column:assignee_id;type:uuid" json:"assigneeId,omitempty"`
AssignedAt *time.Time `gorm:"column:assigned_at;type:timestamptz" json:"assignedAt,omitempty"`
AcceptedAt *time.Time `gorm:"column:accepted_at;type:timestamptz" json:"acceptedAt,omitempty"`
NeedsInfoAt *time.Time `gorm:"column:needs_info_at;type:timestamptz" json:"needsInfoAt,omitempty"`
SLADeadline *time.Time `gorm:"column:sla_deadline;type:timestamptz" json:"slaDeadline,omitempty"`
OverdueAt *time.Time `gorm:"column:overdue_at;type:timestamptz" json:"overdueAt,omitempty"`
LastSLAEventAt *time.Time `gorm:"column:last_sla_event_at;type:timestamptz" json:"lastSlaEventAt,omitempty"`
Opinion *string `gorm:"type:text" json:"opinion,omitempty"`
Plan *string `gorm:"type:text" json:"plan,omitempty"`
ResolvedAt *time.Time `gorm:"column:resolved_at;type:timestamptz" json:"resolvedAt,omitempty"`
ArchivedAt *time.Time `gorm:"column:archived_at;type:timestamptz" json:"archivedAt,omitempty"`
CreatedAt time.Time `gorm:"type:timestamptz" json:"createdAt"`
UpdatedAt time.Time `gorm:"type:timestamptz" json:"updatedAt"`
RoomName *string `gorm:"-" json:"roomName,omitempty"`
}
func (Consultation) TableName() string { return "consultations" }
// ValidConsultationTransition 状态流转规则:unassigned/assigned/accepted/needs_info/resolved/archived。
func ValidConsultationTransition(from, to string) bool {
switch from {
case "unassigned":
return to == "assigned"
case "assigned":
return to == "accepted" || to == "needs_info"
case "accepted":
return to == "needs_info" || to == "resolved"
case "needs_info":
return to == "accepted" || to == "resolved"
case "resolved":
return to == "archived" || to == "needs_info"
default:
return false
}
}
// ConsultationSLAState 返回会诊 SLA 状态;超时只标记,不自动伪造专家结论。
func ConsultationSLAState(t Consultation, now time.Time) string {
if t.SLADeadline == nil {
return "unscheduled"
}
if now.After(*t.SLADeadline) {
return "overdue"
}
return "on_time"
}
// ConsultationSnapshot 病例快照(会诊时打包,避免引用数据变化)
type ConsultationSnapshot struct {
RoomName string `json:"roomName,omitempty"`
LampTest *LampTest `json:"lampTest,omitempty"`
Inspection *InspectionRecord `json:"inspection,omitempty"`
Batch *Batch `json:"batch,omitempty"`
WeatherAlerts []WeatherAlert `json:"weatherAlerts,omitempty"`
CreatedAt time.Time `json:"createdAt"`
}