diff --git a/frontend/electron/main.js b/frontend/electron/main.js index 75fa1647e3e28b928925acae4a888db6f0324c10..46a81fabcaaf4c9fee619182ee2801379b446bf5 100644 --- a/frontend/electron/main.js +++ b/frontend/electron/main.js @@ -10,18 +10,22 @@ * Create: 2025-07-30 * =================================================================================================================== */ -const { app, BrowserWindow, shell } = require('electron') +const { app, BrowserWindow, shell, ipcMain } = require('electron') const path = require('path') const { registerIpcListeners } = require('./ipc.js') app.disableHardwareAcceleration() +let mainWindow = null + function createWindow() { const win = new BrowserWindow({ width: 1200, height: 800, backgroundColor: '#00000000', icon: path.join(__dirname, '../src/assets/logo.png'), + frame: true, + titleBarStyle: 'hidden', webPreferences: { nodeIntegration: false, contextIsolation: true, @@ -33,6 +37,8 @@ function createWindow() { } }) + mainWindow = win + registerIpcListeners(); if (process.env.NODE_ENV === 'development') { @@ -76,6 +82,29 @@ function createWindow() { } } +// 窗口控制 IPC 处理 +ipcMain.on('minimize-window', () => { + if (mainWindow) { + mainWindow.minimize() + } +}) + +ipcMain.on('toggle-maximize', () => { + if (mainWindow) { + if (mainWindow.isMaximized()) { + mainWindow.unmaximize() + } else { + mainWindow.maximize() + } + } +}) + +ipcMain.on('close-window', () => { + if (mainWindow) { + mainWindow.close() + } +}) + app.whenReady().then(createWindow) app.on('window-all-closed', () => { diff --git a/frontend/electron/preload.js b/frontend/electron/preload.js index 669a4f0ec6b0dd2e3770fe3922c8e91939933c2e..6e7a9feb8a58c92fd99b0d7925a725a4fa90e06e 100644 --- a/frontend/electron/preload.js +++ b/frontend/electron/preload.js @@ -15,5 +15,8 @@ const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld('electronAPI', { invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args), closeApp: () => ipcRenderer.send('close-app'), - getUsername: () => ipcRenderer.invoke('get-username') + getUsername: () => ipcRenderer.invoke('get-username'), + minimizeWindow: () => ipcRenderer.send('minimize-window'), + toggleMaximize: () => ipcRenderer.send('toggle-maximize'), + closeWindow: () => ipcRenderer.send('close-window') }) diff --git a/frontend/src/layout/index.vue b/frontend/src/layout/index.vue index c13c3a0a142f20707775d8a3e9a818c7b8482747..da6c5551e0d4d7445b2144b9ebdf4afe2d8a207c 100644 --- a/frontend/src/layout/index.vue +++ b/frontend/src/layout/index.vue @@ -12,13 +12,50 @@ diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 7337c6aa0cf8ec069c782d32d17d7ec9669a0647..308a9b38d9813fc486b266ae154a619ba0ae5d30 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -12,7 +12,7 @@ - + @@ -72,7 +72,7 @@ diff --git a/frontend/src/views/components/GridDisplay.vue b/frontend/src/views/components/GridDisplay.vue index e3f8f212213b24be2f1b2e36cee56750255a44fb..ce6c0f5a00ef8352de10d0fc06384ee70bd2b1db 100644 --- a/frontend/src/views/components/GridDisplay.vue +++ b/frontend/src/views/components/GridDisplay.vue @@ -70,10 +70,11 @@ import { useRouter } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { Tag } from '@/api/index.ts'; import { generateIconBgColor } from '@/utils/index.ts'; +import { useTabStore } from '@/stores/tabStore'; -// 待完善注释 const router = useRouter(); const {t} = useI18n(); +const { addTab } = useTabStore(); const props = withDefaults( defineProps<{ @@ -86,9 +87,20 @@ const props = withDefaults( } ); -// 跳转至详情页 tag, key -const goToDetail = (key) => { - router.push(`/${props.tag}/${key}`); +// 跳转至详情页 tag, key - 新增页签 +const goToDetail = (key: string) => { + const item = props.itemList.find((i: any) => i.key === key); + const detailPath = `/${props.tag}/${key}`; + + // 添加新页签 + addTab({ + id: `${props.tag}-${key}`, + title: item?.name || key, + route: { path: detailPath } + }); + + // 跳转到详情页 + router.push(detailPath); };