const { app, BrowserWindow, Menu, shell, dialog, ipcMain } = require('electron') const path = require('path') const fs = require('fs') const DEV_URL = process.env.VITE_DEV_SERVER_URL || '' function createWindow() { const win = new BrowserWindow({ width: 1240, height: 820, minWidth: 940, minHeight: 620, title: '实习工作日志', icon: path.join(__dirname, '..', 'build', 'icon.png'), autoHideMenuBar: true, backgroundColor: '#FFFFFF', webPreferences: { contextIsolation: true, nodeIntegration: false, preload: path.join(__dirname, 'preload.cjs'), spellcheck: false } }) Menu.setApplicationMenu(null) // 下载接管:导出的 JSON/CSV/Markdown 弹出标准保存对话框 win.webContents.session.on('will-download', (event, item, webContents) => { const result = dialog.showSaveDialogSync(win, { title: '保存文件', defaultPath: path.join(app.getPath('downloads'), item.getFilename()) }) if (!result) { event.preventDefault() return } item.setSavePath(result) }) win.webContents.setWindowOpenHandler(({ url }) => { if (/^https?:/i.test(url)) shell.openExternal(url) return { action: 'deny' } }) if (DEV_URL) { win.loadURL(DEV_URL) } else { win.loadFile(path.join(__dirname, '..', 'dist', 'index.html')) } } // 导出文件:渲染进程请求主进程保存(标准另存为对话框 + 直接写盘) ipcMain.handle('export-file', async (event, payload) => { const win = BrowserWindow.fromWebContents(event.sender) const result = await dialog.showSaveDialog(win, { title: '保存文件', defaultPath: path.join(app.getPath('downloads'), payload.filename) }) if (result.canceled || !result.filePath) return { saved: false, path: '' } fs.writeFileSync(result.filePath, payload.content, 'utf-8') return { saved: true, path: result.filePath } }) app.whenReady().then(() => { createWindow() app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit() })