example.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. 'use strict';
  2. const _ = require('lodash');
  3. const path = require('path');
  4. const fs = require('fs');
  5. const is = require('electron-is');
  6. const { exec } = require('child_process');
  7. const Controller = require('ee-core').Controller;
  8. const Utils = require('ee-core').Utils;
  9. const electronApp = require('electron').app;
  10. const {dialog, webContents, shell, BrowserWindow, BrowserView,
  11. Notification, powerMonitor, screen, nativeTheme} = require('electron');
  12. const autoLaunchManager = require('../library/autoLaunch');
  13. let myTimer = null;
  14. let browserViewObj = null;
  15. let notificationObj = null;
  16. /**
  17. * 示例控制器
  18. * @class
  19. */
  20. class ExampleController extends Controller {
  21. constructor(ctx) {
  22. super(ctx);
  23. }
  24. /**
  25. * 所有方法接收两个参数
  26. * @param args 前端传的参数
  27. * @param event - IpcMainEvent 文档:https://www.electronjs.org/docs/latest/api/structures/ipc-main-event
  28. */
  29. /**
  30. * test
  31. */
  32. async test () {
  33. const result = await this.service.example.test('electron');
  34. let tmpDir = Utils.getLogDir();
  35. console.log('tmpDir:', tmpDir);
  36. console.log('this.app.request:', this.app.request.query);
  37. return result;
  38. }
  39. /**
  40. * json数据库操作
  41. */
  42. async dbOperation(args) {
  43. const { service } = this;
  44. const paramsObj = args;
  45. //console.log('eeeee paramsObj:', paramsObj);
  46. const data = {
  47. action: paramsObj.action,
  48. result: null,
  49. all_list: []
  50. };
  51. switch (paramsObj.action) {
  52. case 'add' :
  53. data.result = await service.storage.addTestData(paramsObj.info);;
  54. break;
  55. case 'del' :
  56. data.result = await service.storage.delTestData(paramsObj.delete_name);;
  57. break;
  58. case 'update' :
  59. data.result = await service.storage.updateTestData(paramsObj.update_name, paramsObj.update_age);
  60. break;
  61. case 'get' :
  62. data.result = await service.storage.getTestData(paramsObj.search_age);
  63. break;
  64. }
  65. data.all_list = await service.storage.getAllTestData();
  66. return data;
  67. }
  68. /**
  69. * hello
  70. */
  71. hello (args) {
  72. let newMsg = args + " +1";
  73. let content = '';
  74. content = '收到:' + args + ',返回:' + newMsg;
  75. return content;
  76. }
  77. /**
  78. * 消息提示对话框
  79. */
  80. messageShow () {
  81. dialog.showMessageBoxSync({
  82. type: 'info', // "none", "info", "error", "question" 或者 "warning"
  83. title: '自定义标题-message',
  84. message: '自定义消息内容',
  85. detail: '其它的额外信息'
  86. })
  87. return '打开了消息框';
  88. }
  89. /**
  90. * 消息提示与确认对话框
  91. */
  92. messageShowConfirm () {
  93. const res = dialog.showMessageBoxSync({
  94. type: 'info',
  95. title: '自定义标题-message',
  96. message: '自定义消息内容',
  97. detail: '其它的额外信息',
  98. cancelId: 1, // 用于取消对话框的按钮的索引
  99. defaultId: 0, // 设置默认选中的按钮
  100. buttons: ['确认', '取消'], // 按钮及索引
  101. })
  102. let data = (res === 0) ? '点击确认按钮' : '点击取消按钮';
  103. return data;
  104. }
  105. /**
  106. * 选择目录
  107. */
  108. selectFolder () {
  109. const filePaths = dialog.showOpenDialogSync({
  110. properties: ['openDirectory', 'createDirectory']
  111. });
  112. if (_.isEmpty(filePaths)) {
  113. return null
  114. }
  115. return filePaths[0];
  116. }
  117. /**
  118. * 打开目录
  119. */
  120. openDirectory (args) {
  121. if (!args.id) {
  122. return false;
  123. }
  124. const dir = electronApp.getPath(args.id);
  125. shell.openPath(dir);
  126. return true;
  127. }
  128. /**
  129. * 长消息 - 开始
  130. */
  131. socketMessageStart (args, event) {
  132. // 每隔1秒,向前端页面发送消息
  133. // 用定时器模拟
  134. // 前端ipc频道 channel
  135. const channel = 'controller.example.socketMessageStart';
  136. myTimer = setInterval(function(e, c, msg) {
  137. let timeNow = Date.now();
  138. let data = msg + ':' + timeNow;
  139. e.reply(`${c}`, data)
  140. }, 1000, event, channel, args)
  141. return '开始了'
  142. }
  143. /**
  144. * 长消息 - 停止
  145. */
  146. socketMessageStop () {
  147. clearInterval(myTimer);
  148. return '停止了'
  149. }
  150. /**
  151. * 执行js语句
  152. */
  153. executeJS (args) {
  154. let jscode = `(()=>{alert('${args}');return 'fromJs:${args}';})()`;
  155. return webContents.fromId(1).executeJavaScript(jscode);
  156. }
  157. /**
  158. * 加载视图内容
  159. */
  160. loadViewContent (args) {
  161. let content = null;
  162. if (args.type == 'html') {
  163. content = path.join('file://', electronApp.getAppPath(), args.content)
  164. } else {
  165. content = args.content;
  166. }
  167. browserViewObj = new BrowserView();
  168. this.app.electron.mainWindow.setBrowserView(browserViewObj)
  169. browserViewObj.setBounds({
  170. x: 300,
  171. y: 170,
  172. width: 650,
  173. height: 400
  174. });
  175. browserViewObj.webContents.loadURL(content);
  176. return true
  177. }
  178. /**
  179. * 移除视图内容
  180. */
  181. removeViewContent () {
  182. this.app.electron.mainWindow.removeBrowserView(browserViewObj);
  183. return true
  184. }
  185. /**
  186. * 打开新窗口
  187. */
  188. createWindow (args) {
  189. let content = null;
  190. if (args.type == 'html') {
  191. content = path.join('file://', electronApp.getAppPath(), args.content)
  192. } else {
  193. content = args.content;
  194. }
  195. let winObj = new BrowserWindow({
  196. x: 10,
  197. y: 10,
  198. width: 980,
  199. height: 650
  200. })
  201. winObj.loadURL(content);
  202. return winObj.id
  203. }
  204. /**
  205. * 加载扩展程序
  206. */
  207. // async loadExtension (args) {
  208. // const crxFile = args[0];
  209. // if (_.isEmpty(crxFile)) {
  210. // return false;
  211. // }
  212. // const extensionId = path.basename(crxFile, '.crx');
  213. // const chromeExtensionDir = chromeExtension.getDirectory();
  214. // const extensionDir = path.join(chromeExtensionDir, extensionId);
  215. // console.log("[api] [example] [loadExtension] extension id:", extensionId);
  216. // unzip(crxFile, extensionDir).then(() => {
  217. // console.log("[api] [example] [loadExtension] unzip success!");
  218. // chromeExtension.load(extensionId);
  219. // });
  220. // return true;
  221. // }
  222. /**
  223. * 创建系统通知
  224. */
  225. sendNotification (arg, event) {
  226. const channel = 'controller.example.sendNotification';
  227. if (!Notification.isSupported()) {
  228. return '当前系统不支持通知';
  229. }
  230. let options = {};
  231. if (!_.isEmpty(arg.title)) {
  232. options.title = arg.title;
  233. }
  234. if (!_.isEmpty(arg.subtitle)) {
  235. options.subtitle = arg.subtitle;
  236. }
  237. if (!_.isEmpty(arg.body)) {
  238. options.body = arg.body;
  239. }
  240. if (!_.isEmpty(arg.silent)) {
  241. options.silent = arg.silent;
  242. }
  243. notificationObj = new Notification(options);
  244. if (arg.clickEvent) {
  245. notificationObj.on('click', (e) => {
  246. let data = {
  247. type: 'click',
  248. msg: '您点击了通知消息'
  249. }
  250. event.reply(`${channel}`, data)
  251. });
  252. }
  253. if (arg.closeEvent) {
  254. notificationObj.on('close', (e) => {
  255. let data = {
  256. type: 'close',
  257. msg: '您关闭了通知消息'
  258. }
  259. event.reply(`${channel}`, data)
  260. });
  261. }
  262. notificationObj.show();
  263. return true
  264. }
  265. /**
  266. * 电源监控
  267. */
  268. initPowerMonitor (arg, event) {
  269. const channel = 'controller.example.initPowerMonitor';
  270. powerMonitor.on('on-ac', (e) => {
  271. let data = {
  272. type: 'on-ac',
  273. msg: '接入了电源'
  274. }
  275. event.reply(`${channel}`, data)
  276. });
  277. powerMonitor.on('on-battery', (e) => {
  278. let data = {
  279. type: 'on-battery',
  280. msg: '使用电池中'
  281. }
  282. event.reply(`${channel}`, data)
  283. });
  284. powerMonitor.on('lock-screen', (e) => {
  285. let data = {
  286. type: 'lock-screen',
  287. msg: '锁屏了'
  288. }
  289. event.reply(`${channel}`, data)
  290. });
  291. powerMonitor.on('unlock-screen', (e) => {
  292. let data = {
  293. type: 'unlock-screen',
  294. msg: '解锁了'
  295. }
  296. event.reply(`${channel}`, data)
  297. });
  298. return true
  299. }
  300. /**
  301. * 获取屏幕信息
  302. */
  303. getScreen (arg) {
  304. let data = [];
  305. let res = {};
  306. if (arg == 0) {
  307. let res = screen.getCursorScreenPoint();
  308. data = [
  309. {
  310. title: '横坐标',
  311. desc: res.x
  312. },
  313. {
  314. title: '纵坐标',
  315. desc: res.y
  316. },
  317. ]
  318. return data;
  319. }
  320. if (arg == 1) {
  321. res = screen.getPrimaryDisplay();
  322. }
  323. if (arg == 2) {
  324. let resArr = screen.getAllDisplays();
  325. // 数组,只取一个吧
  326. res = resArr[0];
  327. }
  328. // console.log('[electron] [ipc] [example] [getScreen] res:', res);
  329. data = [
  330. {
  331. title: '分辨率',
  332. desc: res.bounds.width + ' x ' + res.bounds.height
  333. },
  334. {
  335. title: '单色显示器',
  336. desc: res.monochrome ? '是' : '否'
  337. },
  338. {
  339. title: '色深',
  340. desc: res. colorDepth
  341. },
  342. {
  343. title: '色域',
  344. desc: res.colorSpace
  345. },
  346. {
  347. title: 'scaleFactor',
  348. desc: res.scaleFactor
  349. },
  350. {
  351. title: '加速器',
  352. desc: res.accelerometerSupport
  353. },
  354. {
  355. title: '触控',
  356. desc: res.touchSupport == 'unknown' ? '不支持' : '支持'
  357. },
  358. ]
  359. return data;
  360. }
  361. /**
  362. * 调用其它程序(exe、bash等可执行程序)
  363. */
  364. openSoftware (softName) {
  365. if (!softName) {
  366. return false;
  367. }
  368. let softwarePath = path.join(Utils.getExtraResourcesDir(), softName);
  369. this.app.logger.info('[openSoftware] softwarePath:', softwarePath);
  370. // 检查程序是否存在
  371. if (!fs.existsSync(softwarePath)) {
  372. return false;
  373. }
  374. // 命令行字符串 并 执行
  375. let cmdStr = 'start ' + softwarePath;
  376. exec(cmdStr);
  377. return true;
  378. }
  379. /**
  380. * 开机启动-开启
  381. */
  382. autoLaunch (type) {
  383. console.log('type:', type);
  384. let res = {
  385. type: type,
  386. status: null
  387. };
  388. if (type == 'check') {
  389. res.status = autoLaunchManager.isEnabled();
  390. } else if (type == 'open') {
  391. autoLaunchManager.enable();
  392. res.status = true;
  393. } else if (type == 'close') {
  394. autoLaunchManager.disable();
  395. res.status = false;
  396. }
  397. return res
  398. }
  399. /**
  400. * 获取系统主题
  401. */
  402. getTheme () {
  403. let theme = 'system';
  404. if (nativeTheme.shouldUseHighContrastColors) {
  405. theme = 'light';
  406. } else if (nativeTheme.shouldUseInvertedColorScheme) {
  407. theme = 'dark';
  408. }
  409. return theme;
  410. }
  411. /**
  412. * 设置系统主题
  413. */
  414. setTheme (args) {
  415. // TODO 好像没有什么明显效果
  416. nativeTheme.themeSource = args;
  417. return args;
  418. }
  419. /**
  420. * 检查是否有新版本
  421. */
  422. checkForUpdater () {
  423. const config = this.app.config.autoUpdate;
  424. if ( (is.windows() && config.windows) || (is.macOS() && config.macOS) || (is.linux() && config.linux) ) {
  425. const autoUpdater = require('../library/autoUpdater');
  426. autoUpdater.checkUpdate();
  427. }
  428. return;
  429. }
  430. /**
  431. * 下载新版本
  432. */
  433. downloadApp () {
  434. const config = this.app.config.autoUpdate;
  435. if ( (is.windows() && config.windows) || (is.macOS() && config.macOS) || (is.linux() && config.linux) ) {
  436. const autoUpdater = require('../library/autoUpdater');
  437. autoUpdater.download();
  438. }
  439. return;
  440. }
  441. /**
  442. * 上传文件
  443. */
  444. async uploadFile() {
  445. // const self = this;
  446. // const { ctx, service } = this;
  447. // let tmpDir = Utils.getLogDir();
  448. // const file = ctx.request.files[0];
  449. // try {
  450. // let tmpFile = fs.readFileSync(file.filepath)
  451. // fs.writeFileSync(path.join(tmpDir, file.filename), tmpFile)
  452. // } finally {
  453. // await fs.unlink(file.filepath, function(){});
  454. // }
  455. // const fileStream = fs.createReadStream(path.join(tmpDir, file.filename))
  456. // const uploadRes = await service.example.uploadFileToSMMS(fileStream);
  457. // return uploadRes;
  458. }
  459. /**
  460. * 检测http服务是否开启
  461. */
  462. async checkHttpServer () {
  463. const httpServerConfig = this.app.config.httpServer;
  464. const url = httpServerConfig.protocol + httpServerConfig.host + ':' + httpServerConfig.port;
  465. const data = {
  466. enable: httpServerConfig.enable,
  467. server: url
  468. }
  469. return data;
  470. }
  471. /**
  472. * 一个http请求访问此方法
  473. */
  474. async doHttpRequest () {
  475. // http方法
  476. const method = this.app.request.method;
  477. // http get 参数
  478. let params = this.app.request.query;
  479. params = (params instanceof Object) ? JSON.parse(JSON.stringify(params)) : {};
  480. // http post 参数
  481. const body = this.app.request.body;
  482. const httpInfo = {
  483. method,
  484. params,
  485. body
  486. }
  487. console.log('httpInfo:', httpInfo);
  488. if (!body.id) {
  489. return false;
  490. }
  491. const dir = electronApp.getPath(body.id);
  492. shell.openPath(dir);
  493. return true;
  494. }
  495. /**
  496. * 一个socket io请求访问此方法
  497. */
  498. async doSocketRequest (args) {
  499. if (!args.id) {
  500. return false;
  501. }
  502. const dir = electronApp.getPath(args.id);
  503. shell.openPath(dir);
  504. return true;
  505. }
  506. }
  507. module.exports = ExampleController;