package chat import ( "errors" "gorm.io/gorm" "gorm.io/gorm/clause" "hfb_sys/backend/internal/model" "hfb_sys/backend/internal/modules/chathub" "time" ) type Repository struct { db *gorm.DB hub *chathub.Hub } const ( defaultSupportRoleCode = "cs" ) func NewRepository(db *gorm.DB, hub *chathub.Hub) *Repository { return &Repository{db: db, hub: hub} } func EnsureOrderConversation(tx *gorm.DB, order model.RentalOrder) (*model.ChatConversation, error) { var existing model.ChatConversation err := tx.Where("order_id = ?", order.ID).First(&existing).Error if err == nil { return &existing, nil } if !errors.Is(err, gorm.ErrRecordNotFound) { return nil, err } now := time.Now() conversation := model.ChatConversation{ OrderID: &order.ID, Type: "order_group", Title: orderConversationTitle(order), Status: "active", } if err := tx.Create(&conversation).Error; err != nil { return nil, err } participants := []model.ChatParticipant{ { ConversationID: conversation.ID, ParticipantType: "user", ParticipantID: order.RenterID, Role: "renter", JoinedAt: now, }, { ConversationID: conversation.ID, ParticipantType: "user", ParticipantID: order.OwnerID, Role: "owner", JoinedAt: now, }, } if supportID := defaultSupportAdminID(tx); supportID > 0 { participants = append(participants, model.ChatParticipant{ ConversationID: conversation.ID, ParticipantType: "admin", ParticipantID: supportID, Role: "support", JoinedAt: now, }) } for _, participant := range participants { if err := tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&participant).Error; err != nil { return nil, err } } // 获取自动话术 autoMessage := "订单已支付,群聊已创建。租客、号主和客服可在这里沟通交接与结账问题。" var cfg model.SystemConfig if err := tx.Where("`key` = ?", "chat.auto_welcome_message").First(&cfg).Error; err == nil && cfg.Value != "" { autoMessage = cfg.Value } message := model.ChatMessage{ ConversationID: conversation.ID, SenderType: "system", SenderRole: "system", ContentType: "system", Content: autoMessage, AttachmentURLS: emptyJSONList(), } if err := tx.Create(&message).Error; err != nil { return nil, err } conversation.LastMessageID = &message.ID conversation.LastMessagePreview = truncatePreview(message.Content) conversation.LastMessageAt = &message.CreatedAt if err := tx.Save(&conversation).Error; err != nil { return nil, err } return &conversation, nil } func (r *Repository) NotifyNewConversation(conversationID uint64) { if r.hub == nil { return } r.hub.NotifyConversation(conversationID, &chathub.ChatEvent{ Type: "conversation_updated", ConversationID: conversationID, }) }