example.js 12 KB

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