拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Operit 聊天记录按会话选择导出:从全量导出到多选归档的交互设计与实现

AI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆【免费下载链接】OperitThe most powerful AI agent and AI chat software on Android/Operit是一款Android上能力最为强大、发展最久的AI Agent项目地址https://gitcode.com/gh_mirrors/op/Operit点击查看免费下载本文以 Operit 的「设置 数据备份与恢复 聊天记录」导出功能为对象系统讲解其从一键全量导出演进为先选择会话、再按所选范围导出的完整设计包括多选对话框的交互契约、空选集保护、五种导出格式的复用流程、仅写入所选会话的导出层实现、HTML/TXT 长文本统计口径的收敛以及operit_chat_archivev2 归档格式的兼容性保证。读完本文你将掌握该功能的前端交互编排、底层数据流与统计口径并能在自己的实现中复刻这一套先选择、后导出的可靠流程。现状与动机全量导出的局限在引入会话选择能力之前Operit 设置页中的聊天记录导出按钮直接导出全部聊天记录具体表现为导出动作缺少粒度控制用户无法只备份某几个重要会话HTML 与 TXT 格式导出时消息总数与长文本导出进度均按全部会话计算会话较多、文本量较大时进度反馈与用户实际关注的范围脱节。这一设计在会话数量少时可用但当聊天记录累积到一定规模后全量导出既浪费存储空间也不便于按主题、按角色卡或按时间段归档。因此本次改动将导出流程拆为两步先选择会话再选择格式执行导出。设计目标与行为契约根据 设计文档本次改动确立了几条明确的行为契约契约说明导出前展示多选列表支持单选、多选、全选与清空复用现有格式选择对话框会话选择完成后进入既有格式选择流程不重复造轮子导出层只写所选会话归档文件中仅包含用户勾选的会话统计按所选会话计算HTML/TXT 的消息总数与长文本进度以所选会话为基数空选集不导出未选中任何会话时禁止执行导出也不会悄悄扩大为全量导出归档格式不变JSON 保持operit_chat_archivev2 结构导入侧无需任何改动同时功能入口位于「设置 数据备份与恢复 聊天记录」全选语义保留全量导出的能力即全选 导出全部聊天记录。交互流程从导出按钮到多选对话框完整交互编排位于 ChatBackupSettingsScreen.kt整体链路为导出按钮 → ChatHistoryExportSelectionDialog多选会话 → ExportFormatDialog选择格式 → exportChatHistoriesToDownloads(selectedChatIds, format, onProgress)第一步打开多选对话框点击「导出」时屏幕先重置选中集合再弹出会话选择对话框对应源码 ChatBackupSettingsScreen.ktonExport { selectedExportChatIds emptySet() showChatExportSelectionDialog true },第二步多选会话单选 / 多选 / 全选 / 清空多选对话框实现于 BackupDialogs.kt 的ChatHistoryExportSelectionDialog其交互要素包括选中计数实时展示已选择 X / Y 条资源键为selected_chats_count已选择 %1$d / %2$d 条全选一键选中当前全部会话资源键select_all_current_list全选当会话列表为空时按钮禁用清空一键清空选中集合资源键backup_clear_selection清空仅在存在选中项时可用逐条勾选每条会话以 Card Checkbox 呈现ChatHistoryExportOption点击整行卡片即可切换选中状态未命名会话回退显示未命名会话文案标题过长时最多两行并以省略号截断选择列表使用LazyColumn承载最大高度 360dp会话多时可滚动浏览。关键点在于选中状态以SetString会话 id 集合管理单选即selectedChatIds history.id取消即selectedChatIds - history.id天然支持任意多选组合。第三步空选集保护对话框的「确定」按钮enabled selectedChatIds.isNotEmpty()源码见 BackupDialogs.kt。这意味着未选中任何会话时无法点击确认即便在极端情况下如选中会话被删除绕过 UI 到达导出层底层也会再次拦截见下文导出层实现不会将空选择扩大为全量导出彻底杜绝本想导一个、结果导了全部的误操作。第四步复用格式选择对话框确认选择后屏幕关闭选择对话框并打开既有ExportFormatDialog源码见 ChatBackupSettingsScreen.kt用户在此挑选导出格式并确认执行。格式枚举定义于 ChatFormat.kt枚举值说明归档文件形态JSONOperit 原生 JSON 归档chat_backup_时间戳.jsonMARKDOWN每会话一个 Markdown 文件打包为chat_backup_时间戳.zipHTML浏览器可读的对话页chat_backup_时间戳.htmlTXT纯文本对话记录chat_backup_时间戳.txtCSV结构化表格记录chat_backup_时间戳.csv导出成功后结果卡片展示成功导出 X 条聊天记录为 Y 格式到Z对应资源键backup_chat_export_result_success。导出层仅写入所选会话导出层核心方法为exportChatHistoriesToDownloadsChatHistoryManager.kt它接收三个参数suspend fun exportChatHistoriesToDownloads( selectedChatIds: SetString, format: ExportFormat, onProgress: ((ChatExportProgress) - Unit)?, ): ChatExportResult?其实现要点入口强校验require(selectedChatIds.isNotEmpty())从调用层杜绝空集合导出按 id 过滤会话从chatHistoriesFlow中仅取出id in selectedChatIds的会话若所选会话已全部不存在如已被删除直接返回null并中止导出仅对所选会话写盘JSON 走exportOperitArchiveJsonStream、CSV 走exportOperitArchiveCsvStream、Markdown 逐会话生成.md并打包 zip、HTML/TXT 按需走流式长文本导出exportLongTextHistories任何分支都只遍历chatHistoriesBasic即所选会话子集文件名规范Markdown 子文件会先清洗标题中的非法字符\/:*?|、截断超长标题50 字符上限并用(n)后缀保证文件名唯一避免归档内冲突。统计口径收敛HTML/TXT 长文本导出按所选会话计算原实现中 HTML/TXT 的消息总数与长文本进度按全部会话计算本次改动将其收敛到所选会话集合上。底层逻辑见 ChatHistoryManager.kt当格式为 HTML 或 TXT 时先查询各会话的内容字符数chatContentDao.getSelectedContentCharacterCountsByChat()并过滤为chatId in exportedChatIds随后求和得到totalTextCharacters当totalTextCharacters 4_000_000常量TEXT_EXPORT_STREAMING_THRESHOLD_CHARACTER_COUNT 4_000_000L时启用流式文本导出逐段写出以控制内存占用并通过ChatExportProgress(isLongText, progress, processedCharacters, totalCharacters)上报按字符计的进度未触发流式阈值时消息总数同样以所选会话为基数统计messageDao.getMessageCountsByChatId()过滤chatId in exportedChatIds。UI 侧ChatBackupSettingsScreen.kt通过onProgress回调同步驱动正在导出超长文本X%已处理 A / B 个字符的进度展示确保进度数值与用户勾选的会话范围严格一致。归档格式兼容operit_chat_archive v2本次改动刻意保持 JSON 归档结构不变确保已发布的导入流程、数据库备份与原始快照等下游能力零改动。归档模型定义于 OperitChatArchive.ktSerializable data class OperitChatArchive( val archiveType: String ARCHIVE_TYPE, // operit_chat_archive val formatVersion: Int CURRENT_FORMAT_VERSION, // 2 val exportedAt: Long System.currentTimeMillis(), val chats: ListOperitArchivedChat, ) { companion object { const val ARCHIVE_TYPE operit_chat_archive const val CURRENT_FORMAT_VERSION 2 } }单条会话OperitArchivedChat完整保留会话元数据id、title、createdAt、updatedAt、inputTokens、outputTokens、currentWindowSize、group、displayOrder、workspace、parentChatId、characterCardName、characterCardGroupId、locked、pinned 等消息层OperitArchivedMessage支持variants多模型变体并内置fromChatHistory/toChatHistory双向转换保证导出→导入的可逆性。按设计文档的边界声明本次改动只涉及设置页中的聊天记录导出流程、导出筛选与对应文案归档格式、导入流程、数据库备份和原始快照均不在作用域内详见 方案索引。多语言文案覆盖新增交互全部走字符串资源默认中文文案位于 values/strings.xml核心资源键如下资源键默认文案backup_select_chat_records选择聊天记录backup_select_chat_records_hint请选择要导出的聊天记录。selected_chats_count已选择 %1$d / %2$d 条select_all_current_list全选backup_clear_selection清空按文档要求新增资源键已同步覆盖全部8 套语言资源默认中文values/、英文values-en/、西班牙语values-es/、巴西葡萄牙语values-pt-rBR/、印尼语values-id/、马来语values-ms/、罗马尼亚语values-ro/、韩语values-ko/避免出现未翻译文案。验证与交付准则本次改动遵循仓库默认的执行准则进行验证git diff --check通过确保无空白符错误与格式问题新增资源键已覆盖全部 8 套语言资源见上文清单未运行构建或测试——这是仓库既定的交付约束而非疏漏后续 CI 会按既有流水线接管构建验证。相关实现文件索引如需深入研读或复用该实现可按以下路径查阅方案设计docs/TODO/chat_record_export_selection/01-selection-and-export.md、docs/TODO/chat_record_export_selection/index.md交互编排ChatBackupSettingsScreen.kt多选对话框BackupDialogs.kt导出层实现ChatHistoryManager.kt归档模型OperitChatArchive.kt格式枚举ChatFormat.kt文案资源values/strings.xml 及 7 套对应语言目录这套先选择、后导出、按选择统计、空选不扩大的流程兼顾了精确归档、全量保留与格式兼容三种诉求可作为 Android 端数据导出类功能的通用设计参考。赞分享AI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆【免费下载链接】OperitThe most powerful AI agent and AI chat software on Android/Operit是一款Android上能力最为强大、发展最久的AI Agent项目地址https://gitcode.com/gh_mirrors/op/Operit点击查看免费下载相关推荐Operit 聊天记录选择导出会话级筛选、全选保留与源码实现解析Operit 聊天记录选择导出会话级筛选、全选保留与源码实现解析 聊天记录导出是 Operit「数据备份与恢复」能力中的高频操作。过去点击导出会一次性把全部会AI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆GUI 自动化Codex-X如何把会话导出为Markdown单条导出与多选ZIP打包Codex X如何把会话导出为Markdown单条导出与多选ZIP打包 Codex X 是 OpenAI Codex 桌面端/CLI 的可视化管理工具其中「桌面应用开发者工具AI 应用上一篇德州扑克GTO求解器如何用开源工具破解复杂决策难题下一篇免费德州扑克GTO求解器Desktop Postflop完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门