mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
✨ feat: 实现 session 导入功能
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { ActionIcon, Icon } from '@lobehub/ui';
|
||||
import { Dropdown, MenuProps } from 'antd';
|
||||
import { Dropdown, MenuProps, Upload } from 'antd';
|
||||
import {
|
||||
Feather,
|
||||
FileClock,
|
||||
@@ -14,6 +14,7 @@ import { ReactNode, memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useExportConfig } from '@/hooks/useExportConfig';
|
||||
import { useImportConfig } from '@/hooks/useImportConfig';
|
||||
|
||||
import pkg from '../../../package.json';
|
||||
|
||||
@@ -21,12 +22,18 @@ const BottomAction = memo<{ children: ReactNode }>(({ children }) => {
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const { exportSessions, exportSettings, exportAll, exportAgents } = useExportConfig();
|
||||
|
||||
const { importConfig } = useImportConfig();
|
||||
const items: MenuProps['items'] = useMemo(
|
||||
() => [
|
||||
{
|
||||
icon: <Icon icon={FolderInput} />,
|
||||
key: 'import',
|
||||
label: <div>{t('import')}</div>,
|
||||
label: (
|
||||
<Upload maxCount={1} onChange={importConfig} showUploadList={false}>
|
||||
{t('import')}
|
||||
</Upload>
|
||||
),
|
||||
},
|
||||
{
|
||||
children: [
|
||||
|
||||
36
src/hooks/useImportConfig.ts
Normal file
36
src/hooks/useImportConfig.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useSessionStore } from '@/store/session';
|
||||
import { useSettings } from '@/store/settings';
|
||||
import { importConfigFile } from '@/utils/config';
|
||||
|
||||
export const useImportConfig = () => {
|
||||
const importSessions = useSessionStore((s) => s.importSessions);
|
||||
const importSettings = useSettings((s) => s.importSettings);
|
||||
|
||||
const importConfig = (info: any) => {
|
||||
importConfigFile(info, (config) => {
|
||||
switch (config.exportType) {
|
||||
case 'settings': {
|
||||
importSettings(config.state.settings);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'sessions':
|
||||
case 'agents': {
|
||||
importSessions(config.state.sessions);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'all': {
|
||||
importSessions(config.state.sessions);
|
||||
importSettings(config.state.settings);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return useMemo(() => ({ importConfig }), []);
|
||||
};
|
||||
@@ -1,9 +1,10 @@
|
||||
import { produce } from 'immer';
|
||||
import { merge } from 'lodash-es';
|
||||
import Router from 'next/router';
|
||||
import { StateCreator } from 'zustand/vanilla';
|
||||
|
||||
import { SessionStore, initLobeSession } from '@/store/session';
|
||||
import { LobeAgentSession } from '@/types/session';
|
||||
import { LobeAgentSession, LobeSessions } from '@/types/session';
|
||||
import { uuid } from '@/utils/uuid';
|
||||
|
||||
import { SessionDispatch, sessionsReducer } from './reducers/session';
|
||||
@@ -18,10 +19,22 @@ export interface SessionAction {
|
||||
createSession: () => Promise<string>;
|
||||
|
||||
/**
|
||||
* 分发聊天记录
|
||||
* 变更session
|
||||
* @param payload - 聊天记录
|
||||
*/
|
||||
dispatchSession: (payload: SessionDispatch) => void;
|
||||
/**
|
||||
* 导入会话
|
||||
* @param sessions
|
||||
*/
|
||||
importSessions: (sessions: LobeSessions) => void;
|
||||
|
||||
/**
|
||||
* 生成压缩后的消息
|
||||
* @returns 压缩后的消息
|
||||
*/
|
||||
// genShareUrl: () => string;
|
||||
|
||||
/**
|
||||
* @title 删除会话
|
||||
* @param index - 会话索引
|
||||
@@ -35,12 +48,6 @@ export interface SessionAction {
|
||||
* @returns void
|
||||
*/
|
||||
switchSession: (sessionId?: string | 'new') => Promise<void>;
|
||||
|
||||
/**
|
||||
* 生成压缩后的消息
|
||||
* @returns 压缩后的消息
|
||||
*/
|
||||
// genShareUrl: () => string;
|
||||
}
|
||||
|
||||
export const createSessionSlice: StateCreator<
|
||||
@@ -80,6 +87,20 @@ export const createSessionSlice: StateCreator<
|
||||
});
|
||||
},
|
||||
|
||||
importSessions: (importSessions) => {
|
||||
const { sessions } = get();
|
||||
set({
|
||||
sessions: produce(sessions, (draft) => {
|
||||
for (const [id, session] of Object.entries(importSessions)) {
|
||||
// 如果已经存在,则跳过
|
||||
if (draft[id]) continue;
|
||||
|
||||
draft[id] = session;
|
||||
}
|
||||
}),
|
||||
});
|
||||
},
|
||||
|
||||
removeSession: (sessionId) => {
|
||||
get().dispatchSession({ id: sessionId, type: 'removeSession' });
|
||||
|
||||
@@ -87,7 +108,6 @@ export const createSessionSlice: StateCreator<
|
||||
Router.push('/');
|
||||
}
|
||||
},
|
||||
|
||||
switchSession: async (sessionId) => {
|
||||
if (get().activeId === sessionId) return;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { notification } from 'antd';
|
||||
|
||||
import { CURRENT_CONFIG_VERSION, Migration } from '@/migrations';
|
||||
import { ConfigState } from '@/types/exportConfig';
|
||||
import { ConfigFile } from '@/types/exportConfig';
|
||||
|
||||
export const exportConfigFile = (config: object, fileName?: string) => {
|
||||
const file = `LobeChat-${fileName || '-config'}-v${CURRENT_CONFIG_VERSION}.json`;
|
||||
@@ -26,7 +26,7 @@ export const exportConfigFile = (config: object, fileName?: string) => {
|
||||
a.remove();
|
||||
};
|
||||
|
||||
export const handleImport = (info: any, onConfigImport: (config: ConfigState) => void) => {
|
||||
export const importConfigFile = (info: any, onConfigImport: (config: ConfigFile) => void) => {
|
||||
const reader = new FileReader();
|
||||
//读取完文件之后的回调函数
|
||||
reader.onloadend = function (evt) {
|
||||
@@ -34,9 +34,10 @@ export const handleImport = (info: any, onConfigImport: (config: ConfigState) =>
|
||||
const fileJson = fileString as string;
|
||||
|
||||
try {
|
||||
const { state } = Migration.migrate(JSON.parse(fileJson));
|
||||
const config = JSON.parse(fileJson);
|
||||
const { state } = Migration.migrate(config);
|
||||
|
||||
onConfigImport(state);
|
||||
onConfigImport({ ...config, state });
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
description: `出错原因: ${(error as Error).message}`,
|
||||
|
||||
Reference in New Issue
Block a user