@lobehub/chat 1.77.0 → 1.77.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.77.2](https://github.com/lobehub/lobe-chat/compare/v1.77.1...v1.77.2)
6
+
7
+ <sup>Released on **2025-03-29**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix decrypt error with imported pg data.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix decrypt error with imported pg data, closes [#7220](https://github.com/lobehub/lobe-chat/issues/7220) ([f8a0aa0](https://github.com/lobehub/lobe-chat/commit/f8a0aa0))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 1.77.1](https://github.com/lobehub/lobe-chat/compare/v1.77.0...v1.77.1)
31
+
32
+ <sup>Released on **2025-03-29**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Fix export button and clean orphan agent.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Fix export button and clean orphan agent, closes [#7219](https://github.com/lobehub/lobe-chat/issues/7219) ([112282a](https://github.com/lobehub/lobe-chat/commit/112282a))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ## [Version 1.77.0](https://github.com/lobehub/lobe-chat/compare/v1.76.1...v1.77.0)
6
56
 
7
57
  <sup>Released on **2025-03-29**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Fix decrypt error with imported pg data."
6
+ ]
7
+ },
8
+ "date": "2025-03-29",
9
+ "version": "1.77.2"
10
+ },
11
+ {
12
+ "children": {
13
+ "fixes": [
14
+ "Fix export button and clean orphan agent."
15
+ ]
16
+ },
17
+ "date": "2025-03-29",
18
+ "version": "1.77.1"
19
+ },
2
20
  {
3
21
  "children": {
4
22
  "features": [
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "وضع كامل الشاشة",
185
185
  "historyRange": "نطاق التاريخ",
186
- "import": "استيراد الإعدادات",
186
+ "importData": "استيراد البيانات",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "عذرًا، حدث استثناء أثناء عملية استيراد البيانات. يرجى المحاولة مرة أخرى، أو <1>تقديم مشكلتك</1>، وسنقوم بمساعدتك على الفور في تحديد المشكلة.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Цял екран",
185
185
  "historyRange": "Диапазон на историята",
186
- "import": "Импортирай конфигурация",
186
+ "importData": "Импорт на данни",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Съжаляваме, възникна грешка по време на процеса на импорт на данни. Моля, опитайте отново да ги импортирате или <1>подайте проблем</1>, за да можем да помогнем веднага с отстраняването на проблема.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Vollbildmodus",
185
185
  "historyRange": "Verlaufsbereich",
186
- "import": "Importieren",
186
+ "importData": "Daten importieren",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Es tut uns sehr leid, aber beim Importieren der Daten ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut oder <1>senden Sie uns eine Anfrage</1>, damit wir das Problem umgehend für Sie lösen können.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Full Screen Mode",
185
185
  "historyRange": "History Range",
186
- "import": "Import Configuration",
186
+ "importData": "Import Data",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Sorry, an error occurred during the data import process. Please try importing again, or <1>submit a request</1>, and we will help you troubleshoot the issue as soon as possible.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Pantalla completa",
185
185
  "historyRange": "Rango de historial",
186
- "import": "Importar configuración",
186
+ "importData": "Importar datos",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Lo sentimos mucho, se produjo un error durante el proceso de importación de datos. Inténtalo de nuevo o <1>envía un informe</1>, y te ayudaremos a solucionar el problema lo antes posible.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "حالت تمام صفحه",
185
185
  "historyRange": "محدوده تاریخی",
186
- "import": "وارد کردن تنظیمات",
186
+ "importData": "وارد کردن داده‌ها",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "متأسفانه در فرآیند وارد کردن داده‌ها خطایی رخ داده است. لطفاً دوباره تلاش کنید یا <1>مشکل را گزارش دهید</1> تا ما در اسرع وقت به شما کمک کنیم.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Mode plein écran",
185
185
  "historyRange": "Plage d'historique",
186
- "import": "Importer",
186
+ "importData": "Importer des données",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Désolé, une erreur s'est produite lors de l'importation des données. Veuillez réessayer l'importation ou <1> soumettre un problème </1>, nous vous aiderons à résoudre le problème dès que possible.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Modalità a schermo intero",
185
185
  "historyRange": "Intervallo cronologico",
186
- "import": "Importa configurazione",
186
+ "importData": "Importa dati",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Ci dispiace molto, si è verificato un errore durante il processo di importazione dei dati. Si prega di provare a importare nuovamente, o <1>invia un problema</1>, saremo pronti ad aiutarti a risolvere il problema al più presto.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "フルスクリーンモード",
185
185
  "historyRange": "履歴範囲",
186
- "import": "インポート",
186
+ "importData": "データをインポートする",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "データのインポート中にエラーが発生しました。再度インポートを試すか、<1>問題を報告</1>してください。問題を迅速に解決いたします。",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "전체 화면",
185
185
  "historyRange": "기록 범위",
186
- "import": "가져오기",
186
+ "importData": "데이터 가져오기",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "데이터 가져오기 중에 문제가 발생했습니다. 다시 시도하거나 <1>문제 제출</1>을 클릭하여 문제를 보고하면 우리가 즉시 도와드리겠습니다.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Volledig scherm",
185
185
  "historyRange": "Geschiedenisbereik",
186
- "import": "Importeren",
186
+ "importData": "Gegevens importeren",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Sorry, er is een uitzondering opgetreden tijdens het importeren van gegevens. Probeer opnieuw te importeren of <1>diend een probleem in</1>, we zullen het probleem zo snel mogelijk voor je onderzoeken.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Tryb pełnoekranowy",
185
185
  "historyRange": "Zakres historii",
186
- "import": "Importuj ustawienia",
186
+ "importData": "Importuj dane",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Przepraszamy, wystąpił błąd podczas importowania danych. Spróbuj ponownie zaimportować, lub <1>zgłoś problem</1>, a my postaramy się jak najszybciej rozwiązać problem.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Modo de Tela Cheia",
185
185
  "historyRange": "Intervalo de histórico",
186
- "import": "Importar configuração",
186
+ "importData": "Importar dados",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Desculpe, ocorreu um erro durante o processo de importação de dados. Por favor, tente importar novamente ou <1>envie um problema</1>, e nós iremos ajudá-lo a resolver o problema o mais rápido possível.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Полноэкранный режим",
185
185
  "historyRange": "История",
186
- "import": "Импорт настроек",
186
+ "importData": "Импорт данных",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Извините, произошла ошибка в процессе импорта данных. Попробуйте импортировать заново или <1>сообщите о проблеме</1>, и мы постараемся помочь вам как можно скорее.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Tam Ekran Modu",
185
185
  "historyRange": "Geçmiş Aralığı",
186
- "import": "İçe Aktar",
186
+ "importData": "Veri İçe Aktar",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Üzgünüz, veri aktarımı sırasında bir hata oluştu. Lütfen tekrar deneyin veya <1>bir sorun bildirin</1>, sorunu çözmek için elimizden geleni yapacağız.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "Chế độ toàn màn hình",
185
185
  "historyRange": "Phạm vi lịch sử",
186
- "import": "Nhập cấu hình",
186
+ "importData": "Nhập dữ liệu",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "Xin lỗi vì quá trình nhập dữ liệu gặp sự cố. Vui lòng thử nhập lại hoặc <1>gửi vấn đề</1>, chúng tôi sẽ kiểm tra vấn đề ngay lập tức.",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "全屏模式",
185
185
  "historyRange": "历史范围",
186
- "import": "导入配置",
186
+ "importData": "导入数据",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "非常抱歉,数据导入过程发生异常。请尝试重新导入,或 <1>提交问题</1>,我们将会第一时间帮你排查问题。",
@@ -1083,7 +1083,7 @@
1083
1083
  "description": "GPT-4o-mini 实时版本,支持音频和文本实时输入输出"
1084
1084
  },
1085
1085
  "gpt-4o-mini-tts": {
1086
- "description": "GPT-4o mini TTS 是基于 GPT-4o mini 的文本转语音模型,提供高品质的语音生成,同时降低成本。"
1086
+ "description": "GPT-4o mini TTS 是一个基于 GPT-4o mini 构建的文本转语音模型,这是一种快速且强大的语言模型。使用它可以将文本转换为自然听起来的语音文本。最大输入标记数为 2000。"
1087
1087
  },
1088
1088
  "gpt-4o-realtime-preview": {
1089
1089
  "description": "GPT-4o 实时版本,支持音频和文本实时输入输出"
@@ -183,7 +183,7 @@
183
183
  },
184
184
  "fullscreen": "全螢幕模式",
185
185
  "historyRange": "歷史範圍",
186
- "import": "匯入設定",
186
+ "importData": "匯入資料",
187
187
  "importModal": {
188
188
  "error": {
189
189
  "desc": "非常抱歉,資料匯入過程發生異常。請嘗試重新匯入,或 <1>提交問題</1>,我們將會第一時間幫你排查問題。",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.77.0",
3
+ "version": "1.77.2",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -38,7 +38,7 @@ const Category = memo(() => {
38
38
  },
39
39
  {
40
40
  key: 'import',
41
- label: <DataImporter>{t('import')}</DataImporter>,
41
+ label: <DataImporter>{t('importData')}</DataImporter>,
42
42
  },
43
43
  ];
44
44
 
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
 
3
3
  import { Form, Icon, type ItemGroup } from '@lobehub/ui';
4
- import { App, Button, Dropdown, Space } from 'antd';
4
+ import { App, Button } from 'antd';
5
5
  import isEqual from 'fast-deep-equal';
6
- import { ChevronDown, HardDriveDownload, HardDriveUpload } from 'lucide-react';
6
+ import { HardDriveDownload, HardDriveUpload } from 'lucide-react';
7
7
  import { useCallback } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
 
@@ -68,39 +68,14 @@ const AdvancedActions = () => {
68
68
  },
69
69
  {
70
70
  children: (
71
- <Space.Compact>
72
- <Button
73
- icon={<Icon icon={HardDriveUpload} />}
74
- onClick={() => {
75
- configService.exportAll();
76
- }}
77
- >
78
- {t('storage.actions.export.button')}
79
- </Button>
80
- <Dropdown
81
- menu={{
82
- items: [
83
- {
84
- key: 'allAgent',
85
- label: t('storage.actions.export.exportType.allAgent'),
86
- onClick: configService.exportAgents,
87
- },
88
- {
89
- key: 'allAgentWithMessage',
90
- label: t('storage.actions.export.exportType.allAgentWithMessage'),
91
- onClick: configService.exportSessions,
92
- },
93
- {
94
- key: 'globalSetting',
95
- label: t('storage.actions.export.exportType.globalSetting'),
96
- onClick: configService.exportSettings,
97
- },
98
- ],
99
- }}
100
- >
101
- <Button icon={<Icon icon={ChevronDown} />} />
102
- </Dropdown>
103
- </Space.Compact>
71
+ <Button
72
+ icon={<Icon icon={HardDriveUpload} />}
73
+ onClick={() => {
74
+ configService.exportAll();
75
+ }}
76
+ >
77
+ {t('storage.actions.export.button')}
78
+ </Button>
104
79
  ),
105
80
  label: t('storage.actions.export.title'),
106
81
  minWidth: undefined,
@@ -489,6 +489,7 @@ describe('SessionModel', () => {
489
489
  it('should delete a session and its associated topics and messages', async () => {
490
490
  // Create a session
491
491
  const sessionId = '1';
492
+ await serverDB.insert(users).values([{ id: '456' }]);
492
493
  await serverDB.insert(sessions).values({ id: sessionId, userId });
493
494
 
494
495
  // Create some topics and messages associated with the session
@@ -500,6 +501,11 @@ describe('SessionModel', () => {
500
501
  { id: '1', sessionId, userId, role: 'user' },
501
502
  { id: '2', sessionId, userId, role: 'assistant' },
502
503
  ]);
504
+ await serverDB.insert(agents).values([
505
+ { id: 'a1', userId },
506
+ { id: 'a2', userId: '456' },
507
+ ]);
508
+ await serverDB.insert(agentsToSessions).values([{ agentId: 'a1', userId, sessionId: '1' }]);
503
509
 
504
510
  // Delete the session
505
511
  await sessionModel.delete(sessionId);
@@ -514,6 +520,7 @@ describe('SessionModel', () => {
514
520
  expect(
515
521
  await serverDB.select().from(messages).where(eq(messages.sessionId, sessionId)),
516
522
  ).toHaveLength(0);
523
+ expect(await serverDB.select().from(agents).where(eq(agents.userId, userId))).toHaveLength(0);
517
524
  });
518
525
 
519
526
  it('should not delete sessions belonging to other users', async () => {
@@ -576,6 +583,8 @@ describe('SessionModel', () => {
576
583
  // Create some sessions
577
584
  const sessionIds = ['1', '2', '3'];
578
585
  await serverDB.insert(sessions).values(sessionIds.map((id) => ({ id, userId })));
586
+ await serverDB.insert(agents).values([{ id: '1', userId }]);
587
+ await serverDB.insert(agentsToSessions).values([{ sessionId: '1', agentId: '1', userId }]);
579
588
 
580
589
  // Create some topics and messages associated with the sessions
581
590
  await serverDB.insert(topics).values([
@@ -602,6 +611,7 @@ describe('SessionModel', () => {
602
611
  expect(
603
612
  await serverDB.select().from(messages).where(inArray(messages.sessionId, sessionIds)),
604
613
  ).toHaveLength(0);
614
+ expect(await serverDB.select().from(agents)).toHaveLength(0);
605
615
  });
606
616
 
607
617
  it('should not delete sessions belonging to other users', async () => {
@@ -710,6 +720,14 @@ describe('SessionModel', () => {
710
720
  { id: 'm1', sessionId: '1', userId, role: 'user' },
711
721
  { id: 'm2', sessionId: '2', userId, role: 'assistant' },
712
722
  ]);
723
+ await trx.insert(agents).values([
724
+ { id: 'a1', userId },
725
+ { id: 'a2', userId },
726
+ ]);
727
+ await trx.insert(agentsToSessions).values([
728
+ { agentId: 'a1', sessionId: '1', userId },
729
+ { agentId: 'a2', sessionId: '2', userId },
730
+ ]);
713
731
  });
714
732
 
715
733
  await sessionModel.deleteAll();
@@ -723,6 +741,9 @@ describe('SessionModel', () => {
723
741
  .from(messages)
724
742
  .where(eq(messages.userId, userId));
725
743
  expect(remainingMessages).toHaveLength(0);
744
+
745
+ const agentsTopics = await serverDB.select().from(agents).where(eq(agents.userId, userId));
746
+ expect(agentsTopics).toHaveLength(0);
726
747
  });
727
748
  });
728
749
 
@@ -215,7 +215,15 @@ export class AiProviderModel {
215
215
 
216
216
  const decrypt = decryptor ?? JSON.parse;
217
217
 
218
- const keyVaults = !!result.keyVaults ? await decrypt(result.keyVaults) : {};
218
+ let keyVaults = {};
219
+
220
+ if (!!result.keyVaults) {
221
+ try {
222
+ keyVaults = await decrypt(result.keyVaults);
223
+ } catch {
224
+ /* empty */
225
+ }
226
+ }
219
227
 
220
228
  return {
221
229
  ...result,
@@ -279,26 +279,102 @@ export class SessionModel {
279
279
  // **************** Delete *************** //
280
280
 
281
281
  /**
282
- * Delete a session, also delete all messages and topics associated with it.
282
+ * Delete a session and its associated agent data if no longer referenced.
283
283
  */
284
284
  delete = async (id: string) => {
285
- return this.db
286
- .delete(sessions)
287
- .where(and(eq(sessions.id, id), eq(sessions.userId, this.userId)));
285
+ return this.db.transaction(async (trx) => {
286
+ // First get the agent IDs associated with this session
287
+ const links = await trx
288
+ .select({ agentId: agentsToSessions.agentId })
289
+ .from(agentsToSessions)
290
+ .where(and(eq(agentsToSessions.sessionId, id), eq(agentsToSessions.userId, this.userId)));
291
+
292
+ const agentIds = links.map((link) => link.agentId);
293
+
294
+ // Delete links in agentsToSessions
295
+ await trx
296
+ .delete(agentsToSessions)
297
+ .where(and(eq(agentsToSessions.sessionId, id), eq(agentsToSessions.userId, this.userId)));
298
+
299
+ // Delete the session
300
+ const result = await trx
301
+ .delete(sessions)
302
+ .where(and(eq(sessions.id, id), eq(sessions.userId, this.userId)));
303
+
304
+ // Delete orphaned agents
305
+ await this.clearOrphanAgent(agentIds, trx);
306
+
307
+ return result;
308
+ });
288
309
  };
289
310
 
290
311
  /**
291
- * Batch delete sessions, also delete all messages and topics associated with them.
312
+ * Batch delete sessions and their associated agent data if no longer referenced.
292
313
  */
293
314
  batchDelete = async (ids: string[]) => {
294
- return this.db
295
- .delete(sessions)
296
- .where(and(inArray(sessions.id, ids), eq(sessions.userId, this.userId)));
315
+ if (ids.length === 0) return { count: 0 };
316
+
317
+ return this.db.transaction(async (trx) => {
318
+ // Get agent IDs associated with these sessions
319
+ const links = await trx
320
+ .select({ agentId: agentsToSessions.agentId })
321
+ .from(agentsToSessions)
322
+ .where(
323
+ and(inArray(agentsToSessions.sessionId, ids), eq(agentsToSessions.userId, this.userId)),
324
+ );
325
+
326
+ const agentIds = [...new Set(links.map((link) => link.agentId))];
327
+
328
+ // Delete links in agentsToSessions
329
+ await trx
330
+ .delete(agentsToSessions)
331
+ .where(
332
+ and(inArray(agentsToSessions.sessionId, ids), eq(agentsToSessions.userId, this.userId)),
333
+ );
334
+
335
+ // Delete the sessions
336
+ const result = await trx
337
+ .delete(sessions)
338
+ .where(and(inArray(sessions.id, ids), eq(sessions.userId, this.userId)));
339
+
340
+ // Delete orphaned agents
341
+ await this.clearOrphanAgent(agentIds, trx);
342
+
343
+ return result;
344
+ });
297
345
  };
298
346
 
347
+ /**
348
+ * Delete all sessions and their associated agent data for this user.
349
+ */
299
350
  deleteAll = async () => {
300
- return this.db.delete(sessions).where(eq(sessions.userId, this.userId));
351
+ return this.db.transaction(async (trx) => {
352
+ // Delete all agentsToSessions for this user
353
+ await trx.delete(agentsToSessions).where(eq(agentsToSessions.userId, this.userId));
354
+
355
+ // Delete all agents that were only used by this user's sessions
356
+ await trx.delete(agents).where(eq(agents.userId, this.userId));
357
+
358
+ // Delete all sessions for this user
359
+ return trx.delete(sessions).where(eq(sessions.userId, this.userId));
360
+ });
361
+ };
362
+
363
+ clearOrphanAgent = async (agentIds: string[], trx: any) => {
364
+ // Delete orphaned agents (those not linked to any other sessions)
365
+ for (const agentId of agentIds) {
366
+ const remaining = await trx
367
+ .select()
368
+ .from(agentsToSessions)
369
+ .where(eq(agentsToSessions.agentId, agentId))
370
+ .limit(1);
371
+
372
+ if (remaining.length === 0) {
373
+ await trx.delete(agents).where(and(eq(agents.id, agentId), eq(agents.userId, this.userId)));
374
+ }
375
+ }
301
376
  };
377
+
302
378
  // **************** Update *************** //
303
379
 
304
380
  update = async (id: string, data: Partial<SessionItem>) => {
@@ -64,7 +64,7 @@ const useStyles = createStyles(({ token, css }) => {
64
64
  `,
65
65
  modalContent: css`
66
66
  padding-block: ${token.paddingMD}px;
67
- padding-inline: 0;
67
+ padding-inline: 0;
68
68
  `,
69
69
  successIcon: css`
70
70
  color: ${token.colorSuccess};
@@ -116,7 +116,7 @@ export const useMenu = () => {
116
116
  {
117
117
  icon: <Icon icon={HardDriveDownload} />,
118
118
  key: 'import',
119
- label: <DataImporter>{t('import')}</DataImporter>,
119
+ label: <DataImporter>{t('importData')}</DataImporter>,
120
120
  },
121
121
  {
122
122
  type: 'divider',
@@ -186,7 +186,7 @@ export default {
186
186
  },
187
187
  fullscreen: '全屏模式',
188
188
  historyRange: '历史范围',
189
- import: '导入配置',
189
+ importData: '导入数据',
190
190
  importModal: {
191
191
  error: {
192
192
  desc: '非常抱歉,数据导入过程发生异常。请尝试重新导入,或 <1>提交问题</1>,我们将会第一时间帮你排查问题。',
@@ -225,7 +225,7 @@ export default {
225
225
  name: '表名',
226
226
  },
227
227
  title: '导入数据预览',
228
- totalRecords:"总计将导入 {{count}} 条记录",
228
+ totalRecords: '总计将导入 {{count}} 条记录',
229
229
  totalTables: '{{count}} 个表',
230
230
  },
231
231
  information: '社区与资讯',