From 562e4f5b9e9cc8c011593ff4f9cd4d9e301f866a Mon Sep 17 00:00:00 2001 From: Jasery Date: Tue, 28 Oct 2025 16:34:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E5=AF=B9=E8=AF=9D=E6=A1=86=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=99=A8=EF=BC=8C=E9=87=8D=E6=9E=84=E5=AF=B9=E8=AF=9D=E6=A1=86?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=EF=BC=8C=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/App.vue | 2 + src/renderer/components/ConfirmDialog.vue | 85 +++++++++ src/renderer/components/GlobalDialog.vue | 176 ++++++++++++++++++ src/renderer/components/MessageBoxDialog.vue | 99 ++++++++++ src/renderer/main.ts | 16 ++ src/renderer/screens/CreateTemplateScreen.vue | 25 ++- src/renderer/screens/TemplateListScreen.vue | 35 +++- src/renderer/types/global.d.ts | 19 ++ src/renderer/utils/confirm-dialog-service.ts | 97 ++++++++++ 9 files changed, 543 insertions(+), 11 deletions(-) create mode 100644 src/renderer/components/ConfirmDialog.vue create mode 100644 src/renderer/components/GlobalDialog.vue create mode 100644 src/renderer/components/MessageBoxDialog.vue create mode 100644 src/renderer/types/global.d.ts create mode 100644 src/renderer/utils/confirm-dialog-service.ts diff --git a/src/renderer/App.vue b/src/renderer/App.vue index fe48523..9af8785 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -1,11 +1,13 @@ \ No newline at end of file diff --git a/src/renderer/components/MessageBoxDialog.vue b/src/renderer/components/MessageBoxDialog.vue new file mode 100644 index 0000000..6d0184c --- /dev/null +++ b/src/renderer/components/MessageBoxDialog.vue @@ -0,0 +1,99 @@ + + + \ No newline at end of file diff --git a/src/renderer/main.ts b/src/renderer/main.ts index 7e2952f..5001e0e 100644 --- a/src/renderer/main.ts +++ b/src/renderer/main.ts @@ -10,6 +10,22 @@ import pinia from '@/renderer/plugins/pinia' declare global { interface Window { mainApi?: any + ConfirmDialogManager?: { + showConfirm: (options: { + title: string; + message: string; + confirmText?: string; + cancelText?: string; + confirmColor?: string; + }) => Promise; + showMessage: (options: { + title: string; + message: string; + confirmText?: string; + confirmColor?: string; + dialogColor?: string; + }) => Promise; + }; } } diff --git a/src/renderer/screens/CreateTemplateScreen.vue b/src/renderer/screens/CreateTemplateScreen.vue index 770461a..2f663b0 100644 --- a/src/renderer/screens/CreateTemplateScreen.vue +++ b/src/renderer/screens/CreateTemplateScreen.vue @@ -358,6 +358,7 @@ import { useRoute, useRouter } from 'vue-router' import { useTemplateStore } from '@/renderer/store/template' import { Template } from '@/renderer/store/template' import TemplateTree from '@/renderer/components/TemplateTree.vue' +import { ConfirmDialogService } from '@/renderer/utils/confirm-dialog-service' const router = useRouter() const route = useRoute() @@ -810,9 +811,17 @@ const selectAndAddFile = async () => { currentEditingItem.value = null } -const goBack = () => { +const goBack = async () => { if (hasChanges.value) { - if (confirm('您有未保存的更改,确定要离开吗?')) { + const confirmed = await ConfirmDialogService.confirm({ + title: '确认离开', + message: '您有未保存的更改,确定要离开吗?', + confirmText: '离开', + cancelText: '取消', + confirmColor: 'warning' + }) + + if (confirmed) { router.push('/templates') } } else { @@ -904,8 +913,16 @@ const showEditFileDialog = (file: { path: string; content?: string; sourceFilePa // Variable to track the current item being edited const currentEditingItem = ref<{ path: string; type: 'directory' | 'file'; content?: string; sourceFilePath?: string } | null>(null) -const deleteItem = (item: TreeItem) => { - if (!confirm('确定要删除此项吗?')) return +const deleteItem = async (item: TreeItem) => { + const confirmed = await ConfirmDialogService.confirm({ + title: '删除确认', + message: '确定要删除此项吗?', + confirmText: '删除', + cancelText: '取消', + confirmColor: 'error' + }) + + if (!confirmed) return if (item.type === 'directory') { // Find all directories that start with the item name (including the exact match) diff --git a/src/renderer/screens/TemplateListScreen.vue b/src/renderer/screens/TemplateListScreen.vue index 3eaeb2b..1d66d37 100644 --- a/src/renderer/screens/TemplateListScreen.vue +++ b/src/renderer/screens/TemplateListScreen.vue @@ -141,6 +141,7 @@ import { useRouter } from 'vue-router' import { useTemplateStore } from '@/renderer/store/template' import { Template } from '@/renderer/store/template' import TemplateTree from '@/renderer/components/TemplateTree.vue' +import { ConfirmDialogService } from '@/renderer/utils/confirm-dialog-service' const router = useRouter() const templateStore = useTemplateStore() @@ -216,8 +217,16 @@ const editTemplate = (template: Template) => { router.push(`/create-template/${template.id}`) } -const deleteTemplate = (template: Template) => { - if (confirm(`确定要删除模板 "${template.name}" 吗?此操作不可撤销。`)) { +const deleteTemplate = async (template: Template) => { + const confirmed = await ConfirmDialogService.confirm({ + title: '删除模板', + message: `确定要删除模板 "${template.name}" 吗?此操作不可撤销。`, + confirmText: '删除', + cancelText: '取消', + confirmColor: 'error' + }) + + if (confirmed) { storeDeleteTemplate(template.id) } } @@ -249,16 +258,28 @@ const confirmExecuteTemplate = () => { executePath.value, dirNames ) - .then((result: any) => { + .then(async (result: any) => { if (result.success) { - alert('模板执行成功!') + await ConfirmDialogService.success({ + title: '执行成功', + message: '模板执行成功!', + confirmText: '确定' + }) showExecuteDialog.value = false } else { - alert(`模板执行失败: ${result.error}`) + await ConfirmDialogService.error({ + title: '执行失败', + message: `模板执行失败: ${result.error}`, + confirmText: '确定' + }) } }) - .catch((error: any) => { - alert(`模板执行出错: ${error.message}`) + .catch(async (error: any) => { + await ConfirmDialogService.error({ + title: '执行出错', + message: `模板执行出错: ${error.message}`, + confirmText: '确定' + }) }) } diff --git a/src/renderer/types/global.d.ts b/src/renderer/types/global.d.ts new file mode 100644 index 0000000..a7a2870 --- /dev/null +++ b/src/renderer/types/global.d.ts @@ -0,0 +1,19 @@ +// 确保 TypeScript 能识别我们的全局变量 +interface Window { + ConfirmDialogManager?: { + showConfirm: (options: { + title: string; + message: string; + confirmText?: string; + cancelText?: string; + confirmColor?: string; + }) => Promise; + showMessage: (options: { + title: string; + message: string; + confirmText?: string; + confirmColor?: string; + dialogColor?: string; + }) => Promise; + }; +} \ No newline at end of file diff --git a/src/renderer/utils/confirm-dialog-service.ts b/src/renderer/utils/confirm-dialog-service.ts new file mode 100644 index 0000000..74a4fca --- /dev/null +++ b/src/renderer/utils/confirm-dialog-service.ts @@ -0,0 +1,97 @@ +// 定义对话框选项接口 +interface BaseDialogOptions { + title: string + message: string + confirmText?: string + cancelText?: string + confirmColor?: string +} + +interface ConfirmDialogOptions extends BaseDialogOptions { } + +interface MessageDialogOptions extends BaseDialogOptions { + dialogColor?: string +} + +// 对话框类型 +type DialogType = 'confirm' | 'info' | 'success' | 'warning' | 'error' + +// 全局对话框管理器接口 +interface GlobalDialogManager { + showConfirm: (options: ConfirmDialogOptions) => Promise + showMessage: (options: MessageDialogOptions) => Promise +} + +// 确认对话框服务 +export const ConfirmDialogService = { + // 显示确认对话框 + async confirm(options: ConfirmDialogOptions): Promise { + if (window.ConfirmDialogManager) { + return (window.ConfirmDialogManager as GlobalDialogManager).showConfirm(options) + } else { + console.error('GlobalDialog component not properly initialized') + // 降级到原生 confirm + return confirm(`${options.title}: ${options.message}`) + } + }, + + // 显示信息对话框 + async info(options: MessageDialogOptions): Promise { + if (window.ConfirmDialogManager) { + return (window.ConfirmDialogManager as GlobalDialogManager).showMessage({ + ...options, + dialogColor: options.dialogColor || 'info', + confirmColor: options.confirmColor || 'white' + }) + } else { + console.error('GlobalDialog component not properly initialized') + // 降级到原生 alert + alert(`${options.title}: ${options.message}`) + } + }, + + // 显示成功对话框 + async success(options: MessageDialogOptions): Promise { + if (window.ConfirmDialogManager) { + return (window.ConfirmDialogManager as GlobalDialogManager).showMessage({ + ...options, + dialogColor: options.dialogColor || 'success', + confirmColor: options.confirmColor || 'white' + }) + } else { + console.error('GlobalDialog component not properly initialized') + // 降级到原生 alert + alert(`${options.title}: ${options.message}`) + } + }, + + // 显示警告对话框 + async warning(options: MessageDialogOptions): Promise { + if (window.ConfirmDialogManager) { + return (window.ConfirmDialogManager as GlobalDialogManager).showMessage({ + ...options, + dialogColor: options.dialogColor || 'warning', + confirmColor: options.confirmColor || 'white' + }) + } else { + console.error('GlobalDialog component not properly initialized') + // 降级到原生 alert + alert(`${options.title}: ${options.message}`) + } + }, + + // 显示错误对话框 + async error(options: MessageDialogOptions): Promise { + if (window.ConfirmDialogManager) { + return (window.ConfirmDialogManager as GlobalDialogManager).showMessage({ + ...options, + dialogColor: options.dialogColor || 'error', + confirmColor: options.confirmColor || 'white' + }) + } else { + console.error('GlobalDialog component not properly initialized') + // 降级到原生 alert + alert(`${options.title}: ${options.message}`) + } + } +}