From d6dd34db879b944eba6f04e4c33789ffef313e1a Mon Sep 17 00:00:00 2001 From: landaiqing Date: Sun, 22 Jun 2025 21:30:45 +0800 Subject: [PATCH] :recycle: Refactor and clean up the code --- .../voidraft/internal/models/models.ts | 14 +- .../internal/services/configservice.ts | 10 +- .../internal/services/keybindingservice.ts | 6 +- frontend/src/components/toolbar/Toolbar.vue | 14 +- frontend/src/i18n/locales/en-US.ts | 69 +---- frontend/src/i18n/locales/zh-CN.ts | 69 +---- frontend/src/stores/configStore.ts | 89 +++---- frontend/src/stores/documentStore.ts | 21 +- frontend/src/stores/editorStore.ts | 144 +++++------ frontend/src/stores/logStore.ts | 166 ------------ frontend/src/utils/errorHandler.ts | 97 ------- .../views/settings/pages/AppearancePage.vue | 12 +- .../src/views/settings/pages/EditingPage.vue | 57 +---- .../src/views/settings/pages/GeneralPage.vue | 12 +- go.mod | 20 +- go.sum | 36 ++- internal/models/config.go | 4 +- .../services/config_notification_service.go | 22 +- internal/services/config_service.go | 240 +++++++++--------- internal/services/keybinding_service.go | 83 +++--- internal/services/path_manager.go | 15 -- ...n_service.go => path_migration_service.go} | 0 22 files changed, 357 insertions(+), 843 deletions(-) delete mode 100644 frontend/src/stores/logStore.ts delete mode 100644 frontend/src/utils/errorHandler.ts rename internal/services/{migration_service.go => path_migration_service.go} (100%) diff --git a/frontend/bindings/voidraft/internal/models/models.ts b/frontend/bindings/voidraft/internal/models/models.ts index 2f26024..8da8c69 100644 --- a/frontend/bindings/voidraft/internal/models/models.ts +++ b/frontend/bindings/voidraft/internal/models/models.ts @@ -132,11 +132,19 @@ export class ConfigMetadata { */ "lastUpdated": string; + /** + * 配置版本号 + */ + "version": string; + /** Creates a new ConfigMetadata instance. */ constructor($$source: Partial = {}) { if (!("lastUpdated" in $$source)) { this["lastUpdated"] = ""; } + if (!("version" in $$source)) { + this["version"] = ""; + } Object.assign(this, $$source); } @@ -978,7 +986,7 @@ export class UpdatesConfig { /** * 当前版本号 */ - "Version": string; + "version": string; /** * 是否自动更新 @@ -992,8 +1000,8 @@ export class UpdatesConfig { /** Creates a new UpdatesConfig instance. */ constructor($$source: Partial = {}) { - if (!("Version" in $$source)) { - this["Version"] = ""; + if (!("version" in $$source)) { + this["version"] = ""; } if (!("autoUpdate" in $$source)) { this["autoUpdate"] = false; diff --git a/frontend/bindings/voidraft/internal/services/configservice.ts b/frontend/bindings/voidraft/internal/services/configservice.ts index 172a111..1067bd3 100644 --- a/frontend/bindings/voidraft/internal/services/configservice.ts +++ b/frontend/bindings/voidraft/internal/services/configservice.ts @@ -2,7 +2,7 @@ // This file is automatically generated. DO NOT EDIT /** - * ConfigService 提供基于 Viper 的配置管理功能 + * ConfigService 应用配置服务 * @module */ @@ -42,6 +42,14 @@ export function ResetConfig(): Promise & { cancel(): void } { return $resultPromise; } +/** + * ServiceShutdown 关闭服务 + */ +export function ServiceShutdown(): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(3963562361) as any; + return $resultPromise; +} + /** * Set 设置配置项 */ diff --git a/frontend/bindings/voidraft/internal/services/keybindingservice.ts b/frontend/bindings/voidraft/internal/services/keybindingservice.ts index a3fed66..924ec75 100644 --- a/frontend/bindings/voidraft/internal/services/keybindingservice.ts +++ b/frontend/bindings/voidraft/internal/services/keybindingservice.ts @@ -39,10 +39,10 @@ export function GetKeyBindingConfig(): Promise } /** - * Shutdown 关闭服务 + * ServiceShutdown 关闭服务 */ -export function Shutdown(): Promise & { cancel(): void } { - let $resultPromise = $Call.ByID(3046465148) as any; +export function ServiceShutdown(): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(1610182855) as any; return $resultPromise; } diff --git a/frontend/src/components/toolbar/Toolbar.vue b/frontend/src/components/toolbar/Toolbar.vue index d6f17c5..77c3543 100644 --- a/frontend/src/components/toolbar/Toolbar.vue +++ b/frontend/src/components/toolbar/Toolbar.vue @@ -3,7 +3,6 @@ import {useI18n} from 'vue-i18n'; import {onMounted, onUnmounted, ref, watch} from 'vue'; import {useConfigStore} from '@/stores/configStore'; import {useEditorStore} from '@/stores/editorStore'; -import {useErrorHandler} from '@/utils/errorHandler'; import * as runtime from '@wailsio/runtime'; import {useRouter} from 'vue-router'; import BlockLanguageSelector from './BlockLanguageSelector.vue'; @@ -12,25 +11,20 @@ import {getLanguage} from '@/views/editor/extensions/codeblock/lang-parser/langu const editorStore = useEditorStore(); const configStore = useConfigStore(); -const {safeCall} = useErrorHandler(); const {t} = useI18n(); const router = useRouter(); // 设置窗口置顶 const setWindowAlwaysOnTop = async (isTop: boolean) => { - await safeCall(async () => { - await runtime.Window.SetAlwaysOnTop(isTop); - }, 'window.setTopFailed'); + await runtime.Window.SetAlwaysOnTop(isTop); }; // 切换窗口置顶 const toggleAlwaysOnTop = async () => { - await safeCall(async () => { - await configStore.toggleAlwaysOnTop(); - // 使用Window.SetAlwaysOnTop方法设置窗口置顶状态 - await runtime.Window.SetAlwaysOnTop(configStore.config.general.alwaysOnTop); - }, 'config.alwaysOnTopFailed'); + await configStore.toggleAlwaysOnTop(); + // 使用Window.SetAlwaysOnTop方法设置窗口置顶状态 + await runtime.Window.SetAlwaysOnTop(configStore.config.general.alwaysOnTop); }; // 跳转到设置页面 diff --git a/frontend/src/i18n/locales/en-US.ts b/frontend/src/i18n/locales/en-US.ts index 8a2e64c..d5c55d4 100644 --- a/frontend/src/i18n/locales/en-US.ts +++ b/frontend/src/i18n/locales/en-US.ts @@ -11,70 +11,19 @@ export default { characters: 'Ch', selected: 'Sel' }, - fontSize: 'Font Size', fontSizeTooltip: 'Font Size (Ctrl+wheel to adjust)', - tabLabel: 'Tab', - tabType: { - spaces: 'Spaces', - tab: 'Tab' - }, - encoding: 'UTF-8', settings: 'Settings', alwaysOnTop: 'Always on Top', blockLanguage: 'Block Language', searchLanguage: 'Search language...', noLanguageFound: 'No language found', - autoDetected: 'Auto-detected', formatHint: 'Current block supports formatting, use Ctrl+Shift+F shortcut for formatting', }, - config: { - loadSuccess: 'Configuration loaded successfully', - loadFailed: 'Failed to load configuration', - saveSuccess: 'Configuration saved', - saveFailed: 'Failed to save configuration', - resetSuccess: 'Configuration reset to defaults', - resetFailed: 'Failed to reset configuration', - fontSizeFixed: 'Font size ({value}) has been corrected to {fixed}', - tabSizeFixed: 'Tab size ({value}) has been corrected to {fixed}', - tabTypeFixed: 'Tab type ({value}) is invalid, corrected to spaces', - alwaysOnTopFailed: 'Failed to set window always on top', - alwaysOnTopSuccess: 'Window always on top status updated', - languageChanged: 'Language setting updated', - languageChangeFailed: 'Failed to update language setting', - themeChanged: 'Theme setting updated', - themeChangeFailed: 'Failed to update theme setting', - systemThemeChanged: 'System theme setting updated', - systemThemeChangeFailed: 'Failed to update system theme setting', - startupSuccess: 'Startup setting updated', - startupFailed: 'Failed to update startup setting' - }, - languages: { - 'zh-CN': '简体中文', - 'en-US': 'English' - }, systemTheme: { dark: 'Dark', light: 'Light', auto: 'Follow System' }, - document: { - loadSuccess: 'Document loaded successfully', - loadFailed: 'Failed to load document', - saveSuccess: 'Document saved successfully', - saveFailed: 'Failed to save document', - manualSaveSuccess: 'Manually saved successfully', - settings: { - loadFailed: 'Failed to load save settings', - saveSuccess: 'Save settings updated', - saveFailed: 'Failed to update save settings' - }, - }, - migration: { - started: 'Starting data migration', - migrating: 'Migrating', - completed: 'Migration Completed', - failed: 'Migration Failed' - }, keybindings: { headers: { shortcut: 'Shortcut', @@ -88,10 +37,7 @@ export default { searchToggleWord: 'Toggle whole word matching', searchToggleRegex: 'Toggle regular expression matching', searchShowReplace: 'Show replace functionality', - searchFindNext: 'Find next match', - searchFindPrev: 'Find previous match', searchReplaceAll: 'Replace all matches', - searchSelectAll: 'Select all content', blockSelectAll: 'Select all in block', blockAddAfterCurrent: 'Add new block after current', blockAddAfterLast: 'Add new block at end', @@ -125,7 +71,6 @@ export default { selectSyntaxRight: 'Select syntax right', copyLineUp: 'Copy line up', copyLineDown: 'Copy line down', - simplifySelection: 'Simplify selection', insertBlankLine: 'Insert blank line', selectLine: 'Select line', selectParentSyntax: 'Select parent syntax', @@ -151,10 +96,7 @@ export default { appearance: 'Appearance', keyBindings: 'Key Bindings', updates: 'Updates', - comingSoon: 'Coming Soon...', - save: 'Save', reset: 'Reset', - cancel: 'Cancel', dangerZone: 'Danger Zone', resetAllSettings: 'Reset All Settings', confirmReset: 'Click again to confirm reset', @@ -171,7 +113,6 @@ export default { clickToSelectPath: 'Click to select path', resetDefault: 'Reset Default', resetToDefaultPath: 'Reset to default path', - restartRequiredForDataPath: 'Restart required', fontSize: 'Font Size', fontSizeDescription: 'Editor font size', fontSettings: 'Font Settings', @@ -189,15 +130,7 @@ export default { enableTabIndent: 'Enable Tab Indent', language: 'Interface Language', systemTheme: 'System Theme', - theme: 'Editor Theme', - themeDescription: 'Choose editor theme', - restartRequired: '(Restart required)', saveOptions: 'Save Options', - autoSaveDelay: 'Auto Save Delay (ms)', - selectDirectoryFailed: 'Failed to select directory', - validation: { - customPathRequired: 'A valid directory must be selected when enabling custom path', - customPathAutoDisabled: 'Custom data path has been automatically disabled due to no valid directory selected' - } + autoSaveDelay: 'Auto Save Delay (ms)' } }; \ No newline at end of file diff --git a/frontend/src/i18n/locales/zh-CN.ts b/frontend/src/i18n/locales/zh-CN.ts index 64a1629..8894516 100644 --- a/frontend/src/i18n/locales/zh-CN.ts +++ b/frontend/src/i18n/locales/zh-CN.ts @@ -11,70 +11,19 @@ export default { characters: 'Ch', selected: 'Sel' }, - fontSize: '字体大小', fontSizeTooltip: '字体大小 (Ctrl+滚轮调整)', - tabLabel: 'Tab', - tabType: { - spaces: '空格', - tab: '制表符' - }, - encoding: 'UTF-8', settings: '设置', alwaysOnTop: '窗口置顶', blockLanguage: '块语言', searchLanguage: '搜索语言...', noLanguageFound: '未找到匹配的语言', - autoDetected: '自动检测', formatHint: '当前区块支持格式化,使用 Ctrl+Shift+F 进行格式化', }, - config: { - loadSuccess: '配置加载成功', - loadFailed: '配置加载失败', - saveSuccess: '配置已保存', - saveFailed: '配置保存失败', - resetSuccess: '配置已重置为默认值', - resetFailed: '重置配置失败', - fontSizeFixed: '字体大小值({value})已被修正为{fixed}', - tabSizeFixed: 'Tab大小值({value})已被修正为{fixed}', - tabTypeFixed: 'Tab类型({value})不合法,已修正为空格', - alwaysOnTopFailed: '无法设置窗口置顶状态', - alwaysOnTopSuccess: '窗口置顶状态已更新', - languageChanged: '语言设置已更新', - languageChangeFailed: '语言设置更新失败', - themeChanged: '主题设置已更新', - themeChangeFailed: '主题设置更新失败', - systemThemeChanged: '系统主题设置已更新', - systemThemeChangeFailed: '系统主题设置更新失败', - startupSuccess: '开机启动设置已更新', - startupFailed: '开机启动设置失败' - }, - languages: { - 'zh-CN': '简体中文', - 'en-US': 'English' - }, systemTheme: { dark: '深色', light: '浅色', auto: '跟随系统' }, - document: { - loadSuccess: '文档加载成功', - loadFailed: '文档加载失败', - saveSuccess: '文档保存成功', - saveFailed: '文档保存失败', - manualSaveSuccess: '手动保存成功', - settings: { - loadFailed: '加载保存设置失败', - saveSuccess: '保存设置已更新', - saveFailed: '保存设置更新失败' - }, - }, - migration: { - started: '开始迁移数据', - migrating: '迁移中', - completed: '迁移已完成', - failed: '迁移失败' - }, keybindings: { headers: { shortcut: '快捷键', @@ -88,10 +37,7 @@ export default { searchToggleWord: '切换整词匹配', searchToggleRegex: '切换正则表达式匹配', searchShowReplace: '显示替换功能', - searchFindNext: '查找下一个匹配项', - searchFindPrev: '查找上一个匹配项', searchReplaceAll: '替换全部匹配项', - searchSelectAll: '选择全部内容', blockSelectAll: '块内选择全部', blockAddAfterCurrent: '在当前块后添加新块', blockAddAfterLast: '在最后添加新块', @@ -125,7 +71,6 @@ export default { selectSyntaxRight: '按语法选择右侧', copyLineUp: '向上复制行', copyLineDown: '向下复制行', - simplifySelection: '简化选择', insertBlankLine: '插入空行', selectLine: '选择行', selectParentSyntax: '选择父级语法', @@ -151,10 +96,7 @@ export default { appearance: '外观', keyBindings: '快捷键', updates: '更新', - comingSoon: '即将推出...', - save: '保存', reset: '重置', - cancel: '取消', dangerZone: '危险操作', resetAllSettings: '重置所有设置', confirmReset: '再次点击确认重置', @@ -171,7 +113,6 @@ export default { clickToSelectPath: '点击选择路径', resetDefault: '恢复默认', resetToDefaultPath: '恢复为默认路径', - restartRequiredForDataPath: '需要重启应用程序', fontSize: '字体大小', fontSizeDescription: '编辑器字体大小', fontSettings: '字体设置', @@ -189,15 +130,7 @@ export default { enableTabIndent: '启用 Tab 缩进', language: '界面语言', systemTheme: '系统主题', - theme: '编辑器主题', - themeDescription: '选择编辑器主题', - restartRequired: '(需要重启)', saveOptions: '保存选项', - autoSaveDelay: '自动保存延迟(毫秒)', - selectDirectoryFailed: '选择目录失败', - validation: { - customPathRequired: '启用自定义路径时必须选择一个有效的目录', - customPathAutoDisabled: '由于未选择有效目录,自定义数据路径已自动关闭' - } + autoSaveDelay: '自动保存延迟(毫秒)' } }; \ No newline at end of file diff --git a/frontend/src/stores/configStore.ts b/frontend/src/stores/configStore.ts index 16627a0..7442df7 100644 --- a/frontend/src/stores/configStore.ts +++ b/frontend/src/stores/configStore.ts @@ -1,6 +1,6 @@ import {defineStore} from 'pinia'; import {computed, reactive} from 'vue'; -import {ConfigService, StartupService} from '../../bindings/voidraft/internal/services'; +import {ConfigService, StartupService} from '@/../bindings/voidraft/internal/services'; import { AppConfig, AppearanceConfig, @@ -11,7 +11,6 @@ import { TabType, } from '@/../bindings/voidraft/internal/models/models'; import {useI18n} from 'vue-i18n'; -import {useErrorHandler} from '@/utils/errorHandler'; import {ConfigUtils} from '@/utils/configUtils'; import {WindowController} from '@/utils/windowController'; import * as runtime from '@wailsio/runtime'; @@ -144,11 +143,12 @@ const DEFAULT_CONFIG: AppConfig = { systemTheme: SystemThemeType.SystemThemeAuto }, updates: { - Version: "1.0.0", + version: "1.0.0", autoUpdate: true, betaChannel: false }, metadata: { + version: '1.0.0', lastUpdated: new Date().toString() } }; @@ -156,7 +156,6 @@ const DEFAULT_CONFIG: AppConfig = { export const useConfigStore = defineStore('config', () => { const {locale} = useI18n(); - const {safeCall} = useErrorHandler(); // 响应式状态 const state = reactive({ @@ -250,26 +249,26 @@ export const useConfigStore = defineStore('config', () => { const clamp = (value: number) => ConfigUtils.clamp(value, limit.min, limit.max); return { - increase: () => safeCall(() => updateEditingConfig(key, clamp(state.config.editing[key] + 1)), 'config.saveFailed', 'config.saveSuccess'), - decrease: () => safeCall(() => updateEditingConfig(key, clamp(state.config.editing[key] - 1)), 'config.saveFailed', 'config.saveSuccess'), - set: (value: number) => safeCall(() => updateEditingConfig(key, clamp(value)), 'config.saveFailed', 'config.saveSuccess'), - reset: () => safeCall(() => updateEditingConfig(key, limit.default), 'config.saveFailed', 'config.saveSuccess') + increase: async () => await updateEditingConfig(key, clamp(state.config.editing[key] + 1)), + decrease: async () => await updateEditingConfig(key, clamp(state.config.editing[key] - 1)), + set: async (value: number) => await updateEditingConfig(key, clamp(value)), + reset: async () => await updateEditingConfig(key, limit.default) }; }; // 通用布尔值切换器 const createGeneralToggler = (key: T) => - () => safeCall(() => updateGeneralConfig(key, !state.config.general[key] as GeneralConfig[T]), 'config.saveFailed', 'config.saveSuccess'); + async () => await updateGeneralConfig(key, !state.config.general[key] as GeneralConfig[T]); const createEditingToggler = (key: T) => - () => safeCall(() => updateEditingConfig(key, !state.config.editing[key] as EditingConfig[T]), 'config.saveFailed', 'config.saveSuccess'); + async () => await updateEditingConfig(key, !state.config.editing[key] as EditingConfig[T]); // 枚举值切换器 const createEnumToggler = (key: 'tabType', values: readonly T[]) => - () => { + async () => { const currentIndex = values.indexOf(state.config.editing[key] as T); const nextIndex = (currentIndex + 1) % values.length; - return safeCall(() => updateEditingConfig(key, values[nextIndex]), 'config.saveFailed', 'config.saveSuccess'); + return await updateEditingConfig(key, values[nextIndex]); }; // 重置配置 @@ -278,16 +277,12 @@ export const useConfigStore = defineStore('config', () => { state.isLoading = true; try { - // 调用后端重置配置 - await safeCall(() => ConfigService.ResetConfig(), 'config.resetFailed', 'config.resetSuccess'); - // 立即重新加载后端配置以确保前端状态同步 - await safeCall(async () => { - const appConfig = await ConfigService.GetConfig(); - if (appConfig) { - state.config = JSON.parse(JSON.stringify(appConfig)) as AppConfig; - } - }, 'config.loadFailed', 'config.loadSuccess'); + await ConfigService.ResetConfig() + const appConfig = await ConfigService.GetConfig(); + if (appConfig) { + state.config = JSON.parse(JSON.stringify(appConfig)) as AppConfig; + } } finally { state.isLoading = false; } @@ -295,20 +290,16 @@ export const useConfigStore = defineStore('config', () => { // 语言设置方法 const setLanguage = async (language: LanguageType): Promise => { - await safeCall(async () => { - await updateAppearanceConfig('language', language); + await updateAppearanceConfig('language', language); - // 同步更新前端语言 - const frontendLocale = ConfigUtils.backendLanguageToFrontend(language); - locale.value = frontendLocale as any; - }, 'config.languageChangeFailed', 'config.languageChanged'); + // 同步更新前端语言 + const frontendLocale = ConfigUtils.backendLanguageToFrontend(language); + locale.value = frontendLocale as any; }; // 系统主题设置方法 const setSystemTheme = async (systemTheme: SystemThemeType): Promise => { - await safeCall(async () => { - await updateAppearanceConfig('systemTheme', systemTheme); - }, 'config.systemThemeChangeFailed', 'config.systemThemeChanged'); + await updateAppearanceConfig('systemTheme', systemTheme); }; // 初始化语言设置 @@ -339,21 +330,19 @@ export const useConfigStore = defineStore('config', () => { const togglers = { tabIndent: createEditingToggler('enableTabIndent'), alwaysOnTop: async () => { - await safeCall(async () => { - await updateGeneralConfig('alwaysOnTop', !state.config.general.alwaysOnTop); - // 立即应用窗口置顶状态 - await runtime.Window.SetAlwaysOnTop(state.config.general.alwaysOnTop); - }, 'config.alwaysOnTopFailed', 'config.alwaysOnTopSuccess'); + await updateGeneralConfig('alwaysOnTop', !state.config.general.alwaysOnTop); + // 立即应用窗口置顶状态 + await runtime.Window.SetAlwaysOnTop(state.config.general.alwaysOnTop); }, tabType: createEnumToggler('tabType', CONFIG_LIMITS.tabType.values) }; // 字符串配置设置器 const setters = { - fontFamily: (value: string) => safeCall(() => updateEditingConfig('fontFamily', value), 'config.saveFailed', 'config.saveSuccess'), - fontWeight: (value: string) => safeCall(() => updateEditingConfig('fontWeight', value), 'config.saveFailed', 'config.saveSuccess'), - dataPath: (value: string) => safeCall(() => updateGeneralConfig('dataPath', value), 'config.saveFailed', 'config.saveSuccess'), - autoSaveDelay: (value: number) => safeCall(() => updateEditingConfig('autoSaveDelay', value), 'config.saveFailed', 'config.saveSuccess') + fontFamily: async (value: string) => await updateEditingConfig('fontFamily', value), + fontWeight: async (value: string) => await updateEditingConfig('fontWeight', value), + dataPath: async (value: string) => await updateGeneralConfig('dataPath', value), + autoSaveDelay: async (value: number) => await updateEditingConfig('autoSaveDelay', value) }; return { @@ -366,7 +355,7 @@ export const useConfigStore = defineStore('config', () => { ...limits, // 核心方法 - initConfig: () => safeCall(() => initConfig(), 'config.loadFailed', 'config.loadSuccess'), + initConfig, resetConfig, // 语言相关方法 @@ -385,7 +374,7 @@ export const useConfigStore = defineStore('config', () => { // Tab操作 toggleTabIndent: togglers.tabIndent, - setEnableTabIndent: (value: boolean) => safeCall(() => updateEditingConfig('enableTabIndent', value), 'config.saveFailed', 'config.saveSuccess'), + setEnableTabIndent: (value: boolean) => updateEditingConfig('enableTabIndent', value), ...adjusters.tabSize, increaseTabSize: adjusters.tabSize.increase, decreaseTabSize: adjusters.tabSize.decrease, @@ -397,7 +386,7 @@ export const useConfigStore = defineStore('config', () => { // 窗口操作 toggleAlwaysOnTop: togglers.alwaysOnTop, - setAlwaysOnTop: (value: boolean) => safeCall(() => updateGeneralConfig('alwaysOnTop', value), 'config.saveFailed', 'config.saveSuccess'), + setAlwaysOnTop: (value: boolean) => updateGeneralConfig('alwaysOnTop', value), // 字体操作 setFontFamily: setters.fontFamily, @@ -410,20 +399,18 @@ export const useConfigStore = defineStore('config', () => { setAutoSaveDelay: setters.autoSaveDelay, // 热键配置相关方法 - setEnableGlobalHotkey: (value: boolean) => safeCall(() => updateGeneralConfig('enableGlobalHotkey', value), 'config.saveFailed', 'config.saveSuccess'), - setGlobalHotkey: (hotkey: any) => safeCall(() => updateGeneralConfig('globalHotkey', hotkey), 'config.saveFailed', 'config.saveSuccess'), + setEnableGlobalHotkey: (value: boolean) => updateGeneralConfig('enableGlobalHotkey', value), + setGlobalHotkey: (hotkey: any) => updateGeneralConfig('globalHotkey', hotkey), // 系统托盘配置相关方法 - setEnableSystemTray: (value: boolean) => safeCall(() => updateGeneralConfig('enableSystemTray', value), 'config.saveFailed', 'config.saveSuccess'), + setEnableSystemTray: (value: boolean) => updateGeneralConfig('enableSystemTray', value), // 开机启动配置相关方法 setStartAtLogin: async (value: boolean) => { - await safeCall(async () => { - // 先更新配置文件 - await updateGeneralConfig('startAtLogin', value); - // 再调用系统设置API - await StartupService.SetEnabled(value); - }, 'config.startupFailed', 'config.startupSuccess'); + // 先更新配置文件 + await updateGeneralConfig('startAtLogin', value); + // 再调用系统设置API + await StartupService.SetEnabled(value); } }; }); \ No newline at end of file diff --git a/frontend/src/stores/documentStore.ts b/frontend/src/stores/documentStore.ts index 85abef8..84458e9 100644 --- a/frontend/src/stores/documentStore.ts +++ b/frontend/src/stores/documentStore.ts @@ -2,11 +2,8 @@ import {defineStore} from 'pinia'; import {computed, ref} from 'vue'; import {DocumentService} from '@/../bindings/voidraft/internal/services'; import {Document} from '@/../bindings/voidraft/internal/models/models'; -import {useErrorHandler} from '@/utils/errorHandler'; export const useDocumentStore = defineStore('document', () => { - const {safeCall} = useErrorHandler(); - // 状态 const activeDocument = ref(null); const isLoading = ref(false); @@ -23,15 +20,13 @@ export const useDocumentStore = defineStore('document', () => { // 状态管理包装器 const withStateGuard = async ( operation: () => Promise, - stateRef: typeof isLoading | typeof isSaving, - errorMessageKey: string, - successMessageKey?: string + stateRef: typeof isLoading | typeof isSaving ): Promise => { if (stateRef.value) return null; stateRef.value = true; try { - return await safeCall(operation, errorMessageKey, successMessageKey); + return await operation(); } finally { stateRef.value = false; } @@ -44,9 +39,7 @@ export const useDocumentStore = defineStore('document', () => { activeDocument.value = doc; return doc; }, - isLoading, - 'document.loadFailed', - 'document.loadSuccess' + isLoading ); // 保存文档 @@ -64,9 +57,7 @@ export const useDocumentStore = defineStore('document', () => { return true; }, - isSaving, - 'document.saveFailed', - 'document.saveSuccess' + isSaving ); return result ?? false; @@ -88,9 +79,7 @@ export const useDocumentStore = defineStore('document', () => { return true; }, - isSaving, - 'document.saveFailed', - 'document.manualSaveSuccess' + isSaving ); return result ?? false; diff --git a/frontend/src/stores/editorStore.ts b/frontend/src/stores/editorStore.ts index d4dc165..86a11a4 100644 --- a/frontend/src/stores/editorStore.ts +++ b/frontend/src/stores/editorStore.ts @@ -4,34 +4,29 @@ import {EditorView} from '@codemirror/view'; import {EditorState, Extension} from '@codemirror/state'; import {useConfigStore} from './configStore'; import {useDocumentStore} from './documentStore'; -import {useLogStore} from './logStore'; +import {useThemeStore} from './themeStore'; +import {useI18n} from 'vue-i18n'; +import {SystemThemeType} from '@/../bindings/voidraft/internal/models/models'; +import {DocumentService} from '@/../bindings/voidraft/internal/services'; +import {ensureSyntaxTree} from "@codemirror/language" import {createBasicSetup} from '@/views/editor/extensions/basicSetup'; -import { - createStatsUpdateExtension, - getTabExtensions, - updateTabConfig, - createAutoSavePlugin, - createSaveShortcutPlugin, - createFontExtensionFromBackend, - updateFontConfig, - createDynamicKeymapExtension, -} from '@/views/editor/extensions'; -import { createThemeExtension, updateEditorTheme } from '@/views/editor/extensions/themeExtension'; -import { useThemeStore } from './themeStore'; -import { useI18n } from 'vue-i18n'; -import { SystemThemeType } from '@/../bindings/voidraft/internal/models/models'; -import { DocumentService } from '@/../bindings/voidraft/internal/services'; -import {ensureSyntaxTree } from "@codemirror/language" +import {createThemeExtension, updateEditorTheme} from '@/views/editor/extensions/themeExtension'; +import {getTabExtensions, updateTabConfig} from '@/views/editor/extensions/tabExtension'; +import {createFontExtensionFromBackend, updateFontConfig} from '@/views/editor/extensions/fontExtension'; +import {createStatsUpdateExtension} from '@/views/editor/extensions/statsExtension'; +import {createAutoSavePlugin, createSaveShortcutPlugin} from '@/views/editor/extensions/autoSaveExtension'; +import {createDynamicKeymapExtension} from '@/views/editor/extensions/keymap'; + export interface DocumentStats { lines: number; characters: number; selectedCharacters: number; } + export const useEditorStore = defineStore('editor', () => { // 引用配置store const configStore = useConfigStore(); const documentStore = useDocumentStore(); - const logStore = useLogStore(); const themeStore = useThemeStore(); const { t } = useI18n(); @@ -100,22 +95,6 @@ export const useEditorStore = defineStore('editor', () => { } }; - // 手动保存文档 - const handleManualSave = async () => { - if (!editorView.value) return; - - const view = editorView.value as EditorView; - const content = view.state.doc.toString(); - - // 先更新内容 - await DocumentService.UpdateActiveDocumentContent(content); - // 然后调用强制保存方法 - const success = await documentStore.forceSaveDocument(); - if (success) { - logStore.info(t('document.manualSaveSuccess')); - } - }; - // 创建编辑器 const createEditor = async (initialDoc: string = '') => { if (isEditorInitialized.value || !editorContainer.value) return; @@ -231,6 +210,18 @@ export const useEditorStore = defineStore('editor', () => { }); }; + // 手动保存文档 + const handleManualSave = async () => { + if (!editorView.value) return; + + const view = editorView.value as EditorView; + const content = view.state.doc.toString(); + + // 先更新内容 + await DocumentService.UpdateActiveDocumentContent(content); + // 然后调用强制保存方法 + await documentStore.forceSaveDocument(); + }; // 销毁编辑器 const destroyEditor = () => { @@ -241,51 +232,50 @@ export const useEditorStore = defineStore('editor', () => { } }; + // 监听Tab设置变化 + watch([ + () => configStore.config.editing.tabSize, + () => configStore.config.editing.enableTabIndent, + () => configStore.config.editing.tabType, + ], () => { + reconfigureTabSettings(); + }); - // 监听Tab设置变化 - watch([ - () => configStore.config.editing.tabSize, - () => configStore.config.editing.enableTabIndent, - () => configStore.config.editing.tabType, - ], () => { - reconfigureTabSettings(); - }); + // 监听字体大小变化 + watch([ + () => configStore.config.editing.fontFamily, + () => configStore.config.editing.fontSize, + () => configStore.config.editing.lineHeight, + () => configStore.config.editing.fontWeight, + ], () => { + reconfigureFontSettings(); + applyFontSize(); + }); - // 监听字体大小变化 - watch([ - () => configStore.config.editing.fontFamily, - () => configStore.config.editing.fontSize, - () => configStore.config.editing.lineHeight, - () => configStore.config.editing.fontWeight, - ], () => { - reconfigureFontSettings(); - applyFontSize(); - }); + // 监听主题变化 + watch(() => themeStore.currentTheme, (newTheme) => { + if (editorView.value && newTheme) { + updateEditorTheme(editorView.value as EditorView, newTheme); + } + }); - // 监听主题变化 - watch(() => themeStore.currentTheme, (newTheme) => { - if (editorView.value && newTheme) { - updateEditorTheme(editorView.value as EditorView, newTheme); - } - }); + return { + // 状态 + documentStats, + editorView, + isEditorInitialized, + editorContainer, - return { - // 状态 - documentStats, - editorView, - isEditorInitialized, - editorContainer, - - // 方法 - setEditorView, - setEditorContainer, - updateDocumentStats, - applyFontSize, - createEditor, - reconfigureTabSettings, - reconfigureFontSettings, - handleManualSave, - destroyEditor, - scrollEditorToBottom, - }; + // 方法 + setEditorView, + setEditorContainer, + updateDocumentStats, + applyFontSize, + createEditor, + reconfigureTabSettings, + reconfigureFontSettings, + handleManualSave, + destroyEditor, + scrollEditorToBottom, + }; }); \ No newline at end of file diff --git a/frontend/src/stores/logStore.ts b/frontend/src/stores/logStore.ts deleted file mode 100644 index 76dce45..0000000 --- a/frontend/src/stores/logStore.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { defineStore } from 'pinia'; -import { ref } from 'vue'; - -// 日志级别定义 -export enum LogLevel { - INFO = 'info', - WARNING = 'warning', - ERROR = 'error' -} - -// 日志项结构 -export interface LogItem { - id: number; - level: LogLevel; - message: string; - timestamp: Date; - shown: boolean; // 是否已显示过 -} - -export const useLogStore = defineStore('log', () => { - // 日志列表 - const logs = ref([]); - - // 显示队列 - 存储待显示的日志 - const displayQueue = ref([]); - - // 当前显示的日志 - const currentLog = ref(null); - - // 最近一条日志,用于在工具栏显示 - const latestLog = ref(null); - - // 是否显示日志 - const showLog = ref(false); - - // 自动隐藏计时器 - let hideTimer: number | null = null; - - // 根据日志级别获取显示时间 - function getDisplayTimeByLevel(level: LogLevel): number { - switch(level) { - case LogLevel.ERROR: - return 8000; // 错误显示更长时间 - case LogLevel.WARNING: - return 6000; // 警告显示中等时间 - case LogLevel.INFO: - default: - return 4000; // 信息显示较短时间 - } - } - - // 显示下一条日志 - function showNextLog() { - if (hideTimer) { - window.clearTimeout(hideTimer); - hideTimer = null; - } - - // 如果队列为空,则不显示 - if (displayQueue.value.length === 0) { - showLog.value = false; - currentLog.value = null; - return; - } - - // 取出队列中第一条日志显示 - const nextLog = displayQueue.value.shift()!; - currentLog.value = nextLog; - showLog.value = true; - - // 设置自动隐藏和切换到下一条 - const displayTime = getDisplayTimeByLevel(nextLog.level); - hideTimer = window.setTimeout(() => { - showNextLog(); - }, displayTime); - } - - // 添加日志 - function addLog(level: LogLevel, message: string, autoHideDelay = 0) { - const id = Date.now(); - const logItem: LogItem = { - id, - level, - message, - timestamp: new Date(), - shown: false - }; - - // 添加到日志列表 - logs.value.push(logItem); - - // 保持日志列表在合理大小 - if (logs.value.length > 100) { - logs.value = logs.value.slice(-100); - } - - // 设置最新日志 - latestLog.value = logItem; - - // 添加到显示队列 - displayQueue.value.push(logItem); - - // 如果当前没有显示日志,则开始显示 - if (!currentLog.value && !hideTimer) { - showNextLog(); - } - - return id; - } - - // 添加不同级别的日志的便捷方法 - function info(message: string) { - return addLog(LogLevel.INFO, message); - } - - function warning(message: string) { - return addLog(LogLevel.WARNING, message); - } - - function error(message: string) { - return addLog(LogLevel.ERROR, message); - } - - // 清除日志 - function clearLogs() { - logs.value = []; - displayQueue.value = []; - latestLog.value = null; - currentLog.value = null; - showLog.value = false; - - if (hideTimer) { - window.clearTimeout(hideTimer); - hideTimer = null; - } - } - - // 手动隐藏当前日志 - function hideCurrentLog() { - if (hideTimer) { - window.clearTimeout(hideTimer); - hideTimer = null; - } - showLog.value = false; - currentLog.value = null; - displayQueue.value = []; // 清空队列 - } - - return { - // 状态 - logs, - latestLog, - currentLog, - showLog, - displayQueue, - - // 方法 - addLog, - info, - warning, - error, - clearLogs, - hideCurrentLog, - showNextLog - }; -}); \ No newline at end of file diff --git a/frontend/src/utils/errorHandler.ts b/frontend/src/utils/errorHandler.ts deleted file mode 100644 index c5e4660..0000000 --- a/frontend/src/utils/errorHandler.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { useLogStore } from '@/stores/logStore'; -import { useI18n } from 'vue-i18n'; - -/** - * 创建组合式函数,用于在组件中使用错误处理 - */ -export function useErrorHandler() { - const logStore = useLogStore(); - const { t } = useI18n(); - - const handleError = (error: unknown, messageKey: string) => { - logStore.error(t(messageKey)); - }; - - const safeCall = async ( - operation: () => Promise, - errorMessageKey: string, - successMessageKey?: string - ): Promise => { - try { - const result = await operation(); - if (successMessageKey) { - logStore.info(t(successMessageKey)); - } - return result; - } catch (error) { - logStore.error(t(errorMessageKey)); - return null; - } - }; - - /** - * 静默处理错误,不显示用户提示 - */ - const silentCall = async ( - operation: () => Promise - ): Promise => { - try { - return await operation(); - } catch (error) { - // 静默忽略错误 - return null; - } - }; - - /** - * 创建带错误处理的数值调整器 - */ - const createSafeAdjuster = ( - adjustFn: () => Promise, - errorMessageKey: string - ) => () => safeCall(adjustFn, errorMessageKey); - - return { - handleError, - safeCall, - silentCall, - createSafeAdjuster - }; -} - -/** - * 错误处理工具函数集合(不依赖Vue上下文) - */ -export const ErrorUtils = { - /** - * 静默处理错误 - */ - silent: async (operation: () => Promise): Promise => { - try { - return await operation(); - } catch (error) { - return null; - } - }, - - /** - * 带重试的错误处理 - */ - withRetry: async ( - operation: () => Promise, - maxRetries: number = 3, - delay: number = 1000 - ): Promise => { - for (let i = 0; i < maxRetries; i++) { - try { - return await operation(); - } catch (error) { - if (i === maxRetries - 1) { - return null; - } - await new Promise(resolve => setTimeout(resolve, delay)); - } - } - return null; - } -}; \ No newline at end of file diff --git a/frontend/src/views/settings/pages/AppearancePage.vue b/frontend/src/views/settings/pages/AppearancePage.vue index de3f5d0..7b0c690 100644 --- a/frontend/src/views/settings/pages/AppearancePage.vue +++ b/frontend/src/views/settings/pages/AppearancePage.vue @@ -1,7 +1,6 @@ diff --git a/frontend/src/views/settings/pages/EditingPage.vue b/frontend/src/views/settings/pages/EditingPage.vue index 34814b0..ba84021 100644 --- a/frontend/src/views/settings/pages/EditingPage.vue +++ b/frontend/src/views/settings/pages/EditingPage.vue @@ -1,7 +1,6 @@