diff --git a/src/lib/components/layout/ImportChatsModal.svelte b/src/lib/components/layout/ImportChatsModal.svelte new file mode 100644 index 0000000000..c6209a305a --- /dev/null +++ b/src/lib/components/layout/ImportChatsModal.svelte @@ -0,0 +1,329 @@ + + + +
+
+
+
对话记录导入中心
+
+ 完成准备、筛选后再执行导入,提升成功率与速度。 +
+
+ +
+ +
+
+
+ 1. 准备您的对话记录 +
+
+

请确保导出文件格式为 JSON (.json)纯文本 (.txt)

+

+ 请前往原平台导出历史对话,如 DeepSeek — 系统设置 — 数据管理 — 导出所有历史对话, + ChatGPT — 设置 — 数据管理 — 导出数据。 +

+

如果导出的文件内容过多或过大,建议使用下方的筛选功能生成新的导入文件,以加快导入速度。

+
+
+ +
+
+
2. 筛选记录
+ +
+ +
(dropActive = true)} + on:dragleave|preventDefault={() => (dropActive = false)} + on:drop|preventDefault={(e) => { + dropActive = false; + handleFiles(e.dataTransfer?.files ?? []); + }} + > +
+
+ {fileName ? `已选择:${fileName}` : '拖拽文件到此处,或点击上传'} +
+
+ +
+ 支持 .json / .txt,OpenAI 导出支持自动转换 +
+
+ {#if loading} +
+ + 正在解析文件... +
+ {/if} + {#if errorMsg} +
{errorMsg}
+ {/if} +
+ handleFiles((e.currentTarget as HTMLInputElement).files)} + /> +
+ + {#if filterOpen} +
+
+
+ 总数:{rawChats.length} | 已选:{selectedIndices.size} + {selectedIndices.size === 0 && rawChats.length > 0 ? '(未选则默认导入全部)' : ''} +
+ +
+ +
+ + + + + + + + + + {#if !rawChats.length} + + + + {:else} + {#each displayRows() as row} + + + + + + {/each} + {/if} + +
选择标题 / 摘要时间
+ 请先上传文件以查看可筛选的记录 +
+ toggleRow(row.idx)} + /> + +
+ {row.title} +
+
+ {row.date} +
+
+
+ {/if} +
+ +
+
3. 导入记录
+
+ 确认后将按筛选结果导入到当前账户的对话列表中。 +
+
+ + +
+
+
+
+
diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index d7f50ced91..82e5240b1a 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -52,6 +52,7 @@ import Folder from '../common/Folder.svelte'; import Tooltip from '../common/Tooltip.svelte'; import Folders from './Sidebar/Folders.svelte'; + import ImportChatsModal from './ImportChatsModal.svelte'; import { getChannels, createNewChannel } from '$lib/apis/channels'; import ChannelModal from './Sidebar/ChannelModal.svelte'; import ChannelItem from './Sidebar/ChannelItem.svelte'; @@ -64,8 +65,6 @@ import PinnedModelList from './Sidebar/PinnedModelList.svelte'; import Note from '../icons/Note.svelte'; import { slide } from 'svelte/transition'; - import { getImportOrigin, convertOpenAIChats } from '$lib/utils'; - import { extractChatsFromFile } from '$lib/utils/chatImport'; const BREAKPOINT = 768; @@ -79,6 +78,8 @@ let showCreateChannel = false; + let showImportChatsModal = false; + // Pagination variables let chatListLoading = false; let allChatsLoaded = false; @@ -90,10 +91,6 @@ let newFolderId = null; - // Import Chats state - let importFiles; - let chatImportInputElement: HTMLInputElement; - const initFolders = async () => { const folderList = await getFolders(localStorage.token).catch((error) => { toast.error(`${error}`); @@ -357,32 +354,6 @@ selectedChatId = null; }; - // Import Chats handler - $: if (importFiles) { - console.log(importFiles); - - if (importFiles.length > 0) { - extractChatsFromFile(importFiles[0]) - .then((chats) => { - console.log(chats); - if (getImportOrigin(chats) == 'openai') { - try { - chats = convertOpenAIChats(chats); - } catch (error) { - console.log('Unable to import chats:', error); - toast.error($i18n.t('Failed to convert OpenAI chats')); - return; - } - } - importChatsHandler(chats); - }) - .catch((error) => { - console.error('Import error:', error); - toast.error($i18n.t(error.message)); - }); - } - } - const importChatsHandler = async (_chats) => { for (const chat of _chats) { console.log(chat); @@ -1313,19 +1284,10 @@ > - - -
{#if $user !== undefined && $user !== null}
{/if} + + { + await importChatsHandler(chats); + }} +/> diff --git a/unitest/chat_history_filter.html b/unitest/chat_history_filter.html new file mode 100644 index 0000000000..f5e9da3d22 --- /dev/null +++ b/unitest/chat_history_filter.html @@ -0,0 +1,441 @@ + + + + + + 聊天记录筛选器 (JSON) + + + + +
+

CHAT_FILTER ARRAY_MODE

+ +
+ 等待导入文件... + +
+ + +
+ + +
+
+ +
+
+

请点击右上角导入 JSON 文件

+

支持格式: Standard JSON Array `[{},{}]`

+
+ + + + + + + + + + + +
+ + TITLEINSERTED_AT
+
+ + + + \ No newline at end of file