package service import ( "context" "encoding/json" "errors" "silk-server-go/internal/model" "gorm.io/gorm" "gorm.io/gorm/clause" ) // DetectionTaskCreatePayload 创建待确认检测任务的 outbox 载荷。 type DetectionTaskCreatePayload struct { SourceKey string `json:"sourceKey"` SourceType string `json:"sourceType"` SourceID string `json:"sourceId"` RoomID string `json:"roomId"` BatchID string `json:"batchId"` InspectionID string `json:"inspectionId"` Disease string `json:"disease"` Priority string `json:"priority"` } // NewDetectionTaskOutboxHandler 创建检测任务事件处理器。 func NewDetectionTaskOutboxHandler(db *gorm.DB) EventHandler { return func(ctx context.Context, event model.OutboxEvent) error { if event.EventType != OutboxEventDetectionTaskCreate { return nil } var payload DetectionTaskCreatePayload if err := json.Unmarshal(event.Payload, &payload); err != nil { return err } if payload.SourceKey == "" { return errors.New("detection task sourceKey is required") } disease := payload.Disease if disease == "" { disease = "待确认" } priority := payload.Priority if priority == "" { priority = "routine" } task := model.DetectionTask{ SourceKey: payload.SourceKey, SourceType: payload.SourceType, SourceID: payload.SourceID, RoomID: strPtrOrNil(payload.RoomID), BatchID: strPtrOrNil(payload.BatchID), InspectionID: strPtrOrNil(payload.InspectionID), Disease: disease, Priority: priority, Status: "pending", } return db.WithContext(ctx). Session(&gorm.Session{SkipDefaultTransaction: true}). Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "source_key"}}, DoNothing: true, }). Create(&task).Error } } // NewOutboxHandler 分发当前已支持的业务事件。 func NewOutboxHandler(db *gorm.DB, wechat *WechatService) EventHandler { wechatHandler := NewWechatOutboxHandler(db, wechat) detectionHandler := NewDetectionTaskOutboxHandler(db) return func(ctx context.Context, event model.OutboxEvent) error { switch event.EventType { case OutboxEventWechatSubscribe: return wechatHandler(ctx, event) case OutboxEventDetectionTaskCreate: return detectionHandler(ctx, event) default: return nil } } }