支持客服入口按业务场景分流到客服分组

联系客服支持 scene(general/mohong),按用户与场景复用会话;摸大红入口走摸大红分组选人。
This commit is contained in:
yml2213
2026-07-16 20:05:10 +08:00
parent e07532a188
commit 66ca2693b3
17 changed files with 224 additions and 21 deletions
+32 -7
View File
@@ -58,6 +58,7 @@ func (r *Repository) FindConversation(ctx context.Context, principal Principal,
OrderID: conversation.OrderID,
ListingID: conversation.ListingID,
Type: conversation.Type,
SupportScene: conversation.SupportScene,
Title: conversation.Title,
Status: conversation.Status,
Role: "admin", // 管理员角色
@@ -131,20 +132,43 @@ func (r *Repository) FindOrderConversation(ctx context.Context, userID uint64, o
dto := row.toDTO(participants)
return &dto, nil
}
func (r *Repository) EnsureSupportConversation(ctx context.Context, userID uint64) (*ConversationDTO, error) {
func (r *Repository) EnsureSupportConversation(ctx context.Context, userID uint64, scene string) (*ConversationDTO, error) {
scene, title, groupCode, welcome := resolveSupportScene(scene)
var conversationID uint64
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
var existing model.ChatConversation
err := tx.Table("chat_conversations AS c").
Select("c.*").
Joins("JOIN chat_participants AS cp ON cp.conversation_id = c.id").
Where("c.type = ? AND cp.participant_type = ? AND cp.participant_id = ?", "general_support", "user", userID).
Where(
"c.type = ? AND c.support_scene = ? AND cp.participant_type = ? AND cp.participant_id = ?",
ConversationTypeGeneralSupport, scene, "user", userID,
).
Order("c.id ASC").
Limit(1).
Find(&existing).Error
if err != nil {
return err
}
// 兼容旧数据:scene=general 时也匹配未回填 support_scene 的历史会话
if existing.ID == 0 && scene == SupportSceneGeneral {
err = tx.Table("chat_conversations AS c").
Select("c.*").
Joins("JOIN chat_participants AS cp ON cp.conversation_id = c.id").
Where(
"c.type = ? AND (c.support_scene = '' OR c.support_scene IS NULL) AND cp.participant_type = ? AND cp.participant_id = ?",
ConversationTypeGeneralSupport, "user", userID,
).
Order("c.id ASC").
Limit(1).
Find(&existing).Error
if err != nil {
return err
}
if existing.ID > 0 && existing.SupportScene == "" {
_ = tx.Model(&existing).Update("support_scene", SupportSceneGeneral).Error
}
}
if existing.ID > 0 {
conversationID = existing.ID
return nil
@@ -152,9 +176,10 @@ func (r *Repository) EnsureSupportConversation(ctx context.Context, userID uint6
now := time.Now()
conversation := model.ChatConversation{
Type: "general_support",
Title: "平台客服",
Status: "active",
Type: ConversationTypeGeneralSupport,
SupportScene: scene,
Title: title,
Status: "active",
}
if err := tx.Create(&conversation).Error; err != nil {
return err
@@ -169,7 +194,7 @@ func (r *Repository) EnsureSupportConversation(ctx context.Context, userID uint6
JoinedAt: now,
},
}
if supportID := defaultSupportAdminID(tx); supportID > 0 {
if supportID := pickSupportAdminForScene(tx, groupCode); supportID > 0 {
participants = append(participants, model.ChatParticipant{
ConversationID: conversation.ID,
ParticipantType: "admin",
@@ -189,7 +214,7 @@ func (r *Repository) EnsureSupportConversation(ctx context.Context, userID uint6
SenderType: "system",
SenderRole: "system",
ContentType: "system",
Content: "您好,客服会尽快回复,请直接描述您遇到的问题。",
Content: welcome,
AttachmentURLS: emptyJSONList(),
}
if err := tx.Create(&message).Error; err != nil {