Files
customer-server/dao/conversation_dao.go

141 lines
4.0 KiB
Go
Raw Normal View History

2026-03-14 10:02:49 +08:00
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
}