From 3896275003e07da15de3a2197a9208a7422d5b70 Mon Sep 17 00:00:00 2001 From: gaoshuaixing Date: Wed, 10 May 2023 19:16:28 +0800 Subject: [PATCH] demo --- electron/controller/effect.js | 25 - electron/controller/example.js | 760 ------------------------------- electron/controller/framework.js | 366 ++++++++++++++- electron/controller/hardware.js | 26 -- electron/controller/os.js | 368 ++++++++++++++- 5 files changed, 718 insertions(+), 827 deletions(-) delete mode 100644 electron/controller/example.js diff --git a/electron/controller/effect.js b/electron/controller/effect.js index 7aec32a..8bd8a1e 100644 --- a/electron/controller/effect.js +++ b/electron/controller/effect.js @@ -11,31 +11,6 @@ class EffectController extends Controller { super(ctx); } - /** - * 所有方法接收两个参数 - * @param args 前端传的参数 - * @param event - ipc通信时才有值。详情见:控制器文档 - */ - - /** - * test - */ - async test () { - const result = await this.service.example.test('electron'); - - // let tmpDir = Ps.getLogDir(); - // Log.info('tmpDir:', tmpDir); - - let mid = await Utils.machineIdSync(true); - Log.info('mid 11111111:', mid); - - Utils.machineId().then((id) => { - Log.info('mid 222222222:', id); - }); - - return result; - } - } EffectController.toString = () => '[class EffectController]'; diff --git a/electron/controller/example.js b/electron/controller/example.js deleted file mode 100644 index f9c827f..0000000 --- a/electron/controller/example.js +++ /dev/null @@ -1,760 +0,0 @@ -'use strict'; - -const _ = require('lodash'); -const path = require('path'); -const fs = require('fs'); -const { exec } = require('child_process'); -const { Controller } = require('ee-core'); -const { - app: electronApp, - dialog, shell, BrowserView, Notification, - powerMonitor, screen, nativeTheme -} = require('electron'); -const dayjs = require('dayjs'); -const Ps = require('ee-core/ps'); -const Log = require('ee-core/log'); -const Utils = require('ee-core/utils'); - -let myTimer = null; -let browserViewObj = null; -let notificationObj = null; - -/** - * 示例控制器 - * @class - */ -class ExampleController extends Controller { - - constructor(ctx) { - super(ctx); - } - - /** - * 所有方法接收两个参数 - * @param args 前端传的参数 - * @param event - ipc通信时才有值。详情见:控制器文档 - */ - - /** - * test - */ - async test () { - const result = await this.service.example.test('electron'); - - // let tmpDir = Ps.getLogDir(); - // Log.info('tmpDir:', tmpDir); - - let mid = await Utils.machineIdSync(true); - Log.info('mid 11111111:', mid); - - Utils.machineId().then((id) => { - Log.info('mid 222222222:', id); - }); - - return result; - } - - /** - * json数据库操作 - */ - async dbOperation(args) { - const { service } = this; - const paramsObj = args; - //Log.info('eeeee paramsObj:', paramsObj); - const data = { - action: paramsObj.action, - result: null, - all_list: [] - }; - - switch (paramsObj.action) { - case 'add' : - data.result = await service.storage.addTestData(paramsObj.info);; - break; - case 'del' : - data.result = await service.storage.delTestData(paramsObj.delete_name);; - break; - case 'update' : - data.result = await service.storage.updateTestData(paramsObj.update_name, paramsObj.update_age); - break; - case 'get' : - data.result = await service.storage.getTestData(paramsObj.search_age); - break; - } - - data.all_list = await service.storage.getAllTestData(); - - return data; - } - - /** - * sqlite数据库操作 - */ - async sqlitedbOperation(args) { - const { service } = this; - const paramsObj = args; - //Log.info('eeeee paramsObj:', paramsObj); - const data = { - action: paramsObj.action, - result: null, - all_list: [] - }; - - switch (paramsObj.action) { - case 'add' : - data.result = await service.storage.addTestDataSqlite(paramsObj.info);; - break; - case 'del' : - data.result = await service.storage.delTestDataSqlite(paramsObj.delete_name);; - break; - case 'update' : - data.result = await service.storage.updateTestDataSqlite(paramsObj.update_name, paramsObj.update_age); - break; - case 'get' : - data.result = await service.storage.getTestDataSqlite(paramsObj.search_age); - break; - case 'getDataDir' : - data.result = await service.storage.getDataDir(); - break; - case 'setDataDir' : - data.result = await service.storage.setCustomDataDir(paramsObj.data_dir); - break; - } - - data.all_list = await service.storage.getAllTestDataSqlite(); - - return data; - } - - /** - * 消息提示对话框 - */ - messageShow () { - dialog.showMessageBoxSync({ - type: 'info', // "none", "info", "error", "question" 或者 "warning" - title: '自定义标题-message', - message: '自定义消息内容', - detail: '其它的额外信息' - }) - - return '打开了消息框'; - } - - /** - * 消息提示与确认对话框 - */ - messageShowConfirm () { - const res = dialog.showMessageBoxSync({ - type: 'info', - title: '自定义标题-message', - message: '自定义消息内容', - detail: '其它的额外信息', - cancelId: 1, // 用于取消对话框的按钮的索引 - defaultId: 0, // 设置默认选中的按钮 - buttons: ['确认', '取消'], // 按钮及索引 - }) - let data = (res === 0) ? '点击确认按钮' : '点击取消按钮'; - - return data; - } - - /** - * 选择目录 - */ - selectFolder () { - const filePaths = dialog.showOpenDialogSync({ - properties: ['openDirectory', 'createDirectory'] - }); - - if (_.isEmpty(filePaths)) { - return null - } - - return filePaths[0]; - } - - /** - * 打开目录 - */ - openDirectory (args) { - if (!args.id) { - return false; - } - let dir = ''; - if (path.isAbsolute(args.id)) { - dir = args.id; - } else { - dir = electronApp.getPath(args.id); - } - - shell.openPath(dir); - return true; - } - - /** - * 加载视图内容 - */ - loadViewContent (args) { - let content = null; - if (args.type == 'html') { - content = path.join('file://', electronApp.getAppPath(), args.content) - } else { - content = args.content; - } - - // electron实验性功能,慎用 - browserViewObj = new BrowserView(); - this.app.electron.mainWindow.setBrowserView(browserViewObj) - browserViewObj.setBounds({ - x: 300, - y: 170, - width: 650, - height: 400 - }); - browserViewObj.webContents.loadURL(content); - return true - } - - /** - * 移除视图内容 - */ - removeViewContent () { - // removeBrowserView移除视图后,进程依然存在,估计是electron bug - this.app.electron.mainWindow.removeBrowserView(browserViewObj); - return true - } - - /** - * 打开新窗口 - */ - createWindow (args) { - let content = null; - if (args.type == 'html') { - content = path.join('file://', electronApp.getAppPath(), args.content) - } else if (args.type == 'web') { - content = args.content; - } else if (args.type == 'vue') { - let addr = 'http://localhost:8080' - if (this.config.env == 'prod') { - const mainServer = this.app.config.mainServer; - addr = mainServer.protocol + mainServer.host + ':' + mainServer.port; - } - - content = addr + args.content; - } else { - // some - } - - const addonWindow = this.app.addon.window; - let opt = { - title: args.windowName || 'new window' - } - const name = args.windowName || 'window-1'; - const win = addonWindow.create(name, opt); - const winContentsId = win.webContents.id; - - // load page - win.loadURL(content); - - return winContentsId - } - - /** - * 获取窗口contents id - */ - getWCid (args) { - const addonWindow = this.app.addon.window; - - // 主窗口的name默认是main,其它窗口name开发者自己定义 - const name = args; - const id = addonWindow.getWCid(name); - - return id; - } - - /** - * 加载扩展程序 - */ - // async loadExtension (args) { - // const crxFile = args[0]; - // if (_.isEmpty(crxFile)) { - // return false; - // } - // const extensionId = path.basename(crxFile, '.crx'); - // const chromeExtensionDir = chromeExtension.getDirectory(); - // const extensionDir = path.join(chromeExtensionDir, extensionId); - - // Log.info("[api] [example] [loadExtension] extension id:", extensionId); - // unzip(crxFile, extensionDir).then(() => { - // Log.info("[api] [example] [loadExtension] unzip success!"); - // chromeExtension.load(extensionId); - // }); - - // return true; - // } - - /** - * 创建系统通知 - */ - sendNotification (arg, event) { - const channel = 'controller.example.sendNotification'; - if (!Notification.isSupported()) { - return '当前系统不支持通知'; - } - - let options = {}; - if (!_.isEmpty(arg.title)) { - options.title = arg.title; - } - if (!_.isEmpty(arg.subtitle)) { - options.subtitle = arg.subtitle; - } - if (!_.isEmpty(arg.body)) { - options.body = arg.body; - } - if (!_.isEmpty(arg.silent)) { - options.silent = arg.silent; - } - - notificationObj = new Notification(options); - - if (arg.clickEvent) { - notificationObj.on('click', (e) => { - let data = { - type: 'click', - msg: '您点击了通知消息' - } - event.reply(`${channel}`, data) - }); - } - - if (arg.closeEvent) { - notificationObj.on('close', (e) => { - let data = { - type: 'close', - msg: '您关闭了通知消息' - } - event.reply(`${channel}`, data) - }); - } - - notificationObj.show(); - - return true - } - - /** - * 电源监控 - */ - initPowerMonitor (arg, event) { - const channel = 'controller.example.initPowerMonitor'; - powerMonitor.on('on-ac', (e) => { - let data = { - type: 'on-ac', - msg: '接入了电源' - } - event.reply(`${channel}`, data) - }); - - powerMonitor.on('on-battery', (e) => { - let data = { - type: 'on-battery', - msg: '使用电池中' - } - event.reply(`${channel}`, data) - }); - - powerMonitor.on('lock-screen', (e) => { - let data = { - type: 'lock-screen', - msg: '锁屏了' - } - event.reply(`${channel}`, data) - }); - - powerMonitor.on('unlock-screen', (e) => { - let data = { - type: 'unlock-screen', - msg: '解锁了' - } - event.reply(`${channel}`, data) - }); - - return true - } - - /** - * 获取屏幕信息 - */ - getScreen (arg) { - let data = []; - let res = {}; - if (arg == 0) { - let res = screen.getCursorScreenPoint(); - data = [ - { - title: '横坐标', - desc: res.x - }, - { - title: '纵坐标', - desc: res.y - }, - ] - - return data; - } - if (arg == 1) { - res = screen.getPrimaryDisplay(); - } - if (arg == 2) { - let resArr = screen.getAllDisplays(); - // 数组,只取一个吧 - res = resArr[0]; - } - // Log.info('[electron] [ipc] [example] [getScreen] res:', res); - data = [ - { - title: '分辨率', - desc: res.bounds.width + ' x ' + res.bounds.height - }, - { - title: '单色显示器', - desc: res.monochrome ? '是' : '否' - }, - { - title: '色深', - desc: res. colorDepth - }, - { - title: '色域', - desc: res.colorSpace - }, - { - title: 'scaleFactor', - desc: res.scaleFactor - }, - { - title: '加速器', - desc: res.accelerometerSupport - }, - { - title: '触控', - desc: res.touchSupport == 'unknown' ? '不支持' : '支持' - }, - ] - - return data; - } - - /** - * 调用其它程序(exe、bash等可执行程序) - */ - openSoftware (softName) { - if (!softName) { - return false; - } - - let softwarePath = path.join(Ps.getExtraResourcesDir(), softName); - Log.info('[openSoftware] softwarePath:', softwarePath); - - // 检查程序是否存在 - if (!fs.existsSync(softwarePath)) { - return false; - } - // 命令行字符串 并 执行 - let cmdStr = 'start ' + softwarePath; - exec(cmdStr); - - return true; - } - - /** - * 获取系统主题 - */ - getTheme () { - let theme = 'system'; - if (nativeTheme.shouldUseHighContrastColors) { - theme = 'light'; - } else if (nativeTheme.shouldUseInvertedColorScheme) { - theme = 'dark'; - } - - return theme; - } - - /** - * 设置系统主题 - */ - setTheme (args) { - - // TODO 好像没有什么明显效果 - nativeTheme.themeSource = args; - - return args; - } - - - /** - * 检查是否有新版本 - */ - checkForUpdater () { - const autoUpdaterAddon = this.app.addon.autoUpdater; - autoUpdaterAddon.checkUpdate(); - - return; - } - - /** - * 下载新版本 - */ - downloadApp () { - const autoUpdaterAddon = this.app.addon.autoUpdater; - autoUpdaterAddon.download(); - return; - } - - /** - * 检测http服务是否开启 - */ - async checkHttpServer () { - const httpServerConfig = this.app.config.httpServer; - const url = httpServerConfig.protocol + httpServerConfig.host + ':' + httpServerConfig.port; - - const data = { - enable: httpServerConfig.enable, - server: url - } - return data; - } - - /** - * 一个http请求访问此方法 - */ - async doHttpRequest () { - // http方法 - const method = this.app.request.method; - // http get 参数 - let params = this.app.request.query; - params = (params instanceof Object) ? params : JSON.parse(JSON.stringify(params)); - // http post 参数 - const body = this.app.request.body; - - const httpInfo = { - method, - params, - body - } - Log.info('httpInfo:', httpInfo); - - if (!body.id) { - return false; - } - const dir = electronApp.getPath(body.id); - shell.openPath(dir); - - return true; - } - - /** - * 一个socket io请求访问此方法 - */ - async doSocketRequest (args) { - if (!args.id) { - return false; - } - const dir = electronApp.getPath(args.id); - shell.openPath(dir); - - return true; - } - - /** - * 异步消息类型 - * @param args 前端传的参数 - * @param event - IpcMainInvokeEvent 文档:https://www.electronjs.org/zh/docs/latest/api/structures/ipc-main-invoke-event - */ - async ipcInvokeMsg (args, event) { - let timeNow = dayjs().format('YYYY-MM-DD HH:mm:ss'); - const data = args + ' - ' + timeNow; - - return data; - } - - /** - * 同步消息类型 - * @param args 前端传的参数 - * @param event - IpcMainEvent 文档:https://www.electronjs.org/docs/latest/api/structures/ipc-main-event - */ - async ipcSendSyncMsg (args) { - let timeNow = dayjs().format('YYYY-MM-DD HH:mm:ss'); - const data = args + ' - ' + timeNow; - - return data; - } - - /** - * 双向异步通信 - * @param args 前端传的参数 - * @param event - IpcMainEvent 文档:https://www.electronjs.org/docs/latest/api/structures/ipc-main-event - */ - ipcSendMsg (args, event) { - // 前端ipc频道 channel - const channel = 'controller.example.ipcSendMsg'; - - if (args.type == 'start') { - // 每隔1秒,向前端页面发送消息 - // 用定时器模拟 - myTimer = setInterval(function(e, c, msg) { - let timeNow = Date.now(); - let data = msg + ':' + timeNow; - e.reply(`${c}`, data) - }, 1000, event, channel, args.content) - - return '开始了' - } else if (args.type == 'end') { - clearInterval(myTimer); - return '停止了' - } else { - return 'ohther' - } - } - - /** - * 上传文件 - */ - async uploadFile() { - let tmpDir = Ps.getLogDir(); - const files = this.app.request.files; - let file = files.file; - - let tmpFilePath = path.join(tmpDir, file.originalFilename); - try { - let tmpFile = fs.readFileSync(file.filepath); - fs.writeFileSync(tmpFilePath, tmpFile); - } finally { - await fs.unlink(file.filepath, function(){}); - } - const fileStream = fs.createReadStream(tmpFilePath); - const uploadRes = await this.service.example.uploadFileToSMMS(fileStream); - - return uploadRes; - } - - /** - * 启动java项目 - */ - async startJavaServer () { - let data = { - code: 0, - msg: '', - server: '' - } - const javaCfg = this.app.config.addons.javaServer || {}; - if (!javaCfg.enable) { - data.code = -1; - data.msg = 'addon not enabled!'; - return data; - } - - const javaServerAddon = this.app.addon.javaServer; - await javaServerAddon.createServer(); - - data.server = 'http://localhost:' + javaCfg.port; - - return data; - } - - /** - * 关闭java项目 - */ - async closeJavaServer () { - let data = { - code: 0, - msg: '', - } - const javaCfg = this.app.config.addons.javaServer || {}; - if (!javaCfg.enable) { - data.code = -1; - data.msg = 'addon not enabled!'; - return data; - } - - const javaServerAddon = this.app.addon.javaServer; - await javaServerAddon.kill(); - - return data; - } - - /** - * 任务 - */ - someJob (args, event) { - let jobId = args.id; - let action = args.action; - - let result; - switch (action) { - case 'create': - result = this.service.example.doJob(jobId, action, event); - break; - case 'close': - this.service.example.doJob(jobId, action, event); - break; - default: - } - - let data = { - jobId, - action, - result - } - return data; - } - - /** - * 创建任务池 - */ - async createPool (args, event) { - let num = args.number; - this.service.example.doCreatePool(num, event); - - // test monitor - this.service.example.monitorJob(); - - return; - } - - /** - * 通过进程池执行任务 - */ - someJobByPool (args, event) { - let jobId = args.id; - let action = args.action; - - let result; - switch (action) { - case 'run': - result = this.service.example.doJobByPool(jobId, action, event); - break; - default: - } - - let data = { - jobId, - action, - result - } - return data; - } - - /** - * 测试接口 - */ - hello (args) { - Log.info('hello ', args); - } -} - -ExampleController.toString = () => '[class ExampleController]'; -module.exports = ExampleController; diff --git a/electron/controller/framework.js b/electron/controller/framework.js index 1234411..51da4f1 100644 --- a/electron/controller/framework.js +++ b/electron/controller/framework.js @@ -1,5 +1,16 @@ 'use strict'; +const path = require('path'); +const fs = require('fs'); +const { exec } = require('child_process'); +const { Controller } = require('ee-core'); +const { app: electronApp, shell } = require('electron'); +const dayjs = require('dayjs'); +const Ps = require('ee-core/ps'); +const Log = require('ee-core/log'); +const Utils = require('ee-core/utils'); + +let myTimer = null; /** * electron-egg framework - 功能demo @@ -20,7 +31,7 @@ class FrameworkController extends Controller { /** * test */ - async test () { + async test() { const result = await this.service.example.test('electron'); // let tmpDir = Ps.getLogDir(); @@ -36,6 +47,359 @@ class FrameworkController extends Controller { return result; } + /** + * json数据库操作 + */ + async dbOperation(args) { + const { service } = this; + const paramsObj = args; + //Log.info('eeeee paramsObj:', paramsObj); + const data = { + action: paramsObj.action, + result: null, + all_list: [] + }; + + switch (paramsObj.action) { + case 'add' : + data.result = await service.storage.addTestData(paramsObj.info);; + break; + case 'del' : + data.result = await service.storage.delTestData(paramsObj.delete_name);; + break; + case 'update' : + data.result = await service.storage.updateTestData(paramsObj.update_name, paramsObj.update_age); + break; + case 'get' : + data.result = await service.storage.getTestData(paramsObj.search_age); + break; + } + + data.all_list = await service.storage.getAllTestData(); + + return data; + } + + /** + * sqlite数据库操作 + */ + async sqlitedbOperation(args) { + const { service } = this; + const paramsObj = args; + //Log.info('eeeee paramsObj:', paramsObj); + const data = { + action: paramsObj.action, + result: null, + all_list: [] + }; + + switch (paramsObj.action) { + case 'add' : + data.result = await service.storage.addTestDataSqlite(paramsObj.info);; + break; + case 'del' : + data.result = await service.storage.delTestDataSqlite(paramsObj.delete_name);; + break; + case 'update' : + data.result = await service.storage.updateTestDataSqlite(paramsObj.update_name, paramsObj.update_age); + break; + case 'get' : + data.result = await service.storage.getTestDataSqlite(paramsObj.search_age); + break; + case 'getDataDir' : + data.result = await service.storage.getDataDir(); + break; + case 'setDataDir' : + data.result = await service.storage.setCustomDataDir(paramsObj.data_dir); + break; + } + + data.all_list = await service.storage.getAllTestDataSqlite(); + + return data; + } + + /** + * 调用其它程序(exe、bash等可执行程序) + */ + openSoftware(softName) { + if (!softName) { + return false; + } + + let softwarePath = path.join(Ps.getExtraResourcesDir(), softName); + Log.info('[openSoftware] softwarePath:', softwarePath); + + // 检查程序是否存在 + if (!fs.existsSync(softwarePath)) { + return false; + } + // 命令行字符串 并 执行 + let cmdStr = 'start ' + softwarePath; + exec(cmdStr); + + return true; + } + + /** + * 检查是否有新版本 + */ + checkForUpdater() { + const autoUpdaterAddon = this.app.addon.autoUpdater; + autoUpdaterAddon.checkUpdate(); + + return; + } + + /** + * 下载新版本 + */ + downloadApp() { + const autoUpdaterAddon = this.app.addon.autoUpdater; + autoUpdaterAddon.download(); + return; + } + + /** + * 检测http服务是否开启 + */ + async checkHttpServer() { + const httpServerConfig = this.app.config.httpServer; + const url = httpServerConfig.protocol + httpServerConfig.host + ':' + httpServerConfig.port; + + const data = { + enable: httpServerConfig.enable, + server: url + } + return data; + } + + /** + * 一个http请求访问此方法 + */ + async doHttpRequest() { + // http方法 + const method = this.app.request.method; + // http get 参数 + let params = this.app.request.query; + params = (params instanceof Object) ? params : JSON.parse(JSON.stringify(params)); + // http post 参数 + const body = this.app.request.body; + + const httpInfo = { + method, + params, + body + } + Log.info('httpInfo:', httpInfo); + + if (!body.id) { + return false; + } + const dir = electronApp.getPath(body.id); + shell.openPath(dir); + + return true; + } + + /** + * 一个socket io请求访问此方法 + */ + async doSocketRequest(args) { + if (!args.id) { + return false; + } + const dir = electronApp.getPath(args.id); + shell.openPath(dir); + + return true; + } + + /** + * 异步消息类型 + * @param args 前端传的参数 + * @param event - IpcMainInvokeEvent 文档:https://www.electronjs.org/zh/docs/latest/api/structures/ipc-main-invoke-event + */ + async ipcInvokeMsg(args, event) { + let timeNow = dayjs().format('YYYY-MM-DD HH:mm:ss'); + const data = args + ' - ' + timeNow; + + return data; + } + + /** + * 同步消息类型 + * @param args 前端传的参数 + * @param event - IpcMainEvent 文档:https://www.electronjs.org/docs/latest/api/structures/ipc-main-event + */ + async ipcSendSyncMsg(args) { + let timeNow = dayjs().format('YYYY-MM-DD HH:mm:ss'); + const data = args + ' - ' + timeNow; + + return data; + } + + /** + * 双向异步通信 + * @param args 前端传的参数 + * @param event - IpcMainEvent 文档:https://www.electronjs.org/docs/latest/api/structures/ipc-main-event + */ + ipcSendMsg(args, event) { + // 前端ipc频道 channel + const channel = 'controller.example.ipcSendMsg'; + + if (args.type == 'start') { + // 每隔1秒,向前端页面发送消息 + // 用定时器模拟 + myTimer = setInterval(function(e, c, msg) { + let timeNow = Date.now(); + let data = msg + ':' + timeNow; + e.reply(`${c}`, data) + }, 1000, event, channel, args.content) + + return '开始了' + } else if (args.type == 'end') { + clearInterval(myTimer); + return '停止了' + } else { + return 'ohther' + } + } + + /** + * 上传文件 + */ + async uploadFile() { + let tmpDir = Ps.getLogDir(); + const files = this.app.request.files; + let file = files.file; + + let tmpFilePath = path.join(tmpDir, file.originalFilename); + try { + let tmpFile = fs.readFileSync(file.filepath); + fs.writeFileSync(tmpFilePath, tmpFile); + } finally { + await fs.unlink(file.filepath, function(){}); + } + const fileStream = fs.createReadStream(tmpFilePath); + const uploadRes = await this.service.example.uploadFileToSMMS(fileStream); + + return uploadRes; + } + + /** + * 启动java项目 + */ + async startJavaServer() { + let data = { + code: 0, + msg: '', + server: '' + } + const javaCfg = this.app.config.addons.javaServer || {}; + if (!javaCfg.enable) { + data.code = -1; + data.msg = 'addon not enabled!'; + return data; + } + + const javaServerAddon = this.app.addon.javaServer; + await javaServerAddon.createServer(); + + data.server = 'http://localhost:' + javaCfg.port; + + return data; + } + + /** + * 关闭java项目 + */ + async closeJavaServer() { + let data = { + code: 0, + msg: '', + } + const javaCfg = this.app.config.addons.javaServer || {}; + if (!javaCfg.enable) { + data.code = -1; + data.msg = 'addon not enabled!'; + return data; + } + + const javaServerAddon = this.app.addon.javaServer; + await javaServerAddon.kill(); + + return data; + } + + /** + * 任务 + */ + someJob(args, event) { + let jobId = args.id; + let action = args.action; + + let result; + switch (action) { + case 'create': + result = this.service.example.doJob(jobId, action, event); + break; + case 'close': + this.service.example.doJob(jobId, action, event); + break; + default: + } + + let data = { + jobId, + action, + result + } + return data; + } + + /** + * 创建任务池 + */ + async createPool(args, event) { + let num = args.number; + this.service.example.doCreatePool(num, event); + + // test monitor + this.service.example.monitorJob(); + + return; + } + + /** + * 通过进程池执行任务 + */ + someJobByPool(args, event) { + let jobId = args.id; + let action = args.action; + + let result; + switch (action) { + case 'run': + result = this.service.example.doJobByPool(jobId, action, event); + break; + default: + } + + let data = { + jobId, + action, + result + } + return data; + } + + /** + * 测试接口 + */ + hello(args) { + Log.info('hello ', args); + } } FrameworkController.toString = () => '[class FrameworkController]'; diff --git a/electron/controller/hardware.js b/electron/controller/hardware.js index d9b88d0..3204786 100644 --- a/electron/controller/hardware.js +++ b/electron/controller/hardware.js @@ -1,6 +1,5 @@ 'use strict'; - /** * 硬件设备 - 功能demo * @class @@ -11,31 +10,6 @@ class HardwareController extends Controller { super(ctx); } - /** - * 所有方法接收两个参数 - * @param args 前端传的参数 - * @param event - ipc通信时才有值。详情见:控制器文档 - */ - - /** - * test - */ - async test () { - const result = await this.service.example.test('electron'); - - // let tmpDir = Ps.getLogDir(); - // Log.info('tmpDir:', tmpDir); - - let mid = await Utils.machineIdSync(true); - Log.info('mid 11111111:', mid); - - Utils.machineId().then((id) => { - Log.info('mid 222222222:', id); - }); - - return result; - } - } HardwareController.toString = () => '[class HardwareController]'; diff --git a/electron/controller/os.js b/electron/controller/os.js index 0709680..3255524 100644 --- a/electron/controller/os.js +++ b/electron/controller/os.js @@ -1,5 +1,17 @@ 'use strict'; +const _ = require('lodash'); +const path = require('path'); +const { Controller } = require('ee-core'); +const { + app: electronApp, + dialog, shell, BrowserView, Notification, + powerMonitor, screen, nativeTheme +} = require('electron'); + +let myTimer = null; +let browserViewObj = null; +let notificationObj = null; /** * 操作系统 - 功能demo @@ -18,24 +30,350 @@ class OsController extends Controller { */ /** - * test + * 消息提示对话框 */ - async test () { - const result = await this.service.example.test('electron'); - - // let tmpDir = Ps.getLogDir(); - // Log.info('tmpDir:', tmpDir); - - let mid = await Utils.machineIdSync(true); - Log.info('mid 11111111:', mid); - - Utils.machineId().then((id) => { - Log.info('mid 222222222:', id); - }); - - return result; + messageShow () { + dialog.showMessageBoxSync({ + type: 'info', // "none", "info", "error", "question" 或者 "warning" + title: '自定义标题-message', + message: '自定义消息内容', + detail: '其它的额外信息' + }) + + return '打开了消息框'; } + /** + * 消息提示与确认对话框 + */ + messageShowConfirm () { + const res = dialog.showMessageBoxSync({ + type: 'info', + title: '自定义标题-message', + message: '自定义消息内容', + detail: '其它的额外信息', + cancelId: 1, // 用于取消对话框的按钮的索引 + defaultId: 0, // 设置默认选中的按钮 + buttons: ['确认', '取消'], // 按钮及索引 + }) + let data = (res === 0) ? '点击确认按钮' : '点击取消按钮'; + + return data; + } + + /** + * 选择目录 + */ + selectFolder () { + const filePaths = dialog.showOpenDialogSync({ + properties: ['openDirectory', 'createDirectory'] + }); + + if (_.isEmpty(filePaths)) { + return null + } + + return filePaths[0]; + } + + /** + * 打开目录 + */ + openDirectory (args) { + if (!args.id) { + return false; + } + let dir = ''; + if (path.isAbsolute(args.id)) { + dir = args.id; + } else { + dir = electronApp.getPath(args.id); + } + + shell.openPath(dir); + return true; + } + + /** + * 加载视图内容 + */ + loadViewContent (args) { + let content = null; + if (args.type == 'html') { + content = path.join('file://', electronApp.getAppPath(), args.content) + } else { + content = args.content; + } + + // electron实验性功能,慎用 + browserViewObj = new BrowserView(); + this.app.electron.mainWindow.setBrowserView(browserViewObj) + browserViewObj.setBounds({ + x: 300, + y: 170, + width: 650, + height: 400 + }); + browserViewObj.webContents.loadURL(content); + return true + } + + /** + * 移除视图内容 + */ + removeViewContent () { + // removeBrowserView移除视图后,进程依然存在,估计是electron bug + this.app.electron.mainWindow.removeBrowserView(browserViewObj); + return true + } + + /** + * 打开新窗口 + */ + createWindow (args) { + let content = null; + if (args.type == 'html') { + content = path.join('file://', electronApp.getAppPath(), args.content) + } else if (args.type == 'web') { + content = args.content; + } else if (args.type == 'vue') { + let addr = 'http://localhost:8080' + if (this.config.env == 'prod') { + const mainServer = this.app.config.mainServer; + addr = mainServer.protocol + mainServer.host + ':' + mainServer.port; + } + + content = addr + args.content; + } else { + // some + } + + const addonWindow = this.app.addon.window; + let opt = { + title: args.windowName || 'new window' + } + const name = args.windowName || 'window-1'; + const win = addonWindow.create(name, opt); + const winContentsId = win.webContents.id; + + // load page + win.loadURL(content); + + return winContentsId + } + + /** + * 获取窗口contents id + */ + getWCid (args) { + const addonWindow = this.app.addon.window; + + // 主窗口的name默认是main,其它窗口name开发者自己定义 + const name = args; + const id = addonWindow.getWCid(name); + + return id; + } + + /** + * 加载扩展程序 + */ + // async loadExtension (args) { + // const crxFile = args[0]; + // if (_.isEmpty(crxFile)) { + // return false; + // } + // const extensionId = path.basename(crxFile, '.crx'); + // const chromeExtensionDir = chromeExtension.getDirectory(); + // const extensionDir = path.join(chromeExtensionDir, extensionId); + + // Log.info("[api] [example] [loadExtension] extension id:", extensionId); + // unzip(crxFile, extensionDir).then(() => { + // Log.info("[api] [example] [loadExtension] unzip success!"); + // chromeExtension.load(extensionId); + // }); + + // return true; + // } + + /** + * 创建系统通知 + */ + sendNotification (arg, event) { + const channel = 'controller.example.sendNotification'; + if (!Notification.isSupported()) { + return '当前系统不支持通知'; + } + + let options = {}; + if (!_.isEmpty(arg.title)) { + options.title = arg.title; + } + if (!_.isEmpty(arg.subtitle)) { + options.subtitle = arg.subtitle; + } + if (!_.isEmpty(arg.body)) { + options.body = arg.body; + } + if (!_.isEmpty(arg.silent)) { + options.silent = arg.silent; + } + + notificationObj = new Notification(options); + + if (arg.clickEvent) { + notificationObj.on('click', (e) => { + let data = { + type: 'click', + msg: '您点击了通知消息' + } + event.reply(`${channel}`, data) + }); + } + + if (arg.closeEvent) { + notificationObj.on('close', (e) => { + let data = { + type: 'close', + msg: '您关闭了通知消息' + } + event.reply(`${channel}`, data) + }); + } + + notificationObj.show(); + + return true + } + + /** + * 电源监控 + */ + initPowerMonitor (arg, event) { + const channel = 'controller.example.initPowerMonitor'; + powerMonitor.on('on-ac', (e) => { + let data = { + type: 'on-ac', + msg: '接入了电源' + } + event.reply(`${channel}`, data) + }); + + powerMonitor.on('on-battery', (e) => { + let data = { + type: 'on-battery', + msg: '使用电池中' + } + event.reply(`${channel}`, data) + }); + + powerMonitor.on('lock-screen', (e) => { + let data = { + type: 'lock-screen', + msg: '锁屏了' + } + event.reply(`${channel}`, data) + }); + + powerMonitor.on('unlock-screen', (e) => { + let data = { + type: 'unlock-screen', + msg: '解锁了' + } + event.reply(`${channel}`, data) + }); + + return true + } + + /** + * 获取屏幕信息 + */ + getScreen (arg) { + let data = []; + let res = {}; + if (arg == 0) { + let res = screen.getCursorScreenPoint(); + data = [ + { + title: '横坐标', + desc: res.x + }, + { + title: '纵坐标', + desc: res.y + }, + ] + + return data; + } + if (arg == 1) { + res = screen.getPrimaryDisplay(); + } + if (arg == 2) { + let resArr = screen.getAllDisplays(); + // 数组,只取一个吧 + res = resArr[0]; + } + // Log.info('[electron] [ipc] [example] [getScreen] res:', res); + data = [ + { + title: '分辨率', + desc: res.bounds.width + ' x ' + res.bounds.height + }, + { + title: '单色显示器', + desc: res.monochrome ? '是' : '否' + }, + { + title: '色深', + desc: res. colorDepth + }, + { + title: '色域', + desc: res.colorSpace + }, + { + title: 'scaleFactor', + desc: res.scaleFactor + }, + { + title: '加速器', + desc: res.accelerometerSupport + }, + { + title: '触控', + desc: res.touchSupport == 'unknown' ? '不支持' : '支持' + }, + ] + + return data; + } + + /** + * 获取系统主题 + */ + getTheme () { + let theme = 'system'; + if (nativeTheme.shouldUseHighContrastColors) { + theme = 'light'; + } else if (nativeTheme.shouldUseInvertedColorScheme) { + theme = 'dark'; + } + + return theme; + } + + /** + * 设置系统主题 + */ + setTheme (args) { + + // TODO 好像没有什么明显效果 + nativeTheme.themeSource = args; + + return args; + } } OsController.toString = () => '[class OsController]';