Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/main/presenter/syncPresenter/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { app, shell } from 'electron'
import path from 'path'
import fs from 'fs'
import Database from 'better-sqlite3-multiple-ciphers'
import { ISyncPresenter, IConfigPresenter, ISQLitePresenter } from '@shared/presenter'
import { eventBus, SendTarget } from '@/eventbus'
import { SYNC_EVENTS } from '@/events'
Expand Down Expand Up @@ -121,7 +122,13 @@ export class SyncPresenter implements ISyncPresenter {
*/
public async importFromSync(
importMode: ImportMode = ImportMode.INCREMENT
): Promise<{ success: boolean; message: string }> {
): Promise<{ success: boolean; message: string; count?: number }> {
// Cancel any pending backup to prevent overwriting the backup files during import
if (this.backupTimer) {
clearTimeout(this.backupTimer)
this.backupTimer = null
}

// 检查同步文件夹是否存在
const { exists, path: syncFolderPath } = await this.checkSyncFolder()
if (!exists) {
Expand Down Expand Up @@ -174,13 +181,22 @@ export class SyncPresenter implements ISyncPresenter {
this.copyDirectory(this.PROVIDER_MODELS_DIR_PATH, tempProviderModelsPath)
}

let importedCount = 0
try {
if (importMode === ImportMode.OVERWRITE) {
// For overwrite mode, count conversations from backup db in read-only mode
const backupDb = new Database(dbBackupPath, { readonly: true })
const result = backupDb.prepare('SELECT COUNT(*) as count FROM conversations').get() as {
count: number
}
importedCount = result.count
backupDb.close()

fs.copyFileSync(dbBackupPath, this.DB_PATH)
} else {
// 使用 DataImporter 导入数据
// For incremental mode, DataImporter returns the actual imported count
const importer = new DataImporter(dbBackupPath, this.DB_PATH)
const importedCount = await importer.importData()
importedCount = await importer.importData()
console.log(`成功导入 ${importedCount} 个会话`)
importer.close()
}
Expand Down Expand Up @@ -229,7 +245,7 @@ export class SyncPresenter implements ISyncPresenter {
}

eventBus.send(SYNC_EVENTS.IMPORT_COMPLETED, SendTarget.ALL_WINDOWS)
return { success: true, message: 'sync.success.importComplete' }
return { success: true, message: 'sync.success.importComplete', count: importedCount }
} catch (error: unknown) {
console.error('导入文件失败,恢复备份:', error)

Expand Down
13 changes: 6 additions & 7 deletions src/renderer/settings/components/DataSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,7 @@
<!-- 导入数据 -->
<Dialog v-model:open="isImportDialogOpen">
<DialogTrigger as-child>
<Button
variant="outline"
@click="syncStore.startBackup"
:disabled="!syncStore.syncEnabled"
:dir="languageStore.dir"
>
<Button variant="outline" :disabled="!syncStore.syncEnabled" :dir="languageStore.dir">
<Icon icon="lucide:download" class="w-4 h-4 text-muted-foreground" />
<span class="text-sm font-medium">{{ t('settings.data.importData') }}</span>
</Button>
Expand Down Expand Up @@ -219,7 +214,11 @@
: t('settings.data.importErrorTitle')
}}</AlertDialogTitle>
<AlertDialogDescription>
{{ syncStore.importResult?.message ? t(syncStore.importResult.message) : '' }}
{{
syncStore.importResult?.message
? t(syncStore.importResult.message, { count: syncStore.importResult.count || 0 })
: ''
}}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/en-US/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "Import complete. The application will now restart."
"importComplete": "Successfully imported {count} conversation(s). The application will now restart."
},
"error": {
"notEnabled": "Sync is not enabled",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/fa-IR/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "داده با موفقیت وارد شد. برای راه‌اندازی دوباره برنامه، روی دکمه خوب بزنید."
"importComplete": "{count} مکالمه با موفقیت وارد شد. برای راه‌اندازی دوباره برنامه، روی دکمه خوب بزنید."
},
"error": {
"notEnabled": "ویژگی همگام‌سازی روشن نیست",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/fr-FR/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "Données importées avec succès. Cliquez sur OK pour redémarrer l'application."
"importComplete": "{count} conversation(s) importée(s) avec succès. Cliquez sur OK pour redémarrer l'application."
},
"error": {
"notEnabled": "La fonction de synchronisation n'est pas activée",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/ja-JP/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "データのインポートが完了しました。OKをクリックして、アプリケーションを再起動します。"
"importComplete": "{count}件の会話をインポートしました。OKをクリックして、アプリケーションを再起動します。"
},
"error": {
"notEnabled": "同期機能が有効になっていません",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/ko-KR/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "데이터가 성공적으로 가져와졌습니다. 애플리케이션을 다시 시작하려면 확인을 클릭하세요."
"importComplete": "{count}개의 대화를 성공적으로 가져왔습니다. 애플리케이션을 다시 시작하려면 확인을 클릭하세요."
},
"error": {
"notEnabled": "동기화 기능이 활성화되지 않았습니다",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/pt-BR/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "Importação concluída. O aplicativo será reiniciado agora."
"importComplete": "{count} conversa(s) importada(s) com sucesso. O aplicativo será reiniciado agora."
},
"error": {
"notEnabled": "A sincronização não está ativada",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/ru-RU/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "Данные успешно импортированы. Нажмите OK для перезапуска приложения."
"importComplete": "Успешно импортировано {count} диалогов. Нажмите OK для перезапуска приложения."
},
"error": {
"notEnabled": "Функция синхронизации не включена",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/zh-CN/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "数据导入成功,点击确定后将重启应用"
"importComplete": "成功导入 {count} 个对话,点击确定后将重启应用"
},
"error": {
"notEnabled": "同步功能未启用",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/zh-HK/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "數據導入成功,點擊確定後將重新啟動應用"
"importComplete": "成功導入 {count} 個對話,點擊確定後將重新啟動應用"
},
"error": {
"notEnabled": "同步功能未啟用",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/i18n/zh-TW/sync.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"success": {
"importComplete": "資料匯入成功,點選「確定」後將重新啟動應用程式"
"importComplete": "成功匯入 {count} 個對話,點選「確定」後將重新啟動應用程式"
},
"error": {
"notEnabled": "同步功能未啟用",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/stores/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const useSyncStore = defineStore('sync', () => {
const lastSyncTime = ref(0)
const isBackingUp = ref(false)
const isImporting = ref(false)
const importResult = ref<{ success: boolean; message: string } | null>(null)
const importResult = ref<{ success: boolean; message: string; count?: number } | null>(null)

// 获取 presenter 实例
const configPresenter = usePresenter('configPresenter')
Expand Down
4 changes: 3 additions & 1 deletion src/shared/types/presenters/legacy.presenters.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1339,7 +1339,9 @@ export interface ISyncPresenter {
getBackupStatus(): Promise<{ isBackingUp: boolean; lastBackupTime: number }>

// Import related operations
importFromSync(importMode?: ImportMode): Promise<{ success: boolean; message: string }>
importFromSync(
importMode?: ImportMode
): Promise<{ success: boolean; message: string; count?: number }>
checkSyncFolder(): Promise<{ exists: boolean; path: string }>
openSyncFolder(): Promise<void>

Expand Down