mirror of
https://gitee.com/dromara/electron-egg.git
synced 2026-05-14 19:52:10 +08:00
feat: accept ts
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
"description": "A fast, desktop software development framework",
|
||||
"main": "./electron/main.js",
|
||||
"scripts": {
|
||||
"vite-test": "tsc && vite build",
|
||||
"dev": "ee-bin dev",
|
||||
"dev-frontend": "ee-bin dev --serve=frontend",
|
||||
"dev-electron": "ee-bin dev --serve=electron",
|
||||
@@ -53,11 +54,16 @@
|
||||
"license": "Apache",
|
||||
"devDependencies": {
|
||||
"@electron/rebuild": "^3.7.1",
|
||||
"@types/electron": "^1.4.38",
|
||||
"@types/node": "^22.10.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"debug": "^4.4.0",
|
||||
"ee-bin": "file:.yalc/ee-bin",
|
||||
"electron": "^31.7.6",
|
||||
"electron-builder": "^25.1.8"
|
||||
"electron-builder": "^25.1.8",
|
||||
"typescript": "^5.4.2",
|
||||
"vite": "^6.0.6",
|
||||
"vite-plugin-dts": "^4.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.9",
|
||||
|
||||
@@ -1,12 +1,88 @@
|
||||
'use strict';
|
||||
import path from 'path';
|
||||
import { getBaseDir } from 'ee-core/ps';
|
||||
|
||||
const path = require('path');
|
||||
const { getBaseDir } = require('ee-core/ps');
|
||||
interface WindowOption {
|
||||
title: string;
|
||||
width: number;
|
||||
height: number;
|
||||
minWidth: number;
|
||||
minHeight: number;
|
||||
webPreferences: {
|
||||
contextIsolation: boolean;
|
||||
nodeIntegration: boolean;
|
||||
};
|
||||
frame: boolean;
|
||||
show: boolean;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认配置
|
||||
*/
|
||||
module.exports = () => {
|
||||
interface Logger {
|
||||
level: 'INFO' | 'DEBUG' | 'WARN' | 'ERROR';
|
||||
outputJSON: boolean;
|
||||
appLogName: string;
|
||||
coreLogName: string;
|
||||
errorLogName: string;
|
||||
}
|
||||
|
||||
interface Remote {
|
||||
enable: boolean;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface SocketServer {
|
||||
enable: boolean;
|
||||
port: number;
|
||||
path: string;
|
||||
connectTimeout: number;
|
||||
pingTimeout: number;
|
||||
pingInterval: number;
|
||||
maxHttpBufferSize: number;
|
||||
transports: ('polling' | 'websocket')[];
|
||||
cors: {
|
||||
origin: boolean | string | ((origin: string, callback: (err: any, allow: boolean) => void) => void);
|
||||
};
|
||||
channel: string;
|
||||
}
|
||||
|
||||
interface HttpServer {
|
||||
enable: boolean;
|
||||
https: {
|
||||
enable: boolean;
|
||||
key: string;
|
||||
cert: string;
|
||||
};
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
interface MainServer {
|
||||
indexPath: string;
|
||||
}
|
||||
|
||||
interface Customize {
|
||||
tray: {
|
||||
title: string;
|
||||
icon: string;
|
||||
};
|
||||
awaken: {
|
||||
protocol: string;
|
||||
args: any[];
|
||||
};
|
||||
}
|
||||
|
||||
interface AppConfig {
|
||||
openDevTools: boolean;
|
||||
singleLock: boolean;
|
||||
windowsOption: WindowOption;
|
||||
logger: Logger;
|
||||
remote: Remote;
|
||||
socketServer: SocketServer;
|
||||
httpServer: HttpServer;
|
||||
mainServer: MainServer;
|
||||
customize: Customize;
|
||||
}
|
||||
|
||||
const config: () => AppConfig = () => {
|
||||
return {
|
||||
openDevTools: false,
|
||||
singleLock: true,
|
||||
@@ -17,10 +93,8 @@ module.exports = () => {
|
||||
minWidth: 400,
|
||||
minHeight: 300,
|
||||
webPreferences: {
|
||||
//webSecurity: false,
|
||||
contextIsolation: false, // false -> 可在渲染进程中使用electron的api,true->需要bridge.js(contextBridge)
|
||||
contextIsolation: false,
|
||||
nodeIntegration: true,
|
||||
//preload: path.join(getElectronDir(), 'preload', 'bridge.js'),
|
||||
},
|
||||
frame: true,
|
||||
show: true,
|
||||
@@ -31,11 +105,11 @@ module.exports = () => {
|
||||
outputJSON: false,
|
||||
appLogName: 'ee.log',
|
||||
coreLogName: 'ee-core.log',
|
||||
errorLogName: 'ee-error.log'
|
||||
errorLogName: 'ee-error.log',
|
||||
},
|
||||
remote: {
|
||||
enable: false,
|
||||
url: 'http://electron-egg.kaka996.com/'
|
||||
url: 'http://electron-egg.kaka996.com/',
|
||||
},
|
||||
socketServer: {
|
||||
enable: false,
|
||||
@@ -49,14 +123,14 @@ module.exports = () => {
|
||||
cors: {
|
||||
origin: true,
|
||||
},
|
||||
channel: 'c1'
|
||||
channel: 'c1',
|
||||
},
|
||||
httpServer: {
|
||||
enable: false,
|
||||
https: {
|
||||
enable: false,
|
||||
enable: false,
|
||||
key: '/public/ssl/localhost+1.key',
|
||||
cert: '/public/ssl/localhost+1.pem'
|
||||
cert: '/public/ssl/localhost+1.pem',
|
||||
},
|
||||
host: '127.0.0.1',
|
||||
port: 7071,
|
||||
@@ -67,12 +141,14 @@ module.exports = () => {
|
||||
customize: {
|
||||
tray: {
|
||||
title: 'EE程序',
|
||||
icon: '/public/images/tray.png'
|
||||
icon: '/public/images/tray.png',
|
||||
},
|
||||
awaken: {
|
||||
protocol: 'ee',
|
||||
args: []
|
||||
}
|
||||
args: [],
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,9 +1,17 @@
|
||||
'use strict';
|
||||
interface OpenDevTools {
|
||||
mode: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Development environment configuration, coverage config.default.js
|
||||
*/
|
||||
module.exports = () => {
|
||||
interface Jobs {
|
||||
messageLog: boolean;
|
||||
}
|
||||
|
||||
interface AppConfig {
|
||||
openDevTools: OpenDevTools;
|
||||
jobs: Jobs;
|
||||
}
|
||||
|
||||
const config: () => AppConfig = () => {
|
||||
return {
|
||||
openDevTools: {
|
||||
mode: 'bottom'
|
||||
@@ -13,3 +21,5 @@ module.exports = () => {
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,10 +1,11 @@
|
||||
'use strict';
|
||||
interface AppConfig {
|
||||
openDevTools: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* coverage config.default.js
|
||||
*/
|
||||
module.exports = () => {
|
||||
const config: () => AppConfig = () => {
|
||||
return {
|
||||
openDevTools: false,
|
||||
};
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,18 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* school
|
||||
* @class
|
||||
* SchoolController class
|
||||
*/
|
||||
class SchoolController {
|
||||
|
||||
/**
|
||||
* test
|
||||
* Test method
|
||||
*/
|
||||
async test () {
|
||||
async test(): Promise<string> {
|
||||
return 'hello electron-egg';
|
||||
}
|
||||
}
|
||||
|
||||
SchoolController.toString = () => '[class SchoolController]';
|
||||
module.exports = SchoolController;
|
||||
export default SchoolController;
|
||||
@@ -1,18 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* tool
|
||||
* @class
|
||||
* ToolController class
|
||||
*/
|
||||
class ToolController {
|
||||
|
||||
/**
|
||||
* test
|
||||
* Test method
|
||||
*/
|
||||
async test () {
|
||||
async test(): Promise<string> {
|
||||
return 'hello electron-egg';
|
||||
}
|
||||
}
|
||||
|
||||
ToolController.toString = () => '[class ToolController]';
|
||||
module.exports = ToolController;
|
||||
export default ToolController;
|
||||
@@ -1,18 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* user
|
||||
* @class
|
||||
* UserController class
|
||||
*/
|
||||
class UserController {
|
||||
|
||||
/**
|
||||
* test
|
||||
* Test method
|
||||
*/
|
||||
async test () {
|
||||
async test(): Promise<string> {
|
||||
return 'hello electron-egg';
|
||||
}
|
||||
}
|
||||
|
||||
UserController.toString = () => '[class UserController]';
|
||||
module.exports = UserController;
|
||||
export default UserController;
|
||||
@@ -1,65 +1,61 @@
|
||||
'use strict';
|
||||
|
||||
const { crossService } = require('../service/cross');
|
||||
import { crossService } from '../service/cross';
|
||||
|
||||
/**
|
||||
* Cross
|
||||
* @class
|
||||
* CrossController class
|
||||
*/
|
||||
class CrossController {
|
||||
|
||||
/**
|
||||
* View process service information
|
||||
*/
|
||||
info() {
|
||||
info(): string {
|
||||
crossService.info();
|
||||
return 'hello electron-egg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service url
|
||||
*/
|
||||
async getUrl(args) {
|
||||
*/
|
||||
async getUrl(args: { name: string }): Promise<string> {
|
||||
const { name } = args;
|
||||
const serverUrl = crossService.getUrl(name);
|
||||
return serverUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* kill service
|
||||
* Kill service
|
||||
* By default (modifiable), killing the process will exit the electron application.
|
||||
*/
|
||||
async killServer(args) {
|
||||
*/
|
||||
async killServer(args: { type: string; name: string }): Promise<void> {
|
||||
const { type, name } = args;
|
||||
crossService.killServer(type, name);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* create service
|
||||
*/
|
||||
async createServer(args) {
|
||||
* Create service
|
||||
*/
|
||||
async createServer(args: { program: string }): Promise<void> {
|
||||
const { program } = args;
|
||||
if (program == 'go') {
|
||||
if (program === 'go') {
|
||||
crossService.createGoServer();
|
||||
} else if (program == 'java') {
|
||||
} else if (program === 'java') {
|
||||
crossService.createJavaServer();
|
||||
} else if (program == 'python') {
|
||||
} else if (program === 'python') {
|
||||
crossService.createPythonServer();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the api for the cross service
|
||||
*/
|
||||
async requestApi(args) {
|
||||
const { name, urlPath, params} = args;
|
||||
async requestApi(args: { name: string; urlPath: string; params: any }): Promise<any> {
|
||||
const { name, urlPath, params } = args;
|
||||
const data = await crossService.requestApi(name, urlPath, params);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置类的toString方法,虽然在TypeScript中不常见
|
||||
CrossController.toString = () => '[class CrossController]';
|
||||
module.exports = CrossController;
|
||||
|
||||
// 默认导出类
|
||||
export default CrossController;
|
||||
@@ -1,66 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
const { dialog } = require('electron');
|
||||
const _ = require('lodash');
|
||||
const { getMainWindow } = require('ee-core/electron/window');
|
||||
import { dialog } from 'electron';
|
||||
import _ from 'lodash';
|
||||
import { getMainWindow } from 'ee-core/electron/window';
|
||||
|
||||
/**
|
||||
* effect - demo
|
||||
* @class
|
||||
* EffectController class
|
||||
*/
|
||||
class EffectController {
|
||||
|
||||
/**
|
||||
* select file
|
||||
* Select file
|
||||
*/
|
||||
selectFile() {
|
||||
selectFile(): string | null {
|
||||
const filePaths = dialog.showOpenDialogSync({
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
if (_.isEmpty(filePaths)) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
return filePaths[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* login window
|
||||
* Login window
|
||||
*/
|
||||
loginWindow(args) {
|
||||
loginWindow(args: { width?: number; height?: number }): void {
|
||||
const { width, height } = args;
|
||||
const win = getMainWindow();
|
||||
|
||||
|
||||
const size = {
|
||||
width: width || 400,
|
||||
height: height || 300
|
||||
}
|
||||
};
|
||||
win.setSize(size.width, size.height);
|
||||
win.setResizable(true);
|
||||
win.center();
|
||||
win.show();
|
||||
win.focus();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* restore window
|
||||
* Restore window
|
||||
*/
|
||||
restoreWindow(args) {
|
||||
restoreWindow(args: { width?: number; height?: number }): void {
|
||||
const { width, height } = args;
|
||||
const win = getMainWindow();
|
||||
|
||||
const size = {
|
||||
width: width || 980,
|
||||
height: height || 650
|
||||
}
|
||||
};
|
||||
win.setSize(size.width, size.height);
|
||||
win.setResizable(true);
|
||||
win.center();
|
||||
win.show();
|
||||
win.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置类的toString方法,虽然在TypeScript中不常见
|
||||
EffectController.toString = () => '[class EffectController]';
|
||||
module.exports = EffectController;
|
||||
|
||||
// 默认导出类
|
||||
export default EffectController;
|
||||
@@ -1,18 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* example
|
||||
* @class
|
||||
* ExampleController class
|
||||
*/
|
||||
class ExampleController {
|
||||
|
||||
/**
|
||||
* test
|
||||
* Test method
|
||||
*/
|
||||
async test () {
|
||||
async test(): Promise<string> {
|
||||
return 'hello electron-egg';
|
||||
}
|
||||
}
|
||||
|
||||
// 设置类的toString方法,虽然在TypeScript中不常见
|
||||
ExampleController.toString = () => '[class ExampleController]';
|
||||
module.exports = ExampleController;
|
||||
|
||||
// 默认导出类
|
||||
export default ExampleController;
|
||||
@@ -1,15 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const dayjs = require('dayjs');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { exec } = require('child_process');
|
||||
const { app: electronApp, shell } = require('electron');
|
||||
const { getExtraResourcesDir } = require('ee-core/ps');
|
||||
const { logger } = require('ee-core/log');
|
||||
const { getConfig } = require('ee-core/config');
|
||||
const { frameworkService } = require('../service/framework');
|
||||
const { sqlitedbService } = require('../service/database/sqlitedb');
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { exec } from 'child_process';
|
||||
import { app as electronApp, shell } from 'electron';
|
||||
import { getExtraResourcesDir } from 'ee-core/ps';
|
||||
import { logger } from 'ee-core/log';
|
||||
import { getConfig } from 'ee-core/config';
|
||||
import { frameworkService } from '../service/framework';
|
||||
import { sqlitedbService } from '../service/database/sqlitedb';
|
||||
|
||||
/**
|
||||
* framework - demo
|
||||
@@ -250,4 +247,4 @@ class FrameworkController {
|
||||
}
|
||||
|
||||
FrameworkController.toString = () => '[class FrameworkController]';
|
||||
module.exports = FrameworkController;
|
||||
export default FrameworkController;
|
||||
@@ -1,76 +1,67 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const {
|
||||
app: electronApp, dialog, shell, Notification,
|
||||
} = require('electron');
|
||||
const { windowService } = require('../service/os/window');
|
||||
import _ from 'lodash';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {
|
||||
app as electronApp, dialog, shell, Notification,
|
||||
} from 'electron';
|
||||
import { windowService } from '../service/os/window';
|
||||
|
||||
/**
|
||||
* example
|
||||
* @class
|
||||
* OsController class
|
||||
*/
|
||||
class OsController {
|
||||
|
||||
/**
|
||||
* All methods receive two parameters
|
||||
* @param args Parameters transmitted by the frontend
|
||||
* @param event - Event are only available during IPC communication. For details, please refer to the controller documentation
|
||||
*/
|
||||
|
||||
/**
|
||||
* Message prompt dialog box
|
||||
*/
|
||||
messageShow() {
|
||||
messageShow(): string {
|
||||
dialog.showMessageBoxSync({
|
||||
type: 'info', // "none", "info", "error", "question" 或者 "warning"
|
||||
type: 'info',
|
||||
title: 'Custom Title',
|
||||
message: 'Customize message content',
|
||||
detail: 'Other additional information'
|
||||
})
|
||||
|
||||
detail: 'Other additional information',
|
||||
});
|
||||
|
||||
return 'Opened the message box';
|
||||
}
|
||||
|
||||
/**
|
||||
* Message prompt and confirmation dialog box
|
||||
*/
|
||||
messageShowConfirm() {
|
||||
messageShowConfirm(): string {
|
||||
const res = dialog.showMessageBoxSync({
|
||||
type: 'info',
|
||||
title: 'Custom Title',
|
||||
message: 'Customize message content',
|
||||
detail: 'Other additional information',
|
||||
cancelId: 1, // Index of buttons used to cancel dialog boxes
|
||||
defaultId: 0, // Set default selected button
|
||||
buttons: ['confirm', 'cancel'],
|
||||
})
|
||||
cancelId: 1,
|
||||
defaultId: 0,
|
||||
buttons: ['confirm', 'cancel'],
|
||||
});
|
||||
let data = (res === 0) ? 'click the confirm button' : 'click the cancel button';
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select Directory
|
||||
*/
|
||||
selectFolder() {
|
||||
selectFolder(): string | null {
|
||||
const filePaths = dialog.showOpenDialogSync({
|
||||
properties: ['openDirectory', 'createDirectory']
|
||||
});
|
||||
|
||||
if (_.isEmpty(filePaths)) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
return filePaths[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* open directory
|
||||
* Open directory
|
||||
*/
|
||||
openDirectory(args) {
|
||||
openDirectory(args: { id: string }): boolean {
|
||||
const { id } = args;
|
||||
if (!id) {
|
||||
return false;
|
||||
@@ -89,7 +80,7 @@ class OsController {
|
||||
/**
|
||||
* Select Picture
|
||||
*/
|
||||
selectPic() {
|
||||
selectPic(): string | null {
|
||||
const filePaths = dialog.showOpenDialogSync({
|
||||
title: 'select pic',
|
||||
properties: ['openFile'],
|
||||
@@ -98,31 +89,31 @@ class OsController {
|
||||
]
|
||||
});
|
||||
if (_.isEmpty(filePaths)) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(filePaths[0]);
|
||||
const pic = 'data:image/jpeg;base64,' + data.toString('base64');
|
||||
const pic = 'data:image/jpeg;base64,' + data.toString('base64');
|
||||
return pic;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a new window
|
||||
*/
|
||||
createWindow(args) {
|
||||
createWindow(args: any): string {
|
||||
const wcid = windowService.createWindow(args);
|
||||
return wcid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Window contents id
|
||||
*/
|
||||
getWCid(args) {
|
||||
getWCid(args: any): string | null {
|
||||
const wcid = windowService.getWCid(args);
|
||||
return wcid;
|
||||
}
|
||||
@@ -130,47 +121,46 @@ class OsController {
|
||||
/**
|
||||
* Realize communication between two windows through the transfer of the main process
|
||||
*/
|
||||
window1ToWindow2(args, event) {
|
||||
window1ToWindow2(args: any, event: any): void {
|
||||
windowService.communicate(args, event);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Realize communication between two windows through the transfer of the main process
|
||||
*/
|
||||
window2ToWindow1(args, event) {
|
||||
window2ToWindow1(args: any, event: any): void {
|
||||
windowService.communicate(args, event);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create system notifications
|
||||
*/
|
||||
sendNotification(args, event) {
|
||||
const { title, subtitle, body, silent} = args;
|
||||
|
||||
sendNotification(args: { title?: string; subtitle?: string; body?: string; silent?: boolean }, event: any): boolean {
|
||||
if (!Notification.isSupported()) {
|
||||
return '当前系统不支持通知';
|
||||
return false;
|
||||
}
|
||||
|
||||
let options = {};
|
||||
if (!_.isEmpty(title)) {
|
||||
options.title = title;
|
||||
if (!_.isEmpty(args.title)) {
|
||||
options.title = args.title;
|
||||
}
|
||||
if (!_.isEmpty(subtitle)) {
|
||||
options.subtitle = subtitle;
|
||||
if (!_.isEmpty(args.subtitle)) {
|
||||
options.subtitle = args.subtitle;
|
||||
}
|
||||
if (!_.isEmpty(body)) {
|
||||
options.body = body;
|
||||
if (!_.isEmpty(args.body)) {
|
||||
options.body = args.body;
|
||||
}
|
||||
if (!_.isEmpty(silent)) {
|
||||
options.silent = silent;
|
||||
if (!_.isEmpty(args.silent)) {
|
||||
options.silent = args.silent;
|
||||
}
|
||||
windowService.createNotification(options, event);
|
||||
|
||||
return true
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置类的toString方法,虽然在TypeScript中不常见
|
||||
OsController.toString = () => '[class OsController]';
|
||||
module.exports = OsController;
|
||||
|
||||
// 默认导出类
|
||||
export default OsController;
|
||||
@@ -1,11 +1,7 @@
|
||||
'use strict';
|
||||
import { logger } from 'ee-core/log';
|
||||
|
||||
const { logger } = require('ee-core/log');
|
||||
|
||||
function welcome() {
|
||||
function welcome(): void {
|
||||
logger.info('[child-process] [jobs/example/hello] welcome ! ');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
welcome
|
||||
};
|
||||
export { welcome };
|
||||
@@ -1,18 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const { logger } = require('ee-core/log');
|
||||
const { isChildJob, exit } = require('ee-core/ps');
|
||||
const { childMessage } = require('ee-core/message');
|
||||
const { welcome } = require('./hello');
|
||||
const { UserService } = require('../../service/job/user');
|
||||
import { logger } from 'ee-core/log';
|
||||
import { isChildJob, exit } from 'ee-core/ps';
|
||||
import { childMessage } from 'ee-core/message';
|
||||
import { welcome } from './hello';
|
||||
import { UserService } from '../../service/job/user';
|
||||
|
||||
/**
|
||||
* example - TimerJob
|
||||
* @class
|
||||
* TimerJob class
|
||||
*/
|
||||
class TimerJob {
|
||||
params: any;
|
||||
timer?: NodeJS.Timeout;
|
||||
timeoutTimer?: NodeJS.Timeout;
|
||||
number: number;
|
||||
countdown: number;
|
||||
|
||||
constructor(params) {
|
||||
constructor(params: any) {
|
||||
this.params = params;
|
||||
this.timer = undefined;
|
||||
this.timeoutTimer = undefined;
|
||||
@@ -23,7 +25,7 @@ class TimerJob {
|
||||
/**
|
||||
* handle()方法是必要的,且会被自动调用
|
||||
*/
|
||||
async handle () {
|
||||
async handle(): Promise<void> {
|
||||
logger.info("[child-process] TimerJob params: ", this.params);
|
||||
const { jobId } = this.params;
|
||||
|
||||
@@ -35,34 +37,34 @@ class TimerJob {
|
||||
// 执行任务
|
||||
this.doTimer(jobId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 暂停任务运行
|
||||
*/
|
||||
async pause(jobId) {
|
||||
async pause(jobId: string): Promise<void> {
|
||||
logger.info("[child-process] Pause timerJob, jobId: ", jobId);
|
||||
clearInterval(this.timer);
|
||||
clearInterval(this.timeoutTimer);
|
||||
if (this.timer) clearInterval(this.timer);
|
||||
if (this.timeoutTimer) clearInterval(this.timeoutTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复任务运行
|
||||
*/
|
||||
async resume(jobId, pid) {
|
||||
async resume(jobId: string, pid: number): Promise<void> {
|
||||
logger.info("[child-process] Resume timerJob, jobId: ", jobId, ", pid: ", pid);
|
||||
this.doTimer(jobId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行任务
|
||||
*/
|
||||
async doTimer(jobId) {
|
||||
async doTimer(jobId: string): Promise<void> {
|
||||
// 计时器模拟任务
|
||||
const eventName = 'job-timer-progress-' + jobId;
|
||||
this.timer = setInterval(() => {
|
||||
welcome();
|
||||
|
||||
childMessage.send(eventName, {jobId, number: this.number, end: false});
|
||||
childMessage.send(eventName, { jobId, number: this.number, end: false });
|
||||
this.number++;
|
||||
this.countdown--;
|
||||
}, 1000);
|
||||
@@ -70,19 +72,21 @@ class TimerJob {
|
||||
// 用 setTimeout 模拟任务运行时长
|
||||
this.timeoutTimer = setTimeout(() => {
|
||||
// 关闭计时器模拟任务
|
||||
clearInterval(this.timer);
|
||||
if (this.timer) clearInterval(this.timer);
|
||||
|
||||
// 任务结束,重置前端显示
|
||||
childMessage.send(eventName, {jobId, number:0, pid:0, end: true});
|
||||
childMessage.send(eventName, { jobId, number: 0, pid: 0, end: true });
|
||||
|
||||
// 如果是childJob任务,必须调用 exit() 方法,让进程退出,否则会常驻内存
|
||||
// 如果是childPoolJob任务,常驻内存,等待下一个业务
|
||||
if (isChildJob()) {
|
||||
exit();
|
||||
}
|
||||
}, this.countdown * 1000)
|
||||
}, this.countdown * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置类的toString方法,虽然在TypeScript中不常见
|
||||
TimerJob.toString = () => '[class TimerJob]';
|
||||
module.exports = TimerJob;
|
||||
|
||||
export default TimerJob;
|
||||
@@ -1,19 +1,19 @@
|
||||
const { ElectronEgg } = require('ee-core');
|
||||
const { Lifecycle } = require('./preload/lifecycle');
|
||||
const { preload } = require('./preload');
|
||||
import { ElectronEgg } from 'ee-core';
|
||||
import { Lifecycle } from './preload/lifecycle';
|
||||
import { preload } from './preload';
|
||||
|
||||
// new app
|
||||
// New app
|
||||
const app = new ElectronEgg();
|
||||
|
||||
// register lifecycle
|
||||
// Register lifecycle
|
||||
const life = new Lifecycle();
|
||||
app.register("ready", life.ready);
|
||||
app.register("electron-app-ready", life.electronAppReady);
|
||||
app.register("window-ready", life.windowReady);
|
||||
app.register("before-close", life.beforeClose);
|
||||
|
||||
// register preload
|
||||
// Register preload
|
||||
app.register("preload", preload);
|
||||
|
||||
// run
|
||||
// Run
|
||||
app.run();
|
||||
@@ -3,8 +3,13 @@
|
||||
* 可通过contextBridge 导出api给渲染进程使用
|
||||
*/
|
||||
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
|
||||
// 确保contextBridge.exposeInMainWorld的参数类型正确,这里进行简单的类型定义示例
|
||||
type ElectronApi = {
|
||||
ipcRenderer: typeof ipcRenderer;
|
||||
};
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
ipcRenderer: ipcRenderer,
|
||||
})
|
||||
ipcRenderer: ipcRenderer,
|
||||
} as ElectronApi);
|
||||
@@ -1,15 +1,12 @@
|
||||
/*************************************************
|
||||
** preload为预加载模块,该文件将会在程序启动时加载 **
|
||||
*************************************************/
|
||||
|
||||
function preload() {
|
||||
// 示例功能模块,可选择性使用和修改
|
||||
/**
|
||||
* Preload module, this file will be loaded when the program starts.
|
||||
*/
|
||||
function preload(): void {
|
||||
// Example feature module, optional to use and modify
|
||||
console.log('preload/index.js');
|
||||
}
|
||||
|
||||
/**
|
||||
* 预加载模块入口
|
||||
*/
|
||||
module.exports = {
|
||||
preload
|
||||
}
|
||||
* Entry point of the preload module
|
||||
*/
|
||||
export { preload };
|
||||
@@ -1,51 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
const { getConfig } = require('ee-core/config');
|
||||
const { getMainWindow } = require('ee-core/electron');
|
||||
import { getConfig, Config } from 'ee-core/config';
|
||||
import { getMainWindow } from 'ee-core/electron';
|
||||
|
||||
class Lifecycle {
|
||||
|
||||
/**
|
||||
* core app have been loaded
|
||||
* Core app has been loaded
|
||||
*/
|
||||
async ready() {
|
||||
// do some things
|
||||
async ready(): Promise<void> {
|
||||
// Do some things
|
||||
console.log('[lifecycle] ready');
|
||||
}
|
||||
|
||||
/**
|
||||
* electron app ready
|
||||
* Electron app is ready
|
||||
*/
|
||||
async electronAppReady() {
|
||||
// do some things
|
||||
async electronAppReady(): Promise<void> {
|
||||
// Do some things
|
||||
console.log('[lifecycle] electron-app-ready');
|
||||
}
|
||||
|
||||
/**
|
||||
* main window have been loaded
|
||||
* Main window has been loaded
|
||||
*/
|
||||
async windowReady() {
|
||||
async windowReady(): Promise<void> {
|
||||
console.log('[lifecycle] window-ready');
|
||||
// 延迟加载,无白屏
|
||||
const { windowsOption } = getConfig();
|
||||
if (windowsOption.show == false) {
|
||||
// Delay loading, no white screen
|
||||
const config: Config = getConfig();
|
||||
const { windowsOption } = config;
|
||||
if (windowsOption.show === false) {
|
||||
const win = getMainWindow();
|
||||
win.once('ready-to-show', () => {
|
||||
win.show();
|
||||
win.focus();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* before app close
|
||||
*/
|
||||
async beforeClose() {
|
||||
* Before app close
|
||||
*/
|
||||
async beforeClose(): Promise<void> {
|
||||
console.log('[lifecycle] before-close');
|
||||
}
|
||||
}
|
||||
|
||||
// 设置类的toString方法,虽然在TypeScript中不常见
|
||||
Lifecycle.toString = () => '[class Lifecycle]';
|
||||
module.exports = {
|
||||
Lifecycle
|
||||
};
|
||||
|
||||
export { Lifecycle };
|
||||
@@ -1,56 +1,46 @@
|
||||
'use strict';
|
||||
|
||||
const { logger } = require('ee-core/log');
|
||||
const { getExtraResourcesDir } = require('ee-core/ps');
|
||||
const path = require("path");
|
||||
const axios = require('axios');
|
||||
const { is } = require('ee-core/utils');
|
||||
const { cross } = require('ee-core/cross');
|
||||
import { logger } from 'ee-core/log';
|
||||
import { getExtraResourcesDir } from 'ee-core/ps';
|
||||
import path from 'path';
|
||||
import axios from 'axios';
|
||||
import { is } from 'ee-core/utils';
|
||||
import { cross } from 'ee-core/cross';
|
||||
|
||||
/**
|
||||
* cross
|
||||
* @class
|
||||
* CrossService class for cross platform service management
|
||||
*/
|
||||
class CrossService {
|
||||
|
||||
info() {
|
||||
info(): string {
|
||||
const pids = cross.getPids();
|
||||
logger.info('cross pids:', pids);
|
||||
|
||||
let num = 1;
|
||||
pids.forEach(pid => {
|
||||
let entity = cross.getProc(pid);
|
||||
logger.info(`server-${num} name:${entity.name}`);
|
||||
logger.info(`server-${num} name: ${entity.name}`);
|
||||
logger.info(`server-${num} config:`, entity.config);
|
||||
num++;
|
||||
})
|
||||
});
|
||||
|
||||
return 'hello electron-egg';
|
||||
}
|
||||
|
||||
getUrl(name) {
|
||||
getUrl(name: string): string {
|
||||
const serverUrl = cross.getUrl(name);
|
||||
return serverUrl;
|
||||
}
|
||||
|
||||
killServer(type, name) {
|
||||
if (type == 'all') {
|
||||
killServer(type: string, name: string): void {
|
||||
if (type === 'all') {
|
||||
cross.killAll();
|
||||
} else {
|
||||
cross.killByName(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create go service
|
||||
* In the default configuration, services can be started with applications.
|
||||
* Developers can turn off the configuration and create it manually.
|
||||
*/
|
||||
async createGoServer() {
|
||||
// method 1: Use the default Settings
|
||||
//const entity = await cross.run(serviceName);
|
||||
|
||||
// method 2: Use custom configuration
|
||||
* Create a go service
|
||||
*/
|
||||
async createGoServer(): Promise<void> {
|
||||
const serviceName = "go";
|
||||
const opt = {
|
||||
name: 'goapp',
|
||||
@@ -58,54 +48,43 @@ class CrossService {
|
||||
directory: getExtraResourcesDir(),
|
||||
args: ['--port=7073'],
|
||||
appExit: true,
|
||||
}
|
||||
};
|
||||
const entity = await cross.run(serviceName, opt);
|
||||
logger.info('server name:', entity.name);
|
||||
logger.info('server config:', entity.config);
|
||||
logger.info('server url:', entity.getUrl());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* create java server
|
||||
* Create a java server
|
||||
*/
|
||||
async createJavaServer() {
|
||||
async createJavaServer(): Promise<void> {
|
||||
const serviceName = "java";
|
||||
const jarPath = path.join(getExtraResourcesDir(), 'java-app.jar');
|
||||
const opt = {
|
||||
name: 'javaapp',
|
||||
cmd: path.join(getExtraResourcesDir(), 'jre1.8.0_201/bin/javaw.exe'),
|
||||
directory: getExtraResourcesDir(),
|
||||
args: ['-jar', '-server', '-Xms512M', '-Xmx512M', '-Xss512k', '-Dspring.profiles.active=prod', `-Dserver.port=18080`, `-Dlogging.file.path=${Ps.getLogDir()}`, `${jarPath}`],
|
||||
args: ['-jar', '-server', '-Xms512M', '-Xmx512M', '-Xss512k', '-Dspring.profiles.active=prod', `-Dserver.port=18080`, `-Dlogging.file.path=${getExtraResourcesDir()}`, `${jarPath}`],
|
||||
appExit: false,
|
||||
}
|
||||
};
|
||||
if (is.macOS()) {
|
||||
// Setup Java program
|
||||
opt.cmd = path.join(getExtraResourcesDir(), 'jre1.8.0_201.jre/Contents/Home/bin/java');
|
||||
}
|
||||
if (is.linux()) {
|
||||
// Setup Java program
|
||||
// Setup for Linux
|
||||
}
|
||||
|
||||
const entity = await cross.run(serviceName, opt);
|
||||
logger.info('server name:', entity.name);
|
||||
logger.info('server config:', entity.config);
|
||||
logger.info('server url:', cross.getUrl(entity.name));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create python service
|
||||
* In the default configuration, services can be started with applications.
|
||||
* Developers can turn off the configuration and create it manually.
|
||||
*/
|
||||
async createPythonServer() {
|
||||
// method 1: Use the default Settings
|
||||
//const entity = await cross.run(serviceName);
|
||||
|
||||
// method 2: Use custom configuration
|
||||
* Create a python service
|
||||
*/
|
||||
async createPythonServer(): Promise<void> {
|
||||
const serviceName = "python";
|
||||
const opt = {
|
||||
name: 'pyapp',
|
||||
@@ -114,16 +93,14 @@ class CrossService {
|
||||
args: ['--port=7074'],
|
||||
windowsExtname: true,
|
||||
appExit: true,
|
||||
}
|
||||
};
|
||||
const entity = await cross.run(serviceName, opt);
|
||||
logger.info('server name:', entity.name);
|
||||
logger.info('server config:', entity.config);
|
||||
logger.info('server url:', entity.getUrl());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
async requestApi(name, urlPath, params) {
|
||||
async requestApi(name: string, urlPath: string, params: any): Promise<any> {
|
||||
const serverUrl = cross.getUrl(name);
|
||||
const apiHello = serverUrl + urlPath;
|
||||
console.log('Server Url:', serverUrl);
|
||||
@@ -135,17 +112,16 @@ class CrossService {
|
||||
params,
|
||||
proxy: false,
|
||||
});
|
||||
if (response.status == 200) {
|
||||
if (response.status === 200) {
|
||||
const { data } = response;
|
||||
return data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
CrossService.toString = () => '[class CrossService]';
|
||||
module.exports = {
|
||||
CrossService,
|
||||
crossService: new CrossService()
|
||||
};
|
||||
|
||||
export { CrossService, new CrossService() as crossService };
|
||||
@@ -1,52 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
const { SqliteStorage } = require('ee-core/storage');
|
||||
const { getDataDir } = require('ee-core/ps');
|
||||
const path = require('path');
|
||||
import { SqliteStorage } from 'ee-core/storage';
|
||||
import { getDataDir } from 'ee-core/ps';
|
||||
import path from 'path';
|
||||
|
||||
/**
|
||||
* sqlite数据存储
|
||||
* @class
|
||||
* BasedbService class for sqlite data storage
|
||||
*/
|
||||
class BasedbService {
|
||||
dbname: string;
|
||||
db: any; // Replace 'any' with the actual type if known
|
||||
storage: SqliteStorage;
|
||||
|
||||
constructor(options) {
|
||||
const { dbname } = options;
|
||||
this.dbname = dbname;
|
||||
this.db = undefined;
|
||||
constructor(options: { dbname: string }) {
|
||||
this.dbname = options.dbname;
|
||||
this._init();
|
||||
}
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
/**
|
||||
* Initializes the sqlite database
|
||||
*/
|
||||
_init() {
|
||||
// 定义数据文件
|
||||
private _init(): void {
|
||||
// Define the data file
|
||||
const dbFile = path.join(getDataDir(), "db", this.dbname);
|
||||
const sqliteOptions = {
|
||||
timeout: 6000,
|
||||
verbose: console.log
|
||||
}
|
||||
};
|
||||
this.storage = new SqliteStorage(dbFile, sqliteOptions);
|
||||
this.db = this.storage.db;
|
||||
}
|
||||
|
||||
/*
|
||||
* change data dir (sqlite)
|
||||
/**
|
||||
* Changes the data directory for the sqlite database
|
||||
*/
|
||||
changeDataDir(dir) {
|
||||
// the absolute path of the db file
|
||||
changeDataDir(dir: string): void {
|
||||
// The absolute path of the db file
|
||||
const dbFile = path.join(dir, this.dbname);
|
||||
const sqliteOptions = {
|
||||
timeout: 6000,
|
||||
verbose: console.log
|
||||
}
|
||||
};
|
||||
this.storage = new SqliteStorage(dbFile, sqliteOptions);
|
||||
this.db = this.storage.db;
|
||||
this.db = this.storage.db;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
BasedbService.toString = () => '[class BasedbService]';
|
||||
module.exports = {
|
||||
BasedbService,
|
||||
};
|
||||
|
||||
export { BasedbService };
|
||||
@@ -1,112 +1,112 @@
|
||||
'use strict';
|
||||
|
||||
const { BasedbService } = require('./basedb');
|
||||
const _ = require('lodash');
|
||||
import { BasedbService } from './basedb';
|
||||
import _ from 'lodash';
|
||||
import { SqliteStorage } from 'ee-core/storage';
|
||||
|
||||
/**
|
||||
* sqlite数据存储
|
||||
* @class
|
||||
* SqlitedbService class for sqlite data storage
|
||||
*/
|
||||
class SqlitedbService extends BasedbService {
|
||||
userTableName: string;
|
||||
storage: SqliteStorage;
|
||||
|
||||
constructor () {
|
||||
constructor() {
|
||||
const options = {
|
||||
dbname: 'sqlite-demo.db',
|
||||
}
|
||||
};
|
||||
super(options);
|
||||
this.userTableName = 'user';
|
||||
this._initTable();
|
||||
}
|
||||
|
||||
/*
|
||||
* 初始化表
|
||||
/**
|
||||
* Initializes the table
|
||||
*/
|
||||
_initTable() {
|
||||
// 检查表是否存在
|
||||
private _initTable(): void {
|
||||
// Check if the table exists
|
||||
const masterStmt = this.db.prepare('SELECT * FROM sqlite_master WHERE type=? AND name = ?');
|
||||
let tableExists = masterStmt.get('table', this.userTableName);
|
||||
if (!tableExists) {
|
||||
// 创建表
|
||||
// Create the table
|
||||
const create_user_table_sql =
|
||||
`CREATE TABLE ${this.userTableName}
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name CHAR(50) NOT NULL,
|
||||
age INT
|
||||
);`
|
||||
`CREATE TABLE ${this.userTableName} (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name CHAR(50) NOT NULL,
|
||||
age INT
|
||||
);`
|
||||
this.db.exec(create_user_table_sql);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 增 Test data (sqlite)
|
||||
/**
|
||||
* Adds test data to sqlite
|
||||
*/
|
||||
async addTestDataSqlite(data) {
|
||||
async addTestDataSqlite(data: { name: string; age: number }): Promise<boolean> {
|
||||
const insert = this.db.prepare(`INSERT INTO ${this.userTableName} (name, age) VALUES (@name, @age)`);
|
||||
insert.run(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* 删 Test data (sqlite)
|
||||
/**
|
||||
* Deletes test data from sqlite
|
||||
*/
|
||||
async delTestDataSqlite(name = '') {
|
||||
async delTestDataSqlite(name: string = ''): Promise<boolean> {
|
||||
const delUser = this.db.prepare(`DELETE FROM ${this.userTableName} WHERE name = ?`);
|
||||
delUser.run(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* 改 Test data (sqlite)
|
||||
/**
|
||||
* Updates test data in sqlite
|
||||
*/
|
||||
async updateTestDataSqlite(name= '', age = 0) {
|
||||
async updateTestDataSqlite(name: string = '', age: number = 0): Promise<boolean> {
|
||||
const updateUser = this.db.prepare(`UPDATE ${this.userTableName} SET age = ? WHERE name = ?`);
|
||||
updateUser.run(age, name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 查 Test data (sqlite)
|
||||
/**
|
||||
* Retrieves test data from sqlite
|
||||
*/
|
||||
async getTestDataSqlite(age = 0) {
|
||||
async getTestDataSqlite(age: number = 0): Promise<any[]> {
|
||||
const selectUser = this.db.prepare(`SELECT * FROM ${this.userTableName} WHERE age = @age`);
|
||||
const users = selectUser.all({age: age});
|
||||
const users = selectUser.all({ age: age });
|
||||
return users;
|
||||
}
|
||||
|
||||
/*
|
||||
* all Test data (sqlite)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all test data from sqlite
|
||||
*/
|
||||
async getAllTestDataSqlite() {
|
||||
async getAllTestDataSqlite(): Promise<any[]> {
|
||||
const selectAllUser = this.db.prepare(`SELECT * FROM ${this.userTableName} `);
|
||||
const allUser = selectAllUser.all();
|
||||
const allUser = selectAllUser.all();
|
||||
return allUser;
|
||||
}
|
||||
|
||||
/*
|
||||
* get data dir (sqlite)
|
||||
*/
|
||||
async getDataDir() {
|
||||
const dir = this.storage.getStorageDir();
|
||||
return dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* set custom data dir (sqlite)
|
||||
/**
|
||||
* Gets the data directory for sqlite
|
||||
*/
|
||||
async setCustomDataDir(dir) {
|
||||
async getDataDir(): Promise<string> {
|
||||
const dir = this.storage.getStorageDir();
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom data directory for sqlite
|
||||
*/
|
||||
async setCustomDataDir(dir: string): Promise<void> {
|
||||
if (_.isEmpty(dir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.changeDataDir(dir);
|
||||
this._initTable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
SqlitedbService.toString = () => '[class SqlitedbService]';
|
||||
module.exports = {
|
||||
SqlitedbService,
|
||||
|
||||
export {
|
||||
SqlitedbService,
|
||||
sqlitedbService: new SqlitedbService()
|
||||
};
|
||||
};
|
||||
@@ -1,30 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const { logger } = require('ee-core/log');
|
||||
import { logger } from 'ee-core/log';
|
||||
|
||||
/**
|
||||
* effect
|
||||
* @class
|
||||
* EffectService class for handling effects
|
||||
*/
|
||||
class EffectService {
|
||||
|
||||
/**
|
||||
* hello
|
||||
* Hello method
|
||||
* @param args The arguments passed to the method
|
||||
*/
|
||||
async hello(args) {
|
||||
async hello(args: any): Promise<{ status: string; params: any }> {
|
||||
let obj = {
|
||||
status:'ok',
|
||||
params: args
|
||||
}
|
||||
status: 'ok',
|
||||
params: args,
|
||||
};
|
||||
logger.info('EffectService obj:', obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
EffectService.toString = () => '[class EffectService]';
|
||||
module.exports = {
|
||||
EffectService,
|
||||
effectService: new EffectService()
|
||||
};
|
||||
|
||||
export { EffectService, new EffectService() as effectService };
|
||||
@@ -1,32 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
const { logger } = require('ee-core/log');
|
||||
import { logger } from 'ee-core/log';
|
||||
|
||||
/**
|
||||
* 示例服务
|
||||
* @class
|
||||
* ExampleService class for demonstration purposes
|
||||
*/
|
||||
class ExampleService {
|
||||
|
||||
/**
|
||||
* test
|
||||
* Test method
|
||||
* @param args The arguments passed to the method
|
||||
*/
|
||||
async test(args) {
|
||||
async test(args: any): Promise<{ status: string; params: any }> {
|
||||
let obj = {
|
||||
status:'ok',
|
||||
params: args
|
||||
}
|
||||
status: 'ok',
|
||||
params: args,
|
||||
};
|
||||
|
||||
logger.info('ExampleService obj:', obj);
|
||||
|
||||
//Services.get('framework').test('egg');
|
||||
// Services.get('framework').test('egg'); // This line is commented out and would need proper typing if used
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
ExampleService.toString = () => '[class ExampleService]';
|
||||
module.exports = {
|
||||
ExampleService,
|
||||
exampleService: new ExampleService()
|
||||
};
|
||||
|
||||
export { ExampleService, exampleService: new ExampleService() };
|
||||
@@ -1,16 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
const { logger } = require('ee-core/log');
|
||||
const { ChildJob, ChildPoolJob } = require('ee-core/jobs');
|
||||
import { logger } from 'ee-core/log';
|
||||
import { ChildJob, ChildPoolJob } from 'ee-core/jobs';
|
||||
|
||||
/**
|
||||
* framework
|
||||
* @class
|
||||
* FrameworkService class for framework-related operations
|
||||
*/
|
||||
class FrameworkService {
|
||||
myTimer: NodeJS.Timeout | null;
|
||||
myJob: ChildJob;
|
||||
myJobPool: ChildPoolJob;
|
||||
taskForJob: { [key: string]: any };
|
||||
|
||||
constructor() {
|
||||
// 在构造函数中初始化一些变量
|
||||
// Initialize variables in the constructor
|
||||
this.myTimer = null;
|
||||
this.myJob = new ChildJob();
|
||||
this.myJobPool = new ChildPoolJob();
|
||||
@@ -18,81 +19,73 @@ class FrameworkService {
|
||||
}
|
||||
|
||||
/**
|
||||
* test
|
||||
* Test method
|
||||
* @param args The arguments passed to the method
|
||||
*/
|
||||
async test(args) {
|
||||
async test(args: any): Promise<{ status: string; params: any }> {
|
||||
let obj = {
|
||||
status:'ok',
|
||||
params: args
|
||||
}
|
||||
status: 'ok',
|
||||
params: args,
|
||||
};
|
||||
logger.info('FrameworkService obj:', obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipc通信(双向)
|
||||
* IPC communication (two-way)
|
||||
*/
|
||||
bothWayMessage(type, content, event) {
|
||||
// 前端ipc频道 channel
|
||||
bothWayMessage(type: string, content: any, event: any): string {
|
||||
// Frontend IPC channel
|
||||
const channel = 'controller.framework.ipcSendMsg';
|
||||
|
||||
if (type == 'start') {
|
||||
// 每隔1秒,向前端页面发送消息
|
||||
// 用定时器模拟
|
||||
this.myTimer = setInterval(function(e, c, msg) {
|
||||
if (type === 'start') {
|
||||
// Send messages to the frontend page every 1 second
|
||||
// Simulate with a timer
|
||||
this.myTimer = setInterval((e: any, c: string, msg: string) => {
|
||||
let timeNow = Date.now();
|
||||
let data = msg + ':' + timeNow;
|
||||
e.reply(`${c}`, data)
|
||||
}, 1000, event, channel, content)
|
||||
e.reply(`${c}`, data);
|
||||
}, 1000, event, channel, content);
|
||||
|
||||
return '开始了'
|
||||
} else if (type == 'end') {
|
||||
return 'started';
|
||||
} else if (type === 'end') {
|
||||
clearInterval(this.myTimer);
|
||||
return '停止了'
|
||||
return 'stopped';
|
||||
} else {
|
||||
return 'ohther'
|
||||
return 'other';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行任务
|
||||
*/
|
||||
doJob(jobId, action, event) {
|
||||
* Execute a job
|
||||
*/
|
||||
doJob(jobId: string, action: string, event: any): any {
|
||||
let res = {};
|
||||
let oneTask;
|
||||
let oneTask: any;
|
||||
const channel = 'controller.framework.timerJobProgress';
|
||||
if (action == 'create') {
|
||||
// 执行任务及监听进度
|
||||
if (action === 'create') {
|
||||
// Execute the job and listen for progress
|
||||
let eventName = 'job-timer-progress-' + jobId;
|
||||
const timerTask = this.myJob.exec('./jobs/example/timer', {jobId});
|
||||
timerTask.emitter.on(eventName, (data) => {
|
||||
const timerTask = this.myJob.exec('./jobs/example/timer', { jobId });
|
||||
timerTask.emitter.on(eventName, (data: any) => {
|
||||
logger.info('[main-process] timerTask, from TimerJob data:', data);
|
||||
// 发送数据到渲染进程
|
||||
event.sender.send(`${channel}`, data)
|
||||
})
|
||||
|
||||
// 执行任务及监听进度 异步
|
||||
// myjob.execPromise('./jobs/example/timer', {jobId}).then(task => {
|
||||
// task.emitter.on(eventName, (data) => {
|
||||
// Log.info('[main-process] timerTask, from TimerJob data:', data);
|
||||
// // 发送数据到渲染进程
|
||||
// event.sender.send(`${channel}`, data)
|
||||
// })
|
||||
// });
|
||||
// Send data to the rendering process
|
||||
event.sender.send(`${channel}`, data);
|
||||
});
|
||||
|
||||
res.pid = timerTask.pid;
|
||||
res.pid = timerTask.pid;
|
||||
this.taskForJob[jobId] = timerTask;
|
||||
}
|
||||
if (action == 'close') {
|
||||
if (action === 'close') {
|
||||
oneTask = this.taskForJob[jobId];
|
||||
oneTask.kill();
|
||||
event.sender.send(`${channel}`, {jobId, number:0, pid:0});
|
||||
event.sender.send(`${channel}`, { jobId, number: 0, pid: 0 });
|
||||
}
|
||||
if (action == 'pause') {
|
||||
if (action === 'pause') {
|
||||
oneTask = this.taskForJob[jobId];
|
||||
oneTask.callFunc('./jobs/example/timer', 'pause', jobId);
|
||||
}
|
||||
if (action == 'resume') {
|
||||
if (action === 'resume') {
|
||||
oneTask = this.taskForJob[jobId];
|
||||
oneTask.callFunc('./jobs/example/timer', 'resume', jobId, oneTask.pid);
|
||||
}
|
||||
@@ -100,64 +93,62 @@ class FrameworkService {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 创建pool
|
||||
*/
|
||||
doCreatePool(num, event) {
|
||||
* Create a pool
|
||||
*/
|
||||
doCreatePool(num: number, event: any): void {
|
||||
const channel = 'controller.framework.createPoolNotice';
|
||||
this.myJobPool.create(num).then(pids => {
|
||||
this.myJobPool.create(num).then((pids: number[]) => {
|
||||
event.reply(`${channel}`, pids);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过进程池执行任务
|
||||
*/
|
||||
doJobByPool(jobId, action, event) {
|
||||
* Execute a job through the job pool
|
||||
*/
|
||||
doJobByPool(jobId: string, action: string, event: any): any {
|
||||
let res = {};
|
||||
const channel = 'controller.framework.timerJobProgress';
|
||||
if (action == 'run') {
|
||||
// 异步-执行任务及监听进度
|
||||
this.myJobPool.runPromise('./jobs/example/timer', {jobId}).then(task => {
|
||||
|
||||
// 监听器名称唯一,否则会出现重复监听。
|
||||
// 任务完成时,需要移除监听器,防止内存泄漏
|
||||
if (action === 'run') {
|
||||
// Asynchronously execute the job and listen for progress
|
||||
this.myJobPool.runPromise('./jobs/example/timer', { jobId }).then((task: any) => {
|
||||
// Listener name must be unique, otherwise there will be duplicate listeners
|
||||
// When the task is completed, the listener should be removed to prevent memory leaks
|
||||
let eventName = 'job-timer-progress-' + jobId;
|
||||
task.emitter.on(eventName, (data) => {
|
||||
task.emitter.on(eventName, (data: any) => {
|
||||
logger.info('[main-process] [ChildPoolJob] timerTask, from TimerJob data:', data);
|
||||
|
||||
// 发送数据到渲染进程
|
||||
event.sender.send(`${channel}`, data)
|
||||
|
||||
// 如果收到任务完成的消息,移除监听器
|
||||
// Send data to the rendering process
|
||||
event.sender.send(`${channel}`, data);
|
||||
|
||||
// If the task completion message is received, remove the listener
|
||||
if (data.end) {
|
||||
task.emitter.removeAllListeners(eventName);
|
||||
}
|
||||
});
|
||||
|
||||
res.pid = task.pid;
|
||||
res.pid = task.pid;
|
||||
});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取正在运行的 job 进程
|
||||
*/
|
||||
monitorJob() {
|
||||
* Monitor running jobs
|
||||
*/
|
||||
monitorJob(): void {
|
||||
setInterval(() => {
|
||||
let jobPids = this.myJob.getPids();
|
||||
let jobPoolPids = this.myJobPool.getPids();
|
||||
logger.info(`[main-process] [monitorJob] jobPids: ${jobPids}, jobPoolPids: ${jobPoolPids}`);
|
||||
}, 5000)
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
FrameworkService.toString = () => '[class FrameworkService]';
|
||||
module.exports = {
|
||||
FrameworkService,
|
||||
frameworkService: new FrameworkService()
|
||||
};
|
||||
const frameworkService: FrameworkService = new FrameworkService();
|
||||
export {
|
||||
FrameworkService,
|
||||
frameworkService
|
||||
};
|
||||
@@ -1,26 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
const { logger } = require('ee-core/log');
|
||||
import { logger } from 'ee-core/log';
|
||||
|
||||
// The service used in the job should not rely on Electron's API, as it may cause errors
|
||||
class UserService {
|
||||
|
||||
/**
|
||||
* hello
|
||||
* Hello method
|
||||
* @param args The arguments passed to the method
|
||||
*/
|
||||
async hello(args) {
|
||||
async hello(args: any): Promise<{ status: string; params: any }> {
|
||||
let obj = {
|
||||
status:'ok',
|
||||
params: args
|
||||
}
|
||||
status: 'ok',
|
||||
params: args,
|
||||
};
|
||||
logger.info('UserService obj:', obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
UserService.toString = () => '[class UserService]';
|
||||
module.exports = {
|
||||
UserService
|
||||
};
|
||||
|
||||
export { UserService };
|
||||
@@ -1,35 +1,31 @@
|
||||
const { app: electronApp } = require('electron');
|
||||
const { autoUpdater } = require("electron-updater");
|
||||
const { is } = require('ee-core/utils');
|
||||
const { logger } = require('ee-core/log');
|
||||
const { getConfig } = require('ee-core/config');
|
||||
const { getMainWindow, setCloseAndQuit } = require('ee-core/electron/window');
|
||||
import { app as electronApp } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
import { is } from 'ee-core/utils';
|
||||
import { logger } from 'ee-core/log';
|
||||
import { getConfig } from 'ee-core/config';
|
||||
import { getMainWindow, setCloseAndQuit } from 'ee-core/electron/window';
|
||||
|
||||
/**
|
||||
* 自动升级
|
||||
* @class
|
||||
* AutoUpdater class for automatic updates
|
||||
*/
|
||||
class AutoUpdater {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* 创建
|
||||
* Create and configure the auto updater
|
||||
*/
|
||||
create () {
|
||||
create(): void {
|
||||
logger.info('[addon:autoUpdater] load');
|
||||
const cfg = getConfig().customize.autoUpdater;
|
||||
if ((is.windows() && cfg.windows)
|
||||
|| (is.macOS() && cfg.macOS)
|
||||
|| (is.linux() && cfg.linux))
|
||||
{
|
||||
if ((is.windows() && cfg.windows) ||
|
||||
(is.macOS() && cfg.macOS) ||
|
||||
(is.linux() && cfg.linux)) {
|
||||
// continue
|
||||
} else {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// 是否检查更新
|
||||
// Check for updates immediately
|
||||
if (cfg.force) {
|
||||
this.checkUpdate();
|
||||
}
|
||||
@@ -40,127 +36,127 @@ class AutoUpdater {
|
||||
noAvailable: 2,
|
||||
downloading: 3,
|
||||
downloaded: 4,
|
||||
}
|
||||
} as const;
|
||||
|
||||
const version = electronApp.getVersion();
|
||||
logger.info('[addon:autoUpdater] current version: ', version);
|
||||
|
||||
// 设置下载服务器地址
|
||||
|
||||
// Set the update server URL
|
||||
let server = cfg.options.url;
|
||||
let lastChar = server.substring(server.length - 1);
|
||||
server = lastChar === '/' ? server : server + "/";
|
||||
cfg.options.url = server;
|
||||
|
||||
// 是否后台自动下载
|
||||
|
||||
// Auto download updates in the background
|
||||
autoUpdater.autoDownload = cfg.force ? true : false;
|
||||
|
||||
|
||||
try {
|
||||
autoUpdater.setFeedURL(cfg.options);
|
||||
} catch (error) {
|
||||
logger.error('[addon:autoUpdater] setFeedURL error : ', error);
|
||||
}
|
||||
|
||||
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
//sendStatusToWindow('正在检查更新...');
|
||||
})
|
||||
// sendStatusToWindow('正在检查更新...');
|
||||
});
|
||||
autoUpdater.on('update-available', (info) => {
|
||||
info.status = status.available;
|
||||
info.desc = '有可用更新';
|
||||
this.sendStatusToWindow(info);
|
||||
})
|
||||
});
|
||||
autoUpdater.on('update-not-available', (info) => {
|
||||
info.status = status.noAvailable;
|
||||
info.desc = '没有可用更新';
|
||||
this.sendStatusToWindow(info);
|
||||
})
|
||||
});
|
||||
autoUpdater.on('error', (err) => {
|
||||
const info = {
|
||||
status: status.error,
|
||||
desc: err
|
||||
}
|
||||
desc: err,
|
||||
};
|
||||
this.sendStatusToWindow(info);
|
||||
})
|
||||
});
|
||||
autoUpdater.on('download-progress', (progressObj) => {
|
||||
let percentNumber = parseInt(progressObj.percent);
|
||||
let totalSize = this.bytesChange(progressObj.total);
|
||||
let transferredSize = this.bytesChange(progressObj.transferred);
|
||||
let text = '已下载 ' + percentNumber + '%';
|
||||
text = text + ' (' + transferredSize + "/" + totalSize + ')';
|
||||
|
||||
|
||||
let info = {
|
||||
status: status.downloading,
|
||||
desc: text,
|
||||
percentNumber: percentNumber,
|
||||
totalSize: totalSize,
|
||||
transferredSize: transferredSize
|
||||
}
|
||||
transferredSize: transferredSize,
|
||||
};
|
||||
logger.info('[addon:autoUpdater] progress: ', text);
|
||||
this.sendStatusToWindow(info);
|
||||
})
|
||||
});
|
||||
autoUpdater.on('update-downloaded', (info) => {
|
||||
info.status = status.downloaded;
|
||||
info.desc = '下载完成';
|
||||
this.sendStatusToWindow(info);
|
||||
|
||||
// 托盘插件里面设置了阻止窗口关闭,这里设置允许关闭窗口
|
||||
// Allow the window to close
|
||||
setCloseAndQuit(true);
|
||||
|
||||
|
||||
// Install updates and exit the application
|
||||
autoUpdater.quitAndInstall();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查更新
|
||||
* Check for updates
|
||||
*/
|
||||
checkUpdate () {
|
||||
checkUpdate(): void {
|
||||
autoUpdater.checkForUpdates();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下载更新
|
||||
* Download updates
|
||||
*/
|
||||
download () {
|
||||
download(): void {
|
||||
autoUpdater.downloadUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 向前端发消息
|
||||
* Send status to the frontend
|
||||
*/
|
||||
sendStatusToWindow(content = {}) {
|
||||
sendStatusToWindow(content = {}): void {
|
||||
const textJson = JSON.stringify(content);
|
||||
const channel = 'custom.app.updater';
|
||||
const win = getMainWindow();
|
||||
win.webContents.send(channel, textJson);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 单位转换
|
||||
* Convert bytes to a more readable format
|
||||
*/
|
||||
bytesChange (limit) {
|
||||
bytesChange(limit: number): string {
|
||||
let size = "";
|
||||
if(limit < 0.1 * 1024){
|
||||
if (limit < 0.1 * 1024) {
|
||||
size = limit.toFixed(2) + "B";
|
||||
}else if(limit < 0.1 * 1024 * 1024){
|
||||
size = (limit/1024).toFixed(2) + "KB";
|
||||
}else if(limit < 0.1 * 1024 * 1024 * 1024){
|
||||
size = (limit/(1024 * 1024)).toFixed(2) + "MB";
|
||||
}else{
|
||||
size = (limit/(1024 * 1024 * 1024)).toFixed(2) + "GB";
|
||||
} else if (limit < 0.1 * 1024 * 1024) {
|
||||
size = (limit / 1024).toFixed(2) + "KB";
|
||||
} else if (limit < 0.1 * 1024 * 1024 * 1024) {
|
||||
size = (limit / (1024 * 1024)).toFixed(2) + "MB";
|
||||
} else {
|
||||
size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB";
|
||||
}
|
||||
|
||||
let sizeStr = size + "";
|
||||
let index = sizeStr.indexOf(".");
|
||||
let dou = sizeStr.substring(index + 1 , index + 3);
|
||||
if(dou == "00"){
|
||||
return sizeStr.substring(0, index) + sizeStr.substring(index + 3, index + 5);
|
||||
let sizeStr = size + "";
|
||||
let index = sizeStr.indexOf(".");
|
||||
let dou = sizeStr.substring(index + 1, index + 3);
|
||||
if (dou == "00") {
|
||||
return sizeStr.substring(0, index) + sizeStr.substring(index + 3, index + 5);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
AutoUpdater.toString = () => '[class AutoUpdater]';
|
||||
module.exports = {
|
||||
autoUpdater: new AutoUpdater()
|
||||
};
|
||||
|
||||
export { AutoUpdater, autoUpdater: new AutoUpdater() };
|
||||
@@ -1,34 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const { app: electronApp } = require('electron');
|
||||
const { BrowserWindow, Notification } = require('electron');
|
||||
const { getMainWindow } = require('ee-core/electron/window');
|
||||
const { isProd, getBaseDir } = require('ee-core/ps');
|
||||
import path from 'path';
|
||||
import { app as electronApp, BrowserWindow, Notification } from 'electron';
|
||||
import { getMainWindow } from 'ee-core/electron/window';
|
||||
import { isProd, getBaseDir } from 'ee-core/ps';
|
||||
import { getConfig } from 'ee-core/config';
|
||||
|
||||
/**
|
||||
* Window
|
||||
* @class
|
||||
* WindowService class for managing windows
|
||||
*/
|
||||
class WindowService {
|
||||
myNotification: Notification | null;
|
||||
windows: { [key: string]: BrowserWindow };
|
||||
|
||||
constructor() {
|
||||
this.myNotification = null;
|
||||
this.windows = {}
|
||||
this.windows = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new window
|
||||
*/
|
||||
createWindow(args) {
|
||||
createWindow(args: { type: string; content: string; windowName: string; windowTitle: string }): number {
|
||||
const { type, content, windowName, windowTitle } = args;
|
||||
let contentUrl = null;
|
||||
if (type == 'html') {
|
||||
contentUrl = path.join('file://', getBaseDir(), content)
|
||||
} else if (type == 'web') {
|
||||
let contentUrl: string | null = null;
|
||||
if (type === 'html') {
|
||||
contentUrl = path.join('file://', getBaseDir(), content);
|
||||
} else if (type === 'web') {
|
||||
contentUrl = content;
|
||||
} else if (type == 'vue') {
|
||||
let addr = 'http://localhost:8080'
|
||||
} else if (type === 'vue') {
|
||||
let addr = 'http://localhost:8080';
|
||||
if (isProd()) {
|
||||
const { mainServer } = getConfig();
|
||||
if (isFileProtocol(mainServer)) {
|
||||
@@ -40,7 +39,7 @@ class WindowService {
|
||||
|
||||
contentUrl = addr + content;
|
||||
} else {
|
||||
// some
|
||||
// Handle other types if necessary
|
||||
}
|
||||
|
||||
console.log('contentUrl: ', contentUrl);
|
||||
@@ -48,85 +47,83 @@ class WindowService {
|
||||
title: windowTitle,
|
||||
x: 10,
|
||||
y: 10,
|
||||
width: 980,
|
||||
width: 980,
|
||||
height: 650,
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
nodeIntegration: true,
|
||||
},
|
||||
}
|
||||
};
|
||||
const win = new BrowserWindow(opt);
|
||||
const winContentsId = win.webContents.id;
|
||||
win.loadURL(contentUrl);
|
||||
win.loadURL(contentUrl!);
|
||||
win.webContents.openDevTools();
|
||||
this.windows[windowName] = win;
|
||||
|
||||
return winContentsId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get window contents id
|
||||
*/
|
||||
getWCid(args) {
|
||||
getWCid(args: { windowName: string }): number {
|
||||
const { windowName } = args;
|
||||
let win;
|
||||
if (windowName == 'main') {
|
||||
let win: BrowserWindow;
|
||||
if (windowName === 'main') {
|
||||
win = getMainWindow();
|
||||
} else {
|
||||
win = this.windows[windowName];
|
||||
}
|
||||
|
||||
|
||||
return win.webContents.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Realize communication between two windows through the transfer of the main process
|
||||
*/
|
||||
communicate(args) {
|
||||
communicate(args: { receiver: string; content: any }): void {
|
||||
const { receiver, content } = args;
|
||||
if (receiver == 'main') {
|
||||
if (receiver === 'main') {
|
||||
const win = getMainWindow();
|
||||
win.webContents.send('controller.os.window2ToWindow1', content);
|
||||
} else if (receiver == 'window2') {
|
||||
} else if (receiver === 'window2') {
|
||||
const win = this.windows[receiver];
|
||||
win.webContents.send('controller.os.window1ToWindow2', content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* createNotification
|
||||
* Create a notification
|
||||
*/
|
||||
createNotification(options, event) {
|
||||
createNotification(options: { [key: string]: any }, event: any): void {
|
||||
const channel = 'controller.os.sendNotification';
|
||||
this.myNotification = new Notification(options);
|
||||
|
||||
if (options.clickEvent) {
|
||||
this.myNotification.on('click', (e) => {
|
||||
this.myNotification.on('click', () => {
|
||||
let data = {
|
||||
type: 'click',
|
||||
msg: '您点击了通知消息'
|
||||
}
|
||||
event.reply(`${channel}`, data)
|
||||
msg: '您点击了通知消息',
|
||||
};
|
||||
event.reply(`${channel}`, data);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.closeEvent) {
|
||||
this.myNotification.on('close', (e) => {
|
||||
this.myNotification.on('close', () => {
|
||||
let data = {
|
||||
type: 'close',
|
||||
msg: '您关闭了通知消息'
|
||||
}
|
||||
event.reply(`${channel}`, data)
|
||||
msg: '您关闭了通知消息',
|
||||
};
|
||||
event.reply(`${channel}`, data);
|
||||
});
|
||||
}
|
||||
|
||||
this.myNotification.show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Setting the class toString method, which is not common in TypeScript
|
||||
WindowService.toString = () => '[class WindowService]';
|
||||
module.exports = {
|
||||
WindowService,
|
||||
windowService: new WindowService()
|
||||
};
|
||||
|
||||
export { WindowService, windowService: new WindowService() };
|
||||
32
tsconfig.json
Normal file
32
tsconfig.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"useDefineForClassFields": true,
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true,
|
||||
"types": ["node"],
|
||||
"esModuleInterop": true,
|
||||
|
||||
// "allowJs": true,
|
||||
// "checkJs": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler", // node
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
//"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitAny": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
|
||||
17
vite.config.ts
Normal file
17
vite.config.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import {defineConfig} from 'vite'
|
||||
import {resolve} from 'path';
|
||||
import dts from 'vite-plugin-dts'
|
||||
|
||||
export default defineConfig({
|
||||
define: {'process.env': {}},
|
||||
build: {
|
||||
minify: "esbuild",
|
||||
lib: {
|
||||
entry: resolve(__dirname, './src/electron/main.ts'),
|
||||
formats: ['cjs']
|
||||
},
|
||||
outDir: "runtime",
|
||||
},
|
||||
plugins: [dts({rollupTypes: true}),
|
||||
],
|
||||
})
|
||||
Reference in New Issue
Block a user