ee-core 1.5.2-beta.1 → 1.5.2-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +2 -2
- package/addon/window/index.js +91 -91
- package/bin/tools.js +18 -18
- package/config/config.default.js +280 -280
- package/core/index.js +12 -12
- package/core/lib/ee.js +218 -218
- package/core/lib/loader/context_loader.js +106 -106
- package/core/lib/loader/ee_loader.js +457 -457
- package/core/lib/loader/file_loader.js +325 -325
- package/core/lib/loader/mixin/addon.js +32 -32
- package/core/lib/loader/mixin/config.js +135 -135
- package/core/lib/loader/mixin/controller.js +124 -124
- package/core/lib/loader/mixin/service.js +28 -28
- package/core/lib/utils/base_context_class.js +34 -34
- package/core/lib/utils/index.js +127 -127
- package/core/lib/utils/sequencify.js +59 -59
- package/core/lib/utils/timing.js +77 -77
- package/index.js +49 -49
- package/lib/appLoader.js +53 -53
- package/lib/application.js +84 -84
- package/lib/baseApp.js +131 -131
- package/lib/constant.js +9 -9
- package/lib/eeApp.js +359 -359
- package/lib/httpclient.js +136 -136
- package/lib/logger.js +46 -46
- package/lib/socket/httpServer.js +142 -142
- package/lib/socket/io.js +23 -23
- package/lib/socket/ipcServer.js +108 -108
- package/lib/socket/socketClient.js +50 -50
- package/lib/socket/socketServer.js +76 -76
- package/lib/socket/start.js +22 -22
- package/lib/storage/index.js +33 -33
- package/lib/storage/lowdb/adapters/Base.js +15 -15
- package/lib/storage/lowdb/adapters/FileAsync.js +41 -41
- package/lib/storage/lowdb/adapters/FileSync.js +39 -39
- package/lib/storage/lowdb/adapters/LocalStorage.js +20 -20
- package/lib/storage/lowdb/adapters/Memory.js +8 -8
- package/lib/storage/lowdb/adapters/_stringify.js +4 -4
- package/lib/storage/lowdb/common.js +33 -33
- package/lib/storage/lowdb/fp.js +23 -23
- package/lib/storage/lowdb/{is-promise.js → isPromise.js} +5 -5
- package/lib/storage/lowdb/main.js +46 -46
- package/lib/storage/lowdb/nano.js +5 -5
- package/lib/storage/lowdbStorage.js +98 -98
- package/lib/storage/sqliteStorage.js +127 -127
- package/package.json +48 -48
- package/tools/encrypt.js +274 -274
- package/tools/replaceDist.js +61 -61
- package/utils/common.js +90 -90
- package/utils/index.js +246 -246
- package/utils/wrap.js +37 -37
package/lib/eeApp.js
CHANGED
|
@@ -1,360 +1,360 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const assert = require('assert');
|
|
4
|
-
const getPort = require('get-port');
|
|
5
|
-
const {app, BrowserWindow, BrowserView, Menu} = require('electron');
|
|
6
|
-
const BaseApp = require('./baseApp');
|
|
7
|
-
const is = require('is-type-of');
|
|
8
|
-
const Koa = require('koa');
|
|
9
|
-
const koaServe = require('koa-static');
|
|
10
|
-
const https = require('https');
|
|
11
|
-
const utilsCommon = require('../utils/common');
|
|
12
|
-
|
|
13
|
-
class EeApp extends BaseApp {
|
|
14
|
-
constructor(options = {}) {
|
|
15
|
-
super(options);
|
|
16
|
-
|
|
17
|
-
this.electron = {
|
|
18
|
-
mainWindow: null,
|
|
19
|
-
tray: null,
|
|
20
|
-
extra: {
|
|
21
|
-
closeWindow: false,
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* 生成端口
|
|
28
|
-
*/
|
|
29
|
-
async createPorts () {
|
|
30
|
-
const mainPort = await getPort({port: this.config.mainServer.port});
|
|
31
|
-
process.env.EE_MAIN_PORT = mainPort;
|
|
32
|
-
this.config.mainServer.port = mainPort;
|
|
33
|
-
|
|
34
|
-
if (this.config.socketServer.enable) {
|
|
35
|
-
const socketPort = await getPort({port: this.config.socketServer.port});
|
|
36
|
-
process.env.EE_SOCKET_PORT = socketPort;
|
|
37
|
-
this.config.socketServer.port = socketPort;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (this.config.httpServer.enable) {
|
|
41
|
-
const httpPort = await getPort({port: this.config.httpServer.port});
|
|
42
|
-
process.env.EE_HTTP_PORT = httpPort;
|
|
43
|
-
this.config.httpServer.port = httpPort;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// 更新db配置
|
|
47
|
-
this.getCoreDB().setItem('config', this.config);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* 启动通信模块
|
|
52
|
-
*/
|
|
53
|
-
async startSocket () {
|
|
54
|
-
const socket = require('./socket/start');
|
|
55
|
-
socket(this);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 创建electron应用
|
|
60
|
-
*/
|
|
61
|
-
async createElectronApp () {
|
|
62
|
-
const self = this;
|
|
63
|
-
|
|
64
|
-
const gotTheLock = app.requestSingleInstanceLock();
|
|
65
|
-
if (!gotTheLock) {
|
|
66
|
-
await this.appQuit();
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
app.on('second-instance', (event) => {
|
|
71
|
-
self.restoreMainWindow();
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
app.whenReady().then(() => {
|
|
75
|
-
self.createWindow();
|
|
76
|
-
app.on('activate', () => {
|
|
77
|
-
self.restoreMainWindow();
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
app.on('window-all-closed', () => {
|
|
82
|
-
if (process.platform !== 'darwin') {
|
|
83
|
-
self.coreLogger.info('[Appliaction] [initialize] window-all-closed quit');
|
|
84
|
-
self.appQuit();
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
app.on('before-quit', () => {
|
|
89
|
-
self.electron.extra.closeWindow = true;
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
if (this.config.hardGpu.enable == false) {
|
|
93
|
-
app.disableHardwareAcceleration();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
await this.electronAppReady();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* 创建应用主窗口
|
|
101
|
-
*/
|
|
102
|
-
async createWindow () {
|
|
103
|
-
const winOptions = this.config.windowsOption;
|
|
104
|
-
this.electron.mainWindow = new BrowserWindow(winOptions);
|
|
105
|
-
let win = this.electron.mainWindow;
|
|
106
|
-
|
|
107
|
-
// 菜单显示/隐藏
|
|
108
|
-
if (this.config.openAppMenu === 'dev-show'
|
|
109
|
-
&& this.config.env == 'prod') {
|
|
110
|
-
Menu.setApplicationMenu(null);
|
|
111
|
-
} else if (this.config.openAppMenu === false) {
|
|
112
|
-
Menu.setApplicationMenu(null);
|
|
113
|
-
} else {
|
|
114
|
-
// nothing
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
this.loadingView(winOptions);
|
|
118
|
-
|
|
119
|
-
await this.windowReady();
|
|
120
|
-
|
|
121
|
-
await this._loderAddons();
|
|
122
|
-
|
|
123
|
-
await this._loderPreload();
|
|
124
|
-
|
|
125
|
-
this.selectAppType();
|
|
126
|
-
|
|
127
|
-
// DevTools
|
|
128
|
-
if (!app.isPackaged && this.config.openDevTools) {
|
|
129
|
-
win.webContents.openDevTools();
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* 还原窗口
|
|
135
|
-
*/
|
|
136
|
-
restoreMainWindow () {
|
|
137
|
-
if (this.electron.mainWindow) {
|
|
138
|
-
if (this.electron.mainWindow.isMinimized()) {
|
|
139
|
-
this.electron.mainWindow.restore();
|
|
140
|
-
}
|
|
141
|
-
this.electron.mainWindow.show()
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* 加载已经实现的功能
|
|
147
|
-
*/
|
|
148
|
-
async loadPreference () {
|
|
149
|
-
const preferences = require('./preferences');
|
|
150
|
-
return await preferences(this);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* 加载loading页面
|
|
155
|
-
*/
|
|
156
|
-
loadingView (winOptions) {
|
|
157
|
-
let currentV = process.versions.electron;
|
|
158
|
-
if (utilsCommon.compareVersion(currentV, '12.2.3') == 1) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
if (!this.config.loadingPage) {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
const self = this;
|
|
165
|
-
const loadingBrowserView = new BrowserView();
|
|
166
|
-
this.electron.mainWindow.setBrowserView(loadingBrowserView);
|
|
167
|
-
loadingBrowserView.setBounds({
|
|
168
|
-
x: 0,
|
|
169
|
-
y: 0,
|
|
170
|
-
width: winOptions.width,
|
|
171
|
-
height: winOptions.height
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// loading html
|
|
175
|
-
const loadingHtml = path.join('file://', this.config.homeDir, 'public', 'html', 'loading.html');
|
|
176
|
-
loadingBrowserView.webContents.loadURL(loadingHtml);
|
|
177
|
-
this.logger.info('loadingHtml:', loadingHtml);
|
|
178
|
-
|
|
179
|
-
this.electron.mainWindow.webContents.on('dom-ready', async (event) => {
|
|
180
|
-
self.electron.mainWindow.removeBrowserView(loadingBrowserView);
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* 应用类型 (远程、html、单页应用)
|
|
186
|
-
*/
|
|
187
|
-
selectAppType () {
|
|
188
|
-
let type = '';
|
|
189
|
-
let url = '';
|
|
190
|
-
|
|
191
|
-
// 远程模式
|
|
192
|
-
const remoteConfig = this.config.remoteUrl;
|
|
193
|
-
if (remoteConfig.enable == true) {
|
|
194
|
-
type = 'remote_web';
|
|
195
|
-
url = remoteConfig.url;
|
|
196
|
-
this.loadMainUrl(type, url);
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const developmentModeConfig = this.config.developmentMode;
|
|
201
|
-
const selectMode = developmentModeConfig.default;
|
|
202
|
-
const modeInfo = developmentModeConfig.mode[selectMode];
|
|
203
|
-
let staticDir = null;
|
|
204
|
-
|
|
205
|
-
// html模式
|
|
206
|
-
if (selectMode == 'html') {
|
|
207
|
-
if (this.config.env !== 'prod') {
|
|
208
|
-
staticDir = path.join(this.config.homeDir, 'frontend', 'dist');
|
|
209
|
-
}
|
|
210
|
-
this.loadLocalWeb('html', staticDir, modeInfo);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// 单页应用
|
|
215
|
-
const protocol = modeInfo.protocol || 'http://';
|
|
216
|
-
url = protocol + modeInfo.hostname + ':' + modeInfo.port;
|
|
217
|
-
if (this.config.env !== 'prod') {
|
|
218
|
-
this.loadMainUrl('spa', url);
|
|
219
|
-
} else {
|
|
220
|
-
this.loadLocalWeb('spa');
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* 加载本地前端资源
|
|
226
|
-
*/
|
|
227
|
-
loadLocalWeb (mode, staticDir, hostInfo) {
|
|
228
|
-
const self = this;
|
|
229
|
-
if (!staticDir) {
|
|
230
|
-
staticDir = path.join(this.config.homeDir, 'public', 'dist')
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const koaApp = new Koa();
|
|
234
|
-
koaApp.use(koaServe(staticDir));
|
|
235
|
-
|
|
236
|
-
const mainServer = this.config.mainServer;
|
|
237
|
-
let url = mainServer.protocol + mainServer.host + ':' + mainServer.port;
|
|
238
|
-
if (mode == 'html') {
|
|
239
|
-
url += '/' + hostInfo.indexPage;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const isHttps = mainServer.protocol == 'https://' ? true : false;
|
|
243
|
-
if (isHttps) {
|
|
244
|
-
const keyFile = path.join(this.config.homeDir, mainServer.ssl.key);
|
|
245
|
-
const certFile = path.join(this.config.homeDir, mainServer.ssl.cert);
|
|
246
|
-
assert(fs.existsSync(keyFile), 'ssl key file is required');
|
|
247
|
-
assert(fs.existsSync(certFile), 'ssl cert file is required');
|
|
248
|
-
|
|
249
|
-
const sslOpt = {
|
|
250
|
-
key: fs.readFileSync(keyFile),
|
|
251
|
-
cert: fs.readFileSync(certFile)
|
|
252
|
-
};
|
|
253
|
-
https.createServer(sslOpt, koaApp.callback()).listen(mainServer.port, (err) => {
|
|
254
|
-
if (err) {
|
|
255
|
-
self.coreLogger.info('[error] ', err);
|
|
256
|
-
return
|
|
257
|
-
}
|
|
258
|
-
self.loadMainUrl(mode, url);
|
|
259
|
-
});
|
|
260
|
-
} else {
|
|
261
|
-
koaApp.listen(mainServer.port, () => {
|
|
262
|
-
self.loadMainUrl(mode, url);
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* 主页面
|
|
269
|
-
*/
|
|
270
|
-
loadMainUrl (type, url) {
|
|
271
|
-
const mainServer = this.config.mainServer;
|
|
272
|
-
this.logger.info('[ee-core:main] Env: %s, Type: %s', this.config.env, type);
|
|
273
|
-
this.logger.info('[ee-core:main] App running at: %s', url);
|
|
274
|
-
this.electron.mainWindow.loadURL(url, mainServer.options);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* electron app退出
|
|
279
|
-
*/
|
|
280
|
-
async appQuit () {
|
|
281
|
-
await this.beforeClose();
|
|
282
|
-
app.quit();
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* 加载插件
|
|
287
|
-
*/
|
|
288
|
-
async _loderAddons () {
|
|
289
|
-
this.loader.loadAddons();
|
|
290
|
-
|
|
291
|
-
// 注册主窗口Contents id
|
|
292
|
-
const addonsCfg = this.config.addons;
|
|
293
|
-
if (addonsCfg.window.enable) {
|
|
294
|
-
const win = this.electron.mainWindow;
|
|
295
|
-
const addonWindow = this.addon.window;
|
|
296
|
-
addonWindow.registerWCid('main', win.webContents.id);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* 预加载模块
|
|
302
|
-
*/
|
|
303
|
-
async _loderPreload () {
|
|
304
|
-
let filepath = this.loader.resolveModule(path.join(this.config.baseDir, 'preload', 'index'));
|
|
305
|
-
if (!filepath) return;
|
|
306
|
-
const fileObj = this.loader.loadFile(filepath);
|
|
307
|
-
if (is.function(fileObj) && !is.generatorFunction(fileObj) && !is.asyncFunction(fileObj)) {
|
|
308
|
-
fileObj();
|
|
309
|
-
} else if (is.asyncFunction(fileObj)) {
|
|
310
|
-
await fileObj();
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* 序列化参数
|
|
316
|
-
*/
|
|
317
|
-
stringify(obj, ignore) {
|
|
318
|
-
const result = {};
|
|
319
|
-
Object.keys(obj).forEach(key => {
|
|
320
|
-
if (!ignore.includes(key)) {
|
|
321
|
-
result[key] = obj[key];
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
return JSON.stringify(result);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* 捕获异常
|
|
329
|
-
*/
|
|
330
|
-
async catchLog () {
|
|
331
|
-
const self = this;
|
|
332
|
-
|
|
333
|
-
process.on('uncaughtException', function(err) {
|
|
334
|
-
self.logger.error(err);
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* electron app已经准备好,主窗口还未创建
|
|
340
|
-
*/
|
|
341
|
-
async electronAppReady () {
|
|
342
|
-
// do some things
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* 主应用窗口已经创建
|
|
347
|
-
*/
|
|
348
|
-
async windowReady () {
|
|
349
|
-
// do some things
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* app关闭之前
|
|
354
|
-
*/
|
|
355
|
-
async beforeClose () {
|
|
356
|
-
// do some things
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const getPort = require('get-port');
|
|
5
|
+
const {app, BrowserWindow, BrowserView, Menu} = require('electron');
|
|
6
|
+
const BaseApp = require('./baseApp');
|
|
7
|
+
const is = require('is-type-of');
|
|
8
|
+
const Koa = require('koa');
|
|
9
|
+
const koaServe = require('koa-static');
|
|
10
|
+
const https = require('https');
|
|
11
|
+
const utilsCommon = require('../utils/common');
|
|
12
|
+
|
|
13
|
+
class EeApp extends BaseApp {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
super(options);
|
|
16
|
+
|
|
17
|
+
this.electron = {
|
|
18
|
+
mainWindow: null,
|
|
19
|
+
tray: null,
|
|
20
|
+
extra: {
|
|
21
|
+
closeWindow: false,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 生成端口
|
|
28
|
+
*/
|
|
29
|
+
async createPorts () {
|
|
30
|
+
const mainPort = await getPort({port: this.config.mainServer.port});
|
|
31
|
+
process.env.EE_MAIN_PORT = mainPort;
|
|
32
|
+
this.config.mainServer.port = mainPort;
|
|
33
|
+
|
|
34
|
+
if (this.config.socketServer.enable) {
|
|
35
|
+
const socketPort = await getPort({port: this.config.socketServer.port});
|
|
36
|
+
process.env.EE_SOCKET_PORT = socketPort;
|
|
37
|
+
this.config.socketServer.port = socketPort;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (this.config.httpServer.enable) {
|
|
41
|
+
const httpPort = await getPort({port: this.config.httpServer.port});
|
|
42
|
+
process.env.EE_HTTP_PORT = httpPort;
|
|
43
|
+
this.config.httpServer.port = httpPort;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 更新db配置
|
|
47
|
+
this.getCoreDB().setItem('config', this.config);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 启动通信模块
|
|
52
|
+
*/
|
|
53
|
+
async startSocket () {
|
|
54
|
+
const socket = require('./socket/start');
|
|
55
|
+
socket(this);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 创建electron应用
|
|
60
|
+
*/
|
|
61
|
+
async createElectronApp () {
|
|
62
|
+
const self = this;
|
|
63
|
+
|
|
64
|
+
const gotTheLock = app.requestSingleInstanceLock();
|
|
65
|
+
if (!gotTheLock) {
|
|
66
|
+
await this.appQuit();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
app.on('second-instance', (event) => {
|
|
71
|
+
self.restoreMainWindow();
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
app.whenReady().then(() => {
|
|
75
|
+
self.createWindow();
|
|
76
|
+
app.on('activate', () => {
|
|
77
|
+
self.restoreMainWindow();
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
app.on('window-all-closed', () => {
|
|
82
|
+
if (process.platform !== 'darwin') {
|
|
83
|
+
self.coreLogger.info('[Appliaction] [initialize] window-all-closed quit');
|
|
84
|
+
self.appQuit();
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
app.on('before-quit', () => {
|
|
89
|
+
self.electron.extra.closeWindow = true;
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
if (this.config.hardGpu.enable == false) {
|
|
93
|
+
app.disableHardwareAcceleration();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
await this.electronAppReady();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 创建应用主窗口
|
|
101
|
+
*/
|
|
102
|
+
async createWindow () {
|
|
103
|
+
const winOptions = this.config.windowsOption;
|
|
104
|
+
this.electron.mainWindow = new BrowserWindow(winOptions);
|
|
105
|
+
let win = this.electron.mainWindow;
|
|
106
|
+
|
|
107
|
+
// 菜单显示/隐藏
|
|
108
|
+
if (this.config.openAppMenu === 'dev-show'
|
|
109
|
+
&& this.config.env == 'prod') {
|
|
110
|
+
Menu.setApplicationMenu(null);
|
|
111
|
+
} else if (this.config.openAppMenu === false) {
|
|
112
|
+
Menu.setApplicationMenu(null);
|
|
113
|
+
} else {
|
|
114
|
+
// nothing
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
this.loadingView(winOptions);
|
|
118
|
+
|
|
119
|
+
await this.windowReady();
|
|
120
|
+
|
|
121
|
+
await this._loderAddons();
|
|
122
|
+
|
|
123
|
+
await this._loderPreload();
|
|
124
|
+
|
|
125
|
+
this.selectAppType();
|
|
126
|
+
|
|
127
|
+
// DevTools
|
|
128
|
+
if (!app.isPackaged && this.config.openDevTools) {
|
|
129
|
+
win.webContents.openDevTools();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 还原窗口
|
|
135
|
+
*/
|
|
136
|
+
restoreMainWindow () {
|
|
137
|
+
if (this.electron.mainWindow) {
|
|
138
|
+
if (this.electron.mainWindow.isMinimized()) {
|
|
139
|
+
this.electron.mainWindow.restore();
|
|
140
|
+
}
|
|
141
|
+
this.electron.mainWindow.show()
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 加载已经实现的功能
|
|
147
|
+
*/
|
|
148
|
+
async loadPreference () {
|
|
149
|
+
const preferences = require('./preferences');
|
|
150
|
+
return await preferences(this);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* 加载loading页面
|
|
155
|
+
*/
|
|
156
|
+
loadingView (winOptions) {
|
|
157
|
+
let currentV = process.versions.electron;
|
|
158
|
+
if (utilsCommon.compareVersion(currentV, '12.2.3') == 1) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (!this.config.loadingPage) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const self = this;
|
|
165
|
+
const loadingBrowserView = new BrowserView();
|
|
166
|
+
this.electron.mainWindow.setBrowserView(loadingBrowserView);
|
|
167
|
+
loadingBrowserView.setBounds({
|
|
168
|
+
x: 0,
|
|
169
|
+
y: 0,
|
|
170
|
+
width: winOptions.width,
|
|
171
|
+
height: winOptions.height
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// loading html
|
|
175
|
+
const loadingHtml = path.join('file://', this.config.homeDir, 'public', 'html', 'loading.html');
|
|
176
|
+
loadingBrowserView.webContents.loadURL(loadingHtml);
|
|
177
|
+
this.logger.info('loadingHtml:', loadingHtml);
|
|
178
|
+
|
|
179
|
+
this.electron.mainWindow.webContents.on('dom-ready', async (event) => {
|
|
180
|
+
self.electron.mainWindow.removeBrowserView(loadingBrowserView);
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* 应用类型 (远程、html、单页应用)
|
|
186
|
+
*/
|
|
187
|
+
selectAppType () {
|
|
188
|
+
let type = '';
|
|
189
|
+
let url = '';
|
|
190
|
+
|
|
191
|
+
// 远程模式
|
|
192
|
+
const remoteConfig = this.config.remoteUrl;
|
|
193
|
+
if (remoteConfig.enable == true) {
|
|
194
|
+
type = 'remote_web';
|
|
195
|
+
url = remoteConfig.url;
|
|
196
|
+
this.loadMainUrl(type, url);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const developmentModeConfig = this.config.developmentMode;
|
|
201
|
+
const selectMode = developmentModeConfig.default;
|
|
202
|
+
const modeInfo = developmentModeConfig.mode[selectMode];
|
|
203
|
+
let staticDir = null;
|
|
204
|
+
|
|
205
|
+
// html模式
|
|
206
|
+
if (selectMode == 'html') {
|
|
207
|
+
if (this.config.env !== 'prod') {
|
|
208
|
+
staticDir = path.join(this.config.homeDir, 'frontend', 'dist');
|
|
209
|
+
}
|
|
210
|
+
this.loadLocalWeb('html', staticDir, modeInfo);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// 单页应用
|
|
215
|
+
const protocol = modeInfo.protocol || 'http://';
|
|
216
|
+
url = protocol + modeInfo.hostname + ':' + modeInfo.port;
|
|
217
|
+
if (this.config.env !== 'prod') {
|
|
218
|
+
this.loadMainUrl('spa', url);
|
|
219
|
+
} else {
|
|
220
|
+
this.loadLocalWeb('spa');
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* 加载本地前端资源
|
|
226
|
+
*/
|
|
227
|
+
loadLocalWeb (mode, staticDir, hostInfo) {
|
|
228
|
+
const self = this;
|
|
229
|
+
if (!staticDir) {
|
|
230
|
+
staticDir = path.join(this.config.homeDir, 'public', 'dist')
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const koaApp = new Koa();
|
|
234
|
+
koaApp.use(koaServe(staticDir));
|
|
235
|
+
|
|
236
|
+
const mainServer = this.config.mainServer;
|
|
237
|
+
let url = mainServer.protocol + mainServer.host + ':' + mainServer.port;
|
|
238
|
+
if (mode == 'html') {
|
|
239
|
+
url += '/' + hostInfo.indexPage;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const isHttps = mainServer.protocol == 'https://' ? true : false;
|
|
243
|
+
if (isHttps) {
|
|
244
|
+
const keyFile = path.join(this.config.homeDir, mainServer.ssl.key);
|
|
245
|
+
const certFile = path.join(this.config.homeDir, mainServer.ssl.cert);
|
|
246
|
+
assert(fs.existsSync(keyFile), 'ssl key file is required');
|
|
247
|
+
assert(fs.existsSync(certFile), 'ssl cert file is required');
|
|
248
|
+
|
|
249
|
+
const sslOpt = {
|
|
250
|
+
key: fs.readFileSync(keyFile),
|
|
251
|
+
cert: fs.readFileSync(certFile)
|
|
252
|
+
};
|
|
253
|
+
https.createServer(sslOpt, koaApp.callback()).listen(mainServer.port, (err) => {
|
|
254
|
+
if (err) {
|
|
255
|
+
self.coreLogger.info('[error] ', err);
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
self.loadMainUrl(mode, url);
|
|
259
|
+
});
|
|
260
|
+
} else {
|
|
261
|
+
koaApp.listen(mainServer.port, () => {
|
|
262
|
+
self.loadMainUrl(mode, url);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* 主页面
|
|
269
|
+
*/
|
|
270
|
+
loadMainUrl (type, url) {
|
|
271
|
+
const mainServer = this.config.mainServer;
|
|
272
|
+
this.logger.info('[ee-core:main] Env: %s, Type: %s', this.config.env, type);
|
|
273
|
+
this.logger.info('[ee-core:main] App running at: %s', url);
|
|
274
|
+
this.electron.mainWindow.loadURL(url, mainServer.options);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* electron app退出
|
|
279
|
+
*/
|
|
280
|
+
async appQuit () {
|
|
281
|
+
await this.beforeClose();
|
|
282
|
+
app.quit();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* 加载插件
|
|
287
|
+
*/
|
|
288
|
+
async _loderAddons () {
|
|
289
|
+
this.loader.loadAddons();
|
|
290
|
+
|
|
291
|
+
// 注册主窗口Contents id
|
|
292
|
+
const addonsCfg = this.config.addons;
|
|
293
|
+
if (addonsCfg.window.enable) {
|
|
294
|
+
const win = this.electron.mainWindow;
|
|
295
|
+
const addonWindow = this.addon.window;
|
|
296
|
+
addonWindow.registerWCid('main', win.webContents.id);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* 预加载模块
|
|
302
|
+
*/
|
|
303
|
+
async _loderPreload () {
|
|
304
|
+
let filepath = this.loader.resolveModule(path.join(this.config.baseDir, 'preload', 'index'));
|
|
305
|
+
if (!filepath) return;
|
|
306
|
+
const fileObj = this.loader.loadFile(filepath);
|
|
307
|
+
if (is.function(fileObj) && !is.generatorFunction(fileObj) && !is.asyncFunction(fileObj)) {
|
|
308
|
+
fileObj();
|
|
309
|
+
} else if (is.asyncFunction(fileObj)) {
|
|
310
|
+
await fileObj();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* 序列化参数
|
|
316
|
+
*/
|
|
317
|
+
stringify(obj, ignore) {
|
|
318
|
+
const result = {};
|
|
319
|
+
Object.keys(obj).forEach(key => {
|
|
320
|
+
if (!ignore.includes(key)) {
|
|
321
|
+
result[key] = obj[key];
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
return JSON.stringify(result);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* 捕获异常
|
|
329
|
+
*/
|
|
330
|
+
async catchLog () {
|
|
331
|
+
const self = this;
|
|
332
|
+
|
|
333
|
+
process.on('uncaughtException', function(err) {
|
|
334
|
+
self.logger.error(err);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* electron app已经准备好,主窗口还未创建
|
|
340
|
+
*/
|
|
341
|
+
async electronAppReady () {
|
|
342
|
+
// do some things
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* 主应用窗口已经创建
|
|
347
|
+
*/
|
|
348
|
+
async windowReady () {
|
|
349
|
+
// do some things
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* app关闭之前
|
|
354
|
+
*/
|
|
355
|
+
async beforeClose () {
|
|
356
|
+
// do some things
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
360
|
module.exports = EeApp;
|