utils.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. 'use strict';
  2. const { Controller } = require('ee-core');
  3. const { shell } = require('electron');
  4. const Addon = require('ee-core/addon');
  5. const { dialog } = require('electron');
  6. const fs = require('fs');
  7. const path = require('path');
  8. const CoreWindow = require('ee-core/electron/window');
  9. const { BrowserWindow, Menu } = require('electron');
  10. const errData = {
  11. msg :'请求失败,请联系管理员',
  12. code:999
  13. }
  14. const sharp = require('sharp'); // 确保安装:npm install sharp
  15. /**
  16. * example
  17. * @class
  18. */
  19. class UtilsController extends Controller {
  20. constructor(ctx) {
  21. super(ctx);
  22. }
  23. /**
  24. * 所有方法接收两个参数
  25. * @param args 前端传的参数
  26. * @param event - ipc通信时才有值。详情见:控制器文档
  27. */
  28. /**
  29. * upload
  30. */
  31. async shellFun (params) {
  32. console.log(params)
  33. shell[params.action](params.params)
  34. }
  35. async openMain (config) {
  36. const { id, url } = config;
  37. if (this.app.electron[id]) {
  38. const win = this.app.electron[id];
  39. // 切换到指定的 URL
  40. if(id === 'generate') await win.loadURL(url);
  41. win.focus();
  42. win.show();
  43. return;
  44. }
  45. const win = new BrowserWindow({
  46. ...config,
  47. webPreferences: {
  48. webSecurity: false,
  49. contextIsolation: false, // false -> 可在渲染进程中使用electron的api,true->需要bridge.js(contextBridge)
  50. nodeIntegration: true,
  51. // preload: path.join('../preload/preload.js','../preload/bridge.js'),
  52. },
  53. });
  54. await win.loadURL(config.url); // 设置窗口的 URL
  55. // 监听窗口关闭事件
  56. if(this.app?.env === 'development') win.webContents.openDevTools(config.openDevTools)
  57. //
  58. win.on('close', () => {
  59. delete this.app.electron[config.id]; // 删除窗口引用
  60. });
  61. this.app.electron[config.id] = win ;
  62. }
  63. async openDirectory(optiops={
  64. title:"选择文件夹"
  65. }){
  66. const filePaths = dialog.showOpenDialogSync({
  67. title:optiops.title || '选择文件夹',
  68. properties: ['openDirectory']
  69. })
  70. if(filePaths[0]) return filePaths[0];
  71. return filePaths
  72. }
  73. async openImage(
  74. optiops= {
  75. title:"选择图片",
  76. filters:[
  77. { name: '支持JPG,png,gif', extensions: ['jpg','jpeg','png'] },
  78. ],
  79. }
  80. ){
  81. const filePaths = dialog.showOpenDialogSync({
  82. title:optiops.title || '选择图片',
  83. properties:['openFile'],
  84. filters:optiops.filters || [
  85. { name: '支持JPG,png,gif', extensions: ['jpg','jpeg','png'] },
  86. ]
  87. })
  88. const filePath = filePaths[0];
  89. const fileBuffer = fs.readFileSync(filePath);
  90. const base64Image = fileBuffer.toString('base64');
  91. // 获取文件扩展名
  92. const extension = path.extname(filePath).toLowerCase().replace('.', '');
  93. // 根据扩展名确定 MIME 类型
  94. let mimeType = '';
  95. switch (extension) {
  96. case 'jpg':
  97. case 'jpeg':
  98. mimeType = 'image/jpeg';
  99. break;
  100. case 'png':
  101. mimeType = 'image/png';
  102. break;
  103. case 'gif':
  104. mimeType = 'image/gif';
  105. break;
  106. default:
  107. mimeType = 'application/octet-stream'; // 默认 MIME 类型
  108. break;
  109. }
  110. // 构建 data URL
  111. const dataUrl = `data:${mimeType};base64,${base64Image}`;
  112. return {
  113. filePath:filePath,
  114. base64Image:dataUrl
  115. };
  116. }
  117. async openFile(optiops= {
  118. title:"选择文件",
  119. filters:[
  120. { name: '支持JPG', extensions: ['jpg','jpeg'] },
  121. ],
  122. }){
  123. const filePaths = dialog.showOpenDialogSync({
  124. title:optiops.title || '选择文件',
  125. properties: ['openFile'],
  126. filters: optiops.filters || [
  127. { name: '选择文件' },
  128. ]
  129. })
  130. if(filePaths[0]) return filePaths[0];
  131. return filePaths
  132. }
  133. async readFileImageForPath(filePath,maxWidth=1500){
  134. const getMimeType = (fileName)=>{
  135. const extension = path.extname(fileName).toLowerCase().replace('.', '');
  136. let mimeType = '';
  137. switch (extension) {
  138. case 'jpg':
  139. case 'jpeg':
  140. mimeType = 'image/jpeg';
  141. break;
  142. case 'png':
  143. mimeType = 'image/png';
  144. break;
  145. case 'gif':
  146. mimeType = 'image/gif';
  147. break;
  148. case 'webp':
  149. mimeType = 'image/webp';
  150. break;
  151. case 'avif':
  152. mimeType = 'image/avif';
  153. break;
  154. default:
  155. mimeType = 'application/octet-stream';
  156. break;
  157. }
  158. return mimeType;
  159. }
  160. try {
  161. const fileName = path.basename(filePath);
  162. const image = sharp(filePath);
  163. const metadata = await image.metadata();
  164. let mimeType = getMimeType(fileName); // 调用下面定义的私有方法获取 MIME 类型
  165. let fileBuffer;
  166. if (metadata.width > maxWidth) {
  167. // 如果宽度大于 1500px,压缩至 1500px 宽度,保持比例
  168. fileBuffer = await image.resize(maxWidth).toBuffer();
  169. } else {
  170. // 否则直接读取原图
  171. fileBuffer = fs.readFileSync(filePath);
  172. }
  173. return {
  174. fileBuffer,
  175. fileName,
  176. mimeType
  177. };
  178. } catch (error) {
  179. console.error('Error processing image:', error);
  180. throw error;
  181. }
  182. }
  183. }
  184. UtilsController.toString = () => '[class ExampleController]';
  185. module.exports = UtilsController;