fix: Data config improvement (#7471)

* fix: update localization files for data migration warnings and path validation messages

* fix: update app data path validation and localization messages for installation path consistency

* fix: enhance app data flushing process by adding connection closure and delay in DataSettings component
This commit is contained in:
beyondkmp 2025-06-23 17:18:46 +08:00 committed by GitHub
parent aee8fe6196
commit be15206234
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 69 additions and 40 deletions

View File

@ -1,5 +1,6 @@
import fs from 'node:fs'
import { arch } from 'node:os'
import path from 'node:path'
import { isMac, isWin } from '@main/constant'
import { getBinaryPath, isBinaryExists, runInstallScript } from '@main/utils/process'
@ -57,7 +58,8 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
resourcesPath: getResourcePath(),
logsPath: log.transports.file.getFile().path,
arch: arch(),
isPortable: isWin && 'PORTABLE_EXECUTABLE_DIR' in process.env
isPortable: isWin && 'PORTABLE_EXECUTABLE_DIR' in process.env,
installPath: path.dirname(app.getPath('exe'))
}))
ipcMain.handle(IpcChannel.App_Proxy, async (_, proxy: string) => {
@ -233,7 +235,13 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
BrowserWindow.getAllWindows().forEach((w) => {
w.webContents.session.flushStorageData()
w.webContents.session.cookies.flushStore()
w.webContents.session.closeAllConnections()
})
session.defaultSession.flushStorageData()
session.defaultSession.cookies.flushStore()
session.defaultSession.closeAllConnections()
})
ipcMain.handle(IpcChannel.App_IsNotEmptyDir, async (_, path: string) => {

View File

@ -1091,7 +1091,7 @@
"app_data.copy_data_option": "Copy data, will automatically restart after copying the original directory data to the new directory",
"app_data.copy_time_notice": "Copying data may take a while, do not force quit app",
"app_data.path_changed_without_copy": "Path changed successfully",
"app_data.copying_warning": "Data copying, do not force quit app",
"app_data.copying_warning": "Data copying, do not force quit app, the app will restart after copied",
"app_data.copying": "Copying data to new location...",
"app_data.copy_success": "Successfully copied data to new location",
"app_data.copy_failed": "Failed to copy data",
@ -1104,8 +1104,9 @@
"app_data.select_error_write_permission": "New path does not have write permission",
"app_data.stop_quit_app_reason": "The app is currently migrating data and cannot be exited",
"app_data.select_not_empty_dir": "New path is not empty",
"app_data.select_not_empty_dir_content": "New path is not empty, if you select copy, it will overwrite the data in the new path, there is a risk of data loss, continue?",
"app_data.select_not_empty_dir_content": "New path is not empty, it will overwrite the data in the new path, there is a risk of data loss and copy failure, continue?",
"app_data.select_error_same_path": "New path is the same as the old path, please select another path",
"app_data.select_error_in_app_path": "New path is the same as the application installation path, please select another path",
"app_knowledge": "Knowledge Base Files",
"app_knowledge.button.delete": "Delete File",
"app_knowledge.remove_all": "Remove Knowledge Base Files",

View File

@ -1089,7 +1089,7 @@
"app_data.copy_data_option": "データをコピーする, 開くと元のディレクトリのデータが新しいディレクトリにコピーされます。",
"app_data.copy_time_notice": "データコピーには時間がかかります。アプリを強制終了しないでください。",
"app_data.path_changed_without_copy": "パスが変更されました。",
"app_data.copying_warning": "データコピー中、アプリを強制終了しないでください",
"app_data.copying_warning": "データコピー中、アプリを強制終了しないでください。コピーが完了すると、アプリが自動的に再起動します。",
"app_data.copying": "新しい場所にデータをコピーしています...",
"app_data.copy_success": "データを新しい場所に正常にコピーしました",
"app_data.copy_failed": "データのコピーに失敗しました",
@ -1102,8 +1102,9 @@
"app_data.select_error_write_permission": "新しいパスに書き込み権限がありません",
"app_data.stop_quit_app_reason": "アプリは現在データを移行しているため、終了できません",
"app_data.select_not_empty_dir": "新しいパスは空ではありません",
"app_data.select_not_empty_dir_content": "新しいパスは空ではありません。コピーを選択すると、新しいパスのデータが上書きされます。データが失われるリスクがあります。続行しますか?",
"app_data.select_not_empty_dir_content": "新しいパスは空ではありません。新しいパスのデータが上書きされます。データが失われるリスクがあります。続行しますか?",
"app_data.select_error_same_path": "新しいパスは元のパスと同じです。別のパスを選択してください",
"app_data.select_error_in_app_path": "新しいパスはアプリのインストールパスと同じです。別のパスを選択してください",
"app_knowledge": "知識ベースファイル",
"app_knowledge.button.delete": "ファイルを削除",
"app_knowledge.remove_all": "ナレッジベースファイルを削除",

View File

@ -1089,7 +1089,7 @@
"app_data.copy_data_option": "Копировать данные, будет автоматически перезапущено после копирования данных из исходной директории в новую директорию",
"app_data.copy_time_notice": "Копирование данных из исходной директории займет некоторое время, пожалуйста, будьте терпеливы",
"app_data.path_changed_without_copy": "Путь изменен успешно",
"app_data.copying_warning": "Копирование данных, нельзя взаимодействовать с приложением, не закрывайте приложение",
"app_data.copying_warning": "Копирование данных, нельзя взаимодействовать с приложением, не закрывайте приложение, приложение будет перезапущено после копирования",
"app_data.copying": "Копирование данных в новое место...",
"app_data.copy_success": "Данные успешно скопированы в новое место",
"app_data.copy_failed": "Не удалось скопировать данные",
@ -1102,7 +1102,8 @@
"app_data.select_error_write_permission": "Новый путь не имеет разрешения на запись",
"app_data.stop_quit_app_reason": "Приложение в настоящее время перемещает данные и не может быть закрыто",
"app_data.select_not_empty_dir": "Новый путь не пуст",
"app_data.select_not_empty_dir_content": "Новый путь не пуст, если вы выбираете копирование, он перезапишет данные в новом пути, есть риск потери данных, продолжить?",
"app_data.select_not_empty_dir_content": "Новый путь не пуст, он перезапишет данные в новом пути, есть риск потери данных и ошибки копирования, продолжить?",
"app_data.select_error_in_app_path": "Новый путь совпадает с исходным путем, пожалуйста, выберите другой путь",
"app_data.select_error_same_path": "Новый путь совпадает с исходным путем, пожалуйста, выберите другой путь",
"app_knowledge": "Файлы базы знаний",
"app_knowledge.button.delete": "Удалить файл",

View File

@ -1091,7 +1091,7 @@
"app_data.copy_data_option": "复制数据,会自动重启后将原始目录数据复制到新目录",
"app_data.copy_time_notice": "复制数据将需要一些时间,复制期间不要关闭应用",
"app_data.path_changed_without_copy": "路径已更改成功",
"app_data.copying_warning": "数据复制中不要强制退出app",
"app_data.copying_warning": "数据复制中不要强制退出app, 复制完成后会自动重启应用",
"app_data.copying": "正在将数据复制到新位置...",
"app_data.copy_success": "已成功复制数据到新位置",
"app_data.copy_failed": "复制数据失败",
@ -1104,8 +1104,9 @@
"app_data.select_error_write_permission": "新路径没有写入权限",
"app_data.stop_quit_app_reason": "应用目前在迁移数据, 不能退出",
"app_data.select_not_empty_dir": "新路径不为空",
"app_data.select_not_empty_dir_content": "新路径不为空,选择复制将覆盖新路径中的数据, 有数据丢失的风险,是否继续?",
"app_data.select_not_empty_dir_content": "新路径不为空,将覆盖新路径中的数据, 有数据丢失和复制失败的风险,是否继续?",
"app_data.select_error_same_path": "新路径与旧路径相同,请选择其他路径",
"app_data.select_error_in_app_path": "新路径与应用安装路径相同,请选择其他路径",
"app_knowledge": "知识库文件",
"app_knowledge.button.delete": "删除文件",
"app_knowledge.remove_all": "删除知识库文件",

View File

@ -1091,7 +1091,7 @@
"app_data.copy_data_option": "複製數據, 會自動重啟後將原始目錄數據複製到新目錄",
"app_data.copy_time_notice": "複製數據將需要一些時間,複製期間不要關閉應用",
"app_data.path_changed_without_copy": "路徑已變更成功",
"app_data.copying_warning": "數據複製中,不要強制退出應用",
"app_data.copying_warning": "數據複製中,不要強制退出應用, 複製完成後會自動重啟應用",
"app_data.copying": "正在複製數據到新位置...",
"app_data.copy_success": "成功複製數據到新位置",
"app_data.copy_failed": "複製數據失敗",
@ -1104,8 +1104,9 @@
"app_data.select_error_write_permission": "新路徑沒有寫入權限",
"app_data.stop_quit_app_reason": "應用目前正在遷移數據,不能退出",
"app_data.select_not_empty_dir": "新路徑不為空",
"app_data.select_not_empty_dir_content": "新路徑不為空,選擇複製將覆蓋新路徑中的數據, 有數據丟失的風險,是否繼續?",
"app_data.select_not_empty_dir_content": "新路徑不為空,選擇複製將覆蓋新路徑中的數據, 有數據丟失和複製失敗的風險,是否繼續?",
"app_data.select_error_same_path": "新路徑與舊路徑相同,請選擇其他路徑",
"app_data.select_error_in_app_path": "新路徑與應用安裝路徑相同,請選擇其他路徑",
"app_knowledge": "知識庫文件",
"app_knowledge.button.delete": "刪除檔案",
"app_knowledge.remove_all": "刪除知識庫檔案",

View File

@ -202,12 +202,18 @@ const DataSettings: FC = () => {
return
}
// check new app data path is same as old app data path
if (newAppDataPath.startsWith(appInfo!.appDataPath)) {
// check new app data path is not in old app data path
if (newAppDataPath.startsWith(appInfo.appDataPath)) {
window.message.error(t('settings.data.app_data.select_error_same_path'))
return
}
// check new app data path is not in app install path
if (newAppDataPath.startsWith(appInfo.installPath)) {
window.message.error(t('settings.data.app_data.select_error_in_app_path'))
return
}
// check new app data path has write permission
const hasWritePermission = await window.api.hasWritePermission(newAppDataPath)
if (!hasWritePermission) {
@ -219,25 +225,30 @@ const DataSettings: FC = () => {
<div style={{ fontSize: '18px', fontWeight: 'bold' }}>{t('settings.data.app_data.migration_title')}</div>
)
const migrationClassName = 'migration-modal'
if (await window.api.isNotEmptyDir(newAppDataPath)) {
const modal = window.modal.confirm({
title: t('settings.data.app_data.select_not_empty_dir'),
content: t('settings.data.app_data.select_not_empty_dir_content'),
centered: true,
okText: t('common.confirm'),
cancelText: t('common.cancel'),
onOk: () => {
modal.destroy()
// 显示确认对话框
showMigrationConfirmModal(appInfo.appDataPath, newAppDataPath, migrationTitle, migrationClassName)
}
})
return
}
showMigrationConfirmModal(appInfo.appDataPath, newAppDataPath, migrationTitle, migrationClassName)
}
const doubleConfirmModalBeforeCopyData = (newPath: string) => {
window.modal.confirm({
title: t('settings.data.app_data.select_not_empty_dir'),
content: t('settings.data.app_data.select_not_empty_dir_content'),
centered: true,
okText: t('common.confirm'),
cancelText: t('common.cancel'),
onOk: () => {
window.message.info({
content: t('settings.data.app_data.restart_notice'),
duration: 2
})
setTimeout(() => {
window.api.relaunchApp({
args: ['--new-data-path=' + newPath]
})
}, 500)
}
})
}
// 显示确认迁移的对话框
const showMigrationConfirmModal = async (
originalPath: string,
@ -280,7 +291,7 @@ const DataSettings: FC = () => {
)
// 显示确认模态框
const modal = window.modal.confirm({
window.modal.confirm({
title,
className,
width: 'min(600px, 90vw)',
@ -305,11 +316,12 @@ const DataSettings: FC = () => {
cancelText: t('common.cancel'),
onOk: async () => {
try {
// 立即关闭确认对话框
modal.destroy()
if (shouldCopyData) {
// 如果选择复制数据,显示进度模态框并执行迁移
if (await window.api.isNotEmptyDir(newPath)) {
doubleConfirmModalBeforeCopyData(newPath)
return
}
window.message.info({
content: t('settings.data.app_data.restart_notice'),
duration: 3
@ -318,12 +330,12 @@ const DataSettings: FC = () => {
window.api.relaunchApp({
args: ['--new-data-path=' + newPath]
})
}, 300)
} else {
// 如果不复制数据,直接设置新的应用数据路径
await window.api.setAppDataPath(newPath)
window.message.success(t('settings.data.app_data.path_changed_without_copy'))
}, 500)
return
}
// 如果不复制数据,直接设置新的应用数据路径
await window.api.setAppDataPath(newPath)
window.message.success(t('settings.data.app_data.path_changed_without_copy'))
// 更新应用数据路径
setAppInfo(await window.api.getAppInfo())
@ -333,7 +345,7 @@ const DataSettings: FC = () => {
window.message.success(t('settings.data.app_data.select_success'))
window.api.setStopQuitApp(false, '')
window.api.relaunchApp()
}, 1000)
}, 500)
} catch (error) {
window.api.setStopQuitApp(false, '')
window.message.error({
@ -484,6 +496,9 @@ const DataSettings: FC = () => {
// flush app data
await window.api.flushAppData()
// wait 2 seconds to flush app data
await new Promise((resolve) => setTimeout(resolve, 2000))
// 开始复制过程
const copyResult = await window.api.copy(originalPath, newPath)

View File

@ -387,6 +387,7 @@ export type AppInfo = {
logsPath: string
arch: string
isPortable: boolean
installPath: string
}
export interface Shortcut {