package dao import ( "context" "customer-server/model/entity" "gitea.com/red-future/common/db/mongo" "gitea.com/red-future/common/redis" "github.com/gogf/gf/v2/os/gtime" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo/options" ) var Conversation = new(conversation) type conversation struct{} // BatchInsert 批量插入对话记录 func (d *conversation) BatchInsert(ctx context.Context, list []*entity.Conversation) (err error) { if len(list) == 0 { return } now := gtime.Now().Time docs := make([]interface{}, 0, len(list)) for _, data := range list { docs = append(docs, bson.M{ "userId": data.UserId, "platform": data.Platform, "sessionId": data.SessionId, "question": data.Question, "answer": data.Answer, "messageId": data.MessageId, "msgTime": data.MsgTime, "tenantId": data.TenantId, "creator": "system", "createdAt": now, "updater": "system", "updatedAt": now, "isDeleted": false, }) } _, err = mongo.GetDB().Collection(entity.ConversationCollection).InsertMany(ctx, docs) return } // UpsertByMessageId 幂等插入对话记录(使用 message_id 做唯一键,防止重复消费) func (d *conversation) UpsertByMessageId(ctx context.Context, data *entity.Conversation) (inserted bool, err error) { filter := bson.M{"messageId": data.MessageId} now := gtime.Now().Time update := bson.M{ "$setOnInsert": bson.M{ "userId": data.UserId, "platform": data.Platform, "sessionId": data.SessionId, "question": data.Question, "answer": data.Answer, "messageId": data.MessageId, "msgTime": data.MsgTime, "creator": "system", "createdAt": now, "tenantId": data.TenantId, // 使用传入的租户ID "isDeleted": false, }, "$set": bson.M{ "updater": "system", "updatedAt": now, }, } opts := options.UpdateOne().SetUpsert(true) result, err := mongo.GetDB().Collection(entity.ConversationCollection).UpdateOne(ctx, filter, update, opts) if err != nil { return } // UpsertedCount > 0 表示是新插入,否则是已存在(幂等跳过) inserted = result.UpsertedCount > 0 return } // FindByUserId 根据用户ID查询对话记录 func (d *conversation) FindByUserId(ctx context.Context, userId string, limit int64) (list []*entity.Conversation, err error) { filter := bson.M{"userId": userId, "isDeleted": false} opts := options.Find().SetSort(bson.D{{Key: "msgTime", Value: -1}}).SetLimit(limit) cursor, err := mongo.GetDB().Collection(entity.ConversationCollection).Find(ctx, filter, opts) if err != nil { return } defer cursor.Close(ctx) err = cursor.All(ctx, &list) return } // FindBySessionId 根据 Session ID 查询对话记录 func (d *conversation) FindBySessionId(ctx context.Context, sessionId string) (list []*entity.Conversation, err error) { filter := bson.M{"sessionId": sessionId, "isDeleted": false} opts := options.Find().SetSort(bson.D{{Key: "msgTime", Value: 1}}) cursor, err := mongo.GetDB().Collection(entity.ConversationCollection).Find(ctx, filter, opts) if err != nil { return } defer cursor.Close(ctx) err = cursor.All(ctx, &list) return } // GetRecentHistory 获取用户最近 N 轮历史对话(用于上下文注入) // 返回 redis.HistoryMessage 切片,按时间正序排列 func (d *conversation) GetRecentHistory(ctx context.Context, userId string, limit int64) (history []redis.HistoryMessage, err error) { filter := bson.M{"userId": userId, "isDeleted": false} // 先按时间倒序取最近 N 条,再反转为正序 opts := options.Find().SetSort(bson.D{{Key: "msgTime", Value: -1}}).SetLimit(limit) cursor, err := mongo.GetDB().Collection(entity.ConversationCollection).Find(ctx, filter, opts) if err != nil { return } defer cursor.Close(ctx) var list []*entity.Conversation if err = cursor.All(ctx, &list); err != nil { return } // 反转为时间正序 history = make([]redis.HistoryMessage, len(list)) for i, conv := range list { history[len(list)-1-i] = redis.HistoryMessage{ Question: conv.Question, Answer: conv.Answer, } } return }