package service import ( "context" "encoding/json" "fmt" "time" "github.com/gogf/gf/v2/frame/g" ) // ==================== Redis 操作 ==================== // saveToRedis 保存会话数据到Redis func (s *sessionService) saveToRedis(ctx context.Context, sessionId string, requestMessages []map[string]any, responseMessages []map[string]any) error { key := fmt.Sprintf("chat:session:%s", sessionId) maxRounds := g.Cfg().MustGet(ctx, "session.maxRounds", 10).Int() expireSeconds := g.Cfg().MustGet(ctx, "session.expireTime", 1800).Int64() expireTime := time.Duration(expireSeconds) * time.Second data := map[string]any{ "sessionId": sessionId, "requestContent": requestMessages, "responseContent": responseMessages, "timestamp": time.Now().Unix(), } b, err := json.Marshal(data) if err != nil { return fmt.Errorf("序列化会话数据失败: %w", err) } _, err = g.Redis().Do(ctx, "LPUSH", key, string(b)) if err != nil { return fmt.Errorf("写入Redis失败: %w", err) } _, err = g.Redis().Do(ctx, "LTRIM", key, 0, maxRounds-1) if err != nil { return fmt.Errorf("裁剪Redis列表失败: %w", err) } _, err = g.Redis().Do(ctx, "EXPIRE", key, int64(expireTime.Seconds())) if err != nil { return fmt.Errorf("设置过期时间失败: %w", err) } return nil } // getFromRedis 从Redis获取会话历史 func (s *sessionService) getFromRedis(ctx context.Context, sessionId string) ([]map[string]any, error) { key := fmt.Sprintf("chat:session:%s", sessionId) result, err := g.Redis().Do(ctx, "LRANGE", key, 0, -1) if err != nil { return nil, fmt.Errorf("从Redis获取数据失败: %w", err) } if result == nil || result.IsNil() { return []map[string]any{}, nil } var sessions []map[string]any values := result.Strings() for _, str := range values { var data map[string]any if err := json.Unmarshal([]byte(str), &data); err != nil { g.Log().Warningf(ctx, "[会话] 解析Redis数据失败 err=%v", err) continue } sessions = append(sessions, data) } // 反转(Redis 最新在前 → 时间正序) for i, j := 0, len(sessions)-1; i < j; i, j = i+1, j-1 { sessions[i], sessions[j] = sessions[j], sessions[i] } return sessions, nil } // GetSessionHistoryForInference 获取历史会话,返回扁平消息数组(给推理用) func (s *sessionService) GetSessionHistoryForInference(ctx context.Context, sessionId string) ([]map[string]any, error) { historyData, err := s.getFromRedis(ctx, sessionId) if err != nil { return nil, fmt.Errorf("获取历史会话失败: %w", err) } if len(historyData) == 0 { return []map[string]any{}, nil } var messages []map[string]any for _, round := range historyData { if reqMsgs, ok := round["requestContent"].([]interface{}); ok { for _, m := range reqMsgs { if msg, ok := m.(map[string]interface{}); ok { messages = append(messages, msg) } } } if respMsgs, ok := round["responseContent"].([]interface{}); ok { for _, m := range respMsgs { if msg, ok := m.(map[string]interface{}); ok { messages = append(messages, msg) } } } } return messages, nil }