From d5da651aef3e02055ee73d4926fc538bc8f3a8cb Mon Sep 17 00:00:00 2001 From: Flinlin <3400968477@qq.com> Date: Mon, 11 May 2026 00:27:10 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=E5=88=A0=E9=99=A4=E5=A4=B1=E6=95=88?= =?UTF-8?q?=E7=9A=84=E6=9C=AC=E5=9C=B0=E5=90=AF=E5=8A=A8=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal-plugins/setting/src/env.d.ts | 1 + .../LocalLaunchSetting/LocalLaunchSetting.vue | 21 ++++++++++++ resources/preload.js | 2 ++ src/main/api/renderer/localShortcuts.ts | 32 ++++++++++++++++++- src/preload/index.ts | 1 + src/renderer/src/env.d.ts | 1 + 6 files changed, 57 insertions(+), 1 deletion(-) diff --git a/internal-plugins/setting/src/env.d.ts b/internal-plugins/setting/src/env.d.ts index 3f2dcccd..b0cceaaf 100644 --- a/internal-plugins/setting/src/env.d.ts +++ b/internal-plugins/setting/src/env.d.ts @@ -301,6 +301,7 @@ declare global { add: (type: 'file' | 'folder') => Promise<{ success: boolean; error?: string }> addByPath: (filePath: string) => Promise<{ success: boolean; error?: string }> delete: (id: string) => Promise<{ success: boolean; error?: string }> + deleteWhenNotExist: () => Promise<{ success: boolean; error?: string }> open: (path: string) => Promise<{ success: boolean; error?: string }> updateAlias: (id: string, alias: string) => Promise<{ success: boolean; error?: string }> } diff --git a/internal-plugins/setting/src/views/LocalLaunchSetting/LocalLaunchSetting.vue b/internal-plugins/setting/src/views/LocalLaunchSetting/LocalLaunchSetting.vue index f003693f..efebfd1a 100644 --- a/internal-plugins/setting/src/views/LocalLaunchSetting/LocalLaunchSetting.vue +++ b/internal-plugins/setting/src/views/LocalLaunchSetting/LocalLaunchSetting.vue @@ -257,6 +257,24 @@ async function handleDelete(shortcut: LocalShortcut): Promise { } } +async function handleInvalidItemDelete(): Promise { + if (isDeleting.value) return + isDeleting.value = true + try { + const result = await window.ztools.internal.localShortcuts.deleteWhenNotExist() + if (result.success) { + success('删除成功') + } else { + error(result.error || '删除失败') + } + } catch (err) { + console.error('删除失败:', err) + error('删除失败') + } + await loadShortcuts() + isDeleting.value = false +} + // 获取类型标签 function getTypeLabel(type: string): string { switch (type) { @@ -322,6 +340,9 @@ onMounted(() => { + diff --git a/resources/preload.js b/resources/preload.js index 443c26b7..82bf7338 100644 --- a/resources/preload.js +++ b/resources/preload.js @@ -1,4 +1,5 @@ const electron = require('electron') +const { ipcRenderer } = require('electron') // ── plugin.api 统一 IPC 公共方法(与 utools 写法一致)── @@ -818,6 +819,7 @@ window.ztools = { addByPath: async (filePath) => await electron.ipcRenderer.invoke('local-shortcuts:add-by-path', filePath), delete: async (id) => await electron.ipcRenderer.invoke('local-shortcuts:delete', id), + deleteWhenNotExist: () => ipcRenderer.invoke('local-shortcuts:delete-when-not-exist'), open: async (path) => await electron.ipcRenderer.invoke('local-shortcuts:open', path), updateAlias: async (id, alias) => await electron.ipcRenderer.invoke('local-shortcuts:update-alias', id, alias) diff --git a/src/main/api/renderer/localShortcuts.ts b/src/main/api/renderer/localShortcuts.ts index 910a165d..7764f707 100644 --- a/src/main/api/renderer/localShortcuts.ts +++ b/src/main/api/renderer/localShortcuts.ts @@ -1,5 +1,5 @@ import { app, ipcMain, shell } from 'electron' -import { promises as fs } from 'fs' +import { promises as fs, existsSync } from 'fs' import path from 'path' import { pinyin as getPinyin } from 'pinyin-pro' import databaseAPI from '../shared/database' @@ -43,6 +43,9 @@ export class LocalShortcutsAPI { this.addShortcutByPath(filePath) ) ipcMain.handle('local-shortcuts:delete', (_event, id: string) => this.deleteShortcut(id)) + ipcMain.handle('local-shortcuts:delete-when-not-exist', (_event) => + this.deleteNotExistShortcut() + ) ipcMain.handle('local-shortcuts:open', (_event, shortcutPath: string) => this.openShortcut(shortcutPath) ) @@ -390,6 +393,33 @@ export class LocalShortcutsAPI { return { success: false, error: error instanceof Error ? error.message : '未知错误' } } } + + private async deleteNotExistShortcut(): Promise<{ success: boolean; error?: string }> { + try { + const shortcuts = this.getAllShortcuts() + const { existShortcuts, notExistShortcuts } = shortcuts.reduce( + (acc, cur) => { + existsSync(cur.path) ? acc.existShortcuts.push(cur) : acc.notExistShortcuts.push(cur.id) + return acc + }, + { + existShortcuts: [] as LocalShortcut[], + notExistShortcuts: [] as string[] + } + ) + databaseAPI.dbPut(LOCAL_SHORTCUTS_KEY, existShortcuts) + + console.log('[LocalShortcut] 删除失效本地启动项成功:', notExistShortcuts.toString()) + + // 通知渲染进程刷新本地启动项 + this.mainWindow?.webContents.send('local-shortcuts-changed') + + return { success: true } + } catch (error) { + console.error('[LocalShortcut] 删除失效本地启动项失败:', error) + return { success: false, error: error instanceof Error ? error.message : '未知错误' } + } + } } export default new LocalShortcutsAPI() diff --git a/src/preload/index.ts b/src/preload/index.ts index a9c51ab0..868a418d 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -332,6 +332,7 @@ const api = { getAll: () => ipcRenderer.invoke('local-shortcuts:get-all'), add: (type: 'file' | 'folder') => ipcRenderer.invoke('local-shortcuts:add', type), delete: (id: string) => ipcRenderer.invoke('local-shortcuts:delete', id), + deleteWhenNotExist: () => ipcRenderer.invoke('local-shortcuts:delete-when-not-exist'), open: (path: string) => ipcRenderer.invoke('local-shortcuts:open', path), updateAlias: (id: string, alias: string) => ipcRenderer.invoke('local-shortcuts:update-alias', id, alias) diff --git a/src/renderer/src/env.d.ts b/src/renderer/src/env.d.ts index a2cc0582..659f7e21 100644 --- a/src/renderer/src/env.d.ts +++ b/src/renderer/src/env.d.ts @@ -346,6 +346,7 @@ declare global { > add: (type: 'file' | 'folder') => Promise<{ success: boolean; error?: string }> delete: (id: string) => Promise<{ success: boolean; error?: string }> + deleteWhenNotExist: () => Promise<{ success: boolean; error?: string }> open: (path: string) => Promise<{ success: boolean; error?: string }> updateAlias: (id: string, alias: string) => Promise<{ success: boolean; error?: string }> } From 65fbc8695bef96448bfdacf90092f874cc0baff3 Mon Sep 17 00:00:00 2001 From: Flinlin <3400968477@qq.com> Date: Mon, 11 May 2026 00:27:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=E5=88=A0=E9=99=A4=E5=A4=B1=E6=95=88?= =?UTF-8?q?=E7=9A=84=E6=9C=AC=E5=9C=B0=E5=90=AF=E5=8A=A8=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal-plugins/setting/src/env.d.ts | 1 + .../LocalLaunchSetting/LocalLaunchSetting.vue | 22 +++++++++++++ resources/preload.js | 2 ++ src/main/api/renderer/localShortcuts.ts | 32 ++++++++++++++++++- src/preload/index.ts | 1 + src/renderer/src/env.d.ts | 1 + 6 files changed, 58 insertions(+), 1 deletion(-) diff --git a/internal-plugins/setting/src/env.d.ts b/internal-plugins/setting/src/env.d.ts index 3f2dcccd..b0cceaaf 100644 --- a/internal-plugins/setting/src/env.d.ts +++ b/internal-plugins/setting/src/env.d.ts @@ -301,6 +301,7 @@ declare global { add: (type: 'file' | 'folder') => Promise<{ success: boolean; error?: string }> addByPath: (filePath: string) => Promise<{ success: boolean; error?: string }> delete: (id: string) => Promise<{ success: boolean; error?: string }> + deleteWhenNotExist: () => Promise<{ success: boolean; error?: string }> open: (path: string) => Promise<{ success: boolean; error?: string }> updateAlias: (id: string, alias: string) => Promise<{ success: boolean; error?: string }> } diff --git a/internal-plugins/setting/src/views/LocalLaunchSetting/LocalLaunchSetting.vue b/internal-plugins/setting/src/views/LocalLaunchSetting/LocalLaunchSetting.vue index f003693f..2fb5791f 100644 --- a/internal-plugins/setting/src/views/LocalLaunchSetting/LocalLaunchSetting.vue +++ b/internal-plugins/setting/src/views/LocalLaunchSetting/LocalLaunchSetting.vue @@ -257,6 +257,25 @@ async function handleDelete(shortcut: LocalShortcut): Promise { } } +//删除失效项目 +async function handleInvalidItemDelete(): Promise { + if (isDeleting.value) return + isDeleting.value = true + try { + const result = await window.ztools.internal.localShortcuts.deleteWhenNotExist() + if (result.success) { + success('删除成功') + } else { + error(result.error || '删除失败') + } + } catch (err) { + console.error('删除失败:', err) + error('删除失败') + } + await loadShortcuts() + isDeleting.value = false +} + // 获取类型标签 function getTypeLabel(type: string): string { switch (type) { @@ -322,6 +341,9 @@ onMounted(() => { + diff --git a/resources/preload.js b/resources/preload.js index 443c26b7..82bf7338 100644 --- a/resources/preload.js +++ b/resources/preload.js @@ -1,4 +1,5 @@ const electron = require('electron') +const { ipcRenderer } = require('electron') // ── plugin.api 统一 IPC 公共方法(与 utools 写法一致)── @@ -818,6 +819,7 @@ window.ztools = { addByPath: async (filePath) => await electron.ipcRenderer.invoke('local-shortcuts:add-by-path', filePath), delete: async (id) => await electron.ipcRenderer.invoke('local-shortcuts:delete', id), + deleteWhenNotExist: () => ipcRenderer.invoke('local-shortcuts:delete-when-not-exist'), open: async (path) => await electron.ipcRenderer.invoke('local-shortcuts:open', path), updateAlias: async (id, alias) => await electron.ipcRenderer.invoke('local-shortcuts:update-alias', id, alias) diff --git a/src/main/api/renderer/localShortcuts.ts b/src/main/api/renderer/localShortcuts.ts index 910a165d..7764f707 100644 --- a/src/main/api/renderer/localShortcuts.ts +++ b/src/main/api/renderer/localShortcuts.ts @@ -1,5 +1,5 @@ import { app, ipcMain, shell } from 'electron' -import { promises as fs } from 'fs' +import { promises as fs, existsSync } from 'fs' import path from 'path' import { pinyin as getPinyin } from 'pinyin-pro' import databaseAPI from '../shared/database' @@ -43,6 +43,9 @@ export class LocalShortcutsAPI { this.addShortcutByPath(filePath) ) ipcMain.handle('local-shortcuts:delete', (_event, id: string) => this.deleteShortcut(id)) + ipcMain.handle('local-shortcuts:delete-when-not-exist', (_event) => + this.deleteNotExistShortcut() + ) ipcMain.handle('local-shortcuts:open', (_event, shortcutPath: string) => this.openShortcut(shortcutPath) ) @@ -390,6 +393,33 @@ export class LocalShortcutsAPI { return { success: false, error: error instanceof Error ? error.message : '未知错误' } } } + + private async deleteNotExistShortcut(): Promise<{ success: boolean; error?: string }> { + try { + const shortcuts = this.getAllShortcuts() + const { existShortcuts, notExistShortcuts } = shortcuts.reduce( + (acc, cur) => { + existsSync(cur.path) ? acc.existShortcuts.push(cur) : acc.notExistShortcuts.push(cur.id) + return acc + }, + { + existShortcuts: [] as LocalShortcut[], + notExistShortcuts: [] as string[] + } + ) + databaseAPI.dbPut(LOCAL_SHORTCUTS_KEY, existShortcuts) + + console.log('[LocalShortcut] 删除失效本地启动项成功:', notExistShortcuts.toString()) + + // 通知渲染进程刷新本地启动项 + this.mainWindow?.webContents.send('local-shortcuts-changed') + + return { success: true } + } catch (error) { + console.error('[LocalShortcut] 删除失效本地启动项失败:', error) + return { success: false, error: error instanceof Error ? error.message : '未知错误' } + } + } } export default new LocalShortcutsAPI() diff --git a/src/preload/index.ts b/src/preload/index.ts index a9c51ab0..868a418d 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -332,6 +332,7 @@ const api = { getAll: () => ipcRenderer.invoke('local-shortcuts:get-all'), add: (type: 'file' | 'folder') => ipcRenderer.invoke('local-shortcuts:add', type), delete: (id: string) => ipcRenderer.invoke('local-shortcuts:delete', id), + deleteWhenNotExist: () => ipcRenderer.invoke('local-shortcuts:delete-when-not-exist'), open: (path: string) => ipcRenderer.invoke('local-shortcuts:open', path), updateAlias: (id: string, alias: string) => ipcRenderer.invoke('local-shortcuts:update-alias', id, alias) diff --git a/src/renderer/src/env.d.ts b/src/renderer/src/env.d.ts index a2cc0582..659f7e21 100644 --- a/src/renderer/src/env.d.ts +++ b/src/renderer/src/env.d.ts @@ -346,6 +346,7 @@ declare global { > add: (type: 'file' | 'folder') => Promise<{ success: boolean; error?: string }> delete: (id: string) => Promise<{ success: boolean; error?: string }> + deleteWhenNotExist: () => Promise<{ success: boolean; error?: string }> open: (path: string) => Promise<{ success: boolean; error?: string }> updateAlias: (id: string, alias: string) => Promise<{ success: boolean; error?: string }> }