'use strict'; const { Controller } = require('ee-core'); const { shell } = require('electron'); const Addon = require('ee-core/addon'); const { dialog } = require('electron'); const fs = require('fs'); const path = require('path'); const CoreWindow = require('ee-core/electron/window'); const { BrowserWindow, Menu,app } = require('electron'); const { readConfigFile } = require('../utils/config'); const configDeault = readConfigFile(); const errData = { msg :'请求失败,请联系管理员', code:999 } const sharp = require('sharp'); // 确保安装:npm install sharp /** * example * @class */ class UtilsController extends Controller { constructor(ctx) { super(ctx); } /** * 所有方法接收两个参数 * @param args 前端传的参数 * @param event - ipc通信时才有值。详情见:控制器文档 */ /** * upload */ async shellFun (params) { // 如果是打开路径操作,确保路径存在 if (params.action === 'openMkPath') { try { // 确保目录存在,如果不存在就创建 if (!fs.existsSync(params.params)) { fs.mkdirSync(params.params, { recursive: true }); } shell.openPath(params.params) return; } catch (err) { console.error('创建目录失败:', err); // 即使创建目录失败,也尝试打开路径(可能已经存在) } } shell[params.action](params.params) } async openMain (config) { const { id, url } = config; if (this.app.electron[id]) { const win = this.app.electron[id]; // 切换到指定的 URL await win.loadURL(url); win.focus(); win.show(); return; } const win = new BrowserWindow({ ...config, webPreferences: { webSecurity: false, contextIsolation: false, // false -> 可在渲染进程中使用electron的api,true->需要bridge.js(contextBridge) nodeIntegration: true, // preload: path.join('../preload/preload.js','../preload/bridge.js'), }, }); await win.loadURL(config.url); // 设置窗口的 URL // 监听窗口关闭事件 if(configDeault.debug) win.webContents.openDevTools() // win.on('close', () => { delete this.app.electron[config.id]; // 删除窗口引用 }); this.app.electron[config.id] = win ; } async openDirectory(optiops={ title:"选择文件夹" }){ const filePaths = dialog.showOpenDialogSync({ title:optiops.title || '选择文件夹', properties: ['openDirectory'] }) if(filePaths[0]) return filePaths[0]; return filePaths } /** * 关闭所有子窗口 */ closeAllWindows() { try { // 获取所有窗口 const windows = this.app.electron; // 关闭除主窗口外的所有窗口 for (const [id, window] of Object.entries(windows)) { if (!['mainWindow','extra'].includes(id)) { // 保留主窗口 try { window.close(); delete this.app.electron[id]; } catch (error) { console.error(`关闭窗口 ${id} 失败:`, error); } } } console.log('所有子窗口已关闭'); return { success: true, message: '所有子窗口已关闭' }; } catch (error) { console.error('关闭所有窗口失败:', error); return { success: false, message: '关闭所有窗口失败: ' + error.message }; } } async openImage( optiops= { title:"选择图片", filters:[ { name: '支持JPG,png,gif', extensions: ['jpg','jpeg','png'] }, ], } ){ const filePaths = dialog.showOpenDialogSync({ title:optiops.title || '选择图片', properties:['openFile'], filters:optiops.filters || [ { name: '支持JPG,png,gif', extensions: ['jpg','jpeg','png'] }, ] }) const filePath = filePaths[0]; const fileBuffer = fs.readFileSync(filePath); const base64Image = fileBuffer.toString('base64'); // 获取文件扩展名 const extension = path.extname(filePath).toLowerCase().replace('.', ''); // 根据扩展名确定 MIME 类型 let mimeType = ''; switch (extension) { case 'jpg': case 'jpeg': mimeType = 'image/jpeg'; break; case 'png': mimeType = 'image/png'; break; case 'gif': mimeType = 'image/gif'; break; default: mimeType = 'application/octet-stream'; // 默认 MIME 类型 break; } // 构建 data URL const dataUrl = `data:${mimeType};base64,${base64Image}`; return { filePath:filePath, base64Image:dataUrl }; } async openFile(optiops= { title:"选择文件", filters:[ { name: '支持JPG', extensions: ['jpg','jpeg'] }, ], }){ const filePaths = dialog.showOpenDialogSync({ title:optiops.title || '选择文件', properties: ['openFile'], filters: optiops.filters || [ { name: '选择文件' }, ] }) if(filePaths[0]) return filePaths[0]; return filePaths } getAppConfig(){ const config = readConfigFile() const appPath = app.getAppPath(); const pyPath = path.join(path.dirname(appPath), 'extraResources', 'py'); return { ...config, userDataPath: app.getPath('userData'), appPath: appPath, pyPath:pyPath, } } async readFileImageForPath(filePath,maxWidth=1500){ const getMimeType = (fileName)=>{ const extension = path.extname(fileName).toLowerCase().replace('.', ''); let mimeType = ''; switch (extension) { case 'jpg': case 'jpeg': mimeType = 'image/jpeg'; break; case 'png': mimeType = 'image/png'; break; case 'gif': mimeType = 'image/gif'; break; case 'webp': mimeType = 'image/webp'; break; case 'avif': mimeType = 'image/avif'; break; default: mimeType = 'application/octet-stream'; break; } return mimeType; } try { const fileName = path.basename(filePath); const image = sharp(filePath); const metadata = await image.metadata(); let mimeType = getMimeType(fileName); // 调用下面定义的私有方法获取 MIME 类型 let fileBuffer; if (metadata.width > maxWidth) { // 如果宽度大于 1500px,压缩至 1500px 宽度,保持比例 fileBuffer = await image.resize(maxWidth).toBuffer(); } else { // 否则直接读取原图 fileBuffer = fs.readFileSync(filePath); } return { fileBuffer, fileName, mimeType }; } catch (error) { console.error('Error processing image:', error); throw error; } } } UtilsController.toString = () => '[class ExampleController]'; module.exports = UtilsController;