141 lines
4.0 KiB
Go
141 lines
4.0 KiB
Go
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
|
|
}
|