package memory import ( "encoding/json" "fmt" "os" "path/filepath" "time" "github.com/hxclaw/hxclaw/cmd/hxclaw/internal" ) type ExportDocument struct { Version int `json:"version"` ExportedAt string `json:"exported_at"` Sessions []*SessionData `json:"sessions"` } type SessionData struct { ID int64 `json:"id"` UUID string `json:"uuid"` Summary string `json:"summary"` ChatIDs []int64 `json:"chat_ids"` CreatedAt int64 `json:"created_at"` UpdatedAt int64 `json:"updated_at"` Chats []*Chat `json:"chats"` } func ExportIfNeeded() { memoryCfg := internal.GetProjectConfig().Memory if !memoryCfg.Enabled || !memoryCfg.AutoExport { return } db := GetDB() if db == nil { return } exportPath := filepath.Join(internal.GetConfigDir(), "export-data.json") if err := ExportToFile(exportPath); err != nil { fmt.Printf("警告:导出数据失败: %v\n", err) return } fmt.Printf("数据已导出: %s\n", exportPath) } func ExportToFile(filename string) error { db := GetDB() if db == nil { return fmt.Errorf("数据库未初始化") } sessions, err := db.GetAllSessions() if err != nil { return fmt.Errorf("查询会话失败: %w", err) } var doc ExportDocument doc.Version = 1 doc.ExportedAt = time.Now().Format(time.RFC3339) if _, err := os.Stat(filename); err == nil { data, readErr := os.ReadFile(filename) if readErr == nil { json.Unmarshal(data, &doc) } } sessionMap := make(map[string]*SessionData) for i := range doc.Sessions { sessionMap[doc.Sessions[i].UUID] = doc.Sessions[i] } for _, s := range sessions { if existing, ok := sessionMap[s.UUID]; ok { existing.Summary = s.Summary existing.ChatIDs = s.ChatIDs existing.UpdatedAt = s.UpdatedAt } else { sessionData := &SessionData{ ID: s.ID, UUID: s.UUID, Summary: s.Summary, ChatIDs: s.ChatIDs, CreatedAt: s.CreatedAt, UpdatedAt: s.UpdatedAt, Chats: []*Chat{}, } doc.Sessions = append(doc.Sessions, sessionData) sessionMap[s.UUID] = sessionData } chats, err := db.GetChatsBySessionID(s.ID) if err != nil { continue } sessionMap[s.UUID].Chats = append(sessionMap[s.UUID].Chats, chats...) } file, err := os.Create(filename) if err != nil { return fmt.Errorf("创建文件失败: %w", err) } defer file.Close() encoder := json.NewEncoder(file) encoder.SetIndent("", " ") return encoder.Encode(doc) }