This commit is contained in:
gaoshuaixing
2022-02-22 21:42:30 +08:00
parent 271637368a
commit af4fed2c47
13 changed files with 0 additions and 1538 deletions

View File

@@ -1,62 +0,0 @@
'use strict';
const Service = require('egg').Service;
class BaseService extends Service {
/*
* ipc call
*/
async ipcCall(method = '', ...params) {
let result = {
err: null,
data: null
};
if (!method) {
result.err = 'Method does not exist';
return result;
}
try {
result = await this.service.socket.call(method, params);
} catch (err) {
this.app.logger.error('[base] [ipcCall] request error:', err);
result.err = 'request err';
}
this.app.logger.info('[base] [ipcCall] result:', result);
return result;
}
/*
* ipc call
*/
// async ipcCall(method = '', ...params) {
// let result = {
// err: null,
// data: null
// };
// if (!method) {
// result.err = 'Method does not exist';
// return result;
// }
// const port = this.service.storage.getElectronIPCPort();
// const url = 'http://localhost:' + port + '/send';
// try {
// const response = await request.post(url)
// .send({ cmd: method, params: params })
// .set('accept', 'json');
// result = JSON.parse(response.text);
// } catch (err) {
// this.app.logger.error('[base] [ipcCall] request error:', err);
// result.err = 'request err';
// }
// this.app.logger.info('[base] [ipcCall] result:', result);
// return result;
// }
}
module.exports = BaseService;

View File

@@ -1,12 +0,0 @@
// // 密码校验规则(32位字符串,既Md5加密后的)
// const passwordReg1 = /^.{32}$/
// // 手机号码校验规则
// const phoneReg = /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/
'use strict';
const regRule = {
paswwordReg1: /^.{32}$/,
phoneReg: /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/,
emailReg: /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/,
};
module.exports = regRule;

View File

@@ -1,500 +0,0 @@
'use strict';
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const net = require('net');
exports = module.exports;
// control variable of func "myPrint"
const isPrintFlag = true;
/**
* Check and invoke callback function
*/
exports.invokeCallback = function(cb) {
if (!!cb && typeof cb === 'function') {
cb.apply(null, Array.prototype.slice.call(arguments, 1));
}
};
exports.size = function(obj) {
if (!obj) {
return 0;
}
let size = 0;
for (const f in obj) {
if (obj.hasOwnProperty(f)) {
size++;
}
}
return size;
};
// print the file name and the line number ~ begin
function getStack() {
const orig = Error.prepareStackTrace;
Error.prepareStackTrace = function(_, stack) {
return stack;
};
const err = new Error();
Error.captureStackTrace(err, arguments.callee);
const stack = err.stack;
Error.prepareStackTrace = orig;
return stack;
}
function getFileName(stack) {
return stack[1].getFileName();
}
function getLineNumber(stack) {
return stack[1].getLineNumber();
}
exports.myPrint = function() {
if (isPrintFlag) {
const len = arguments.length;
if (len <= 0) {
return;
}
const stack = getStack();
let aimStr =
"'" + getFileName(stack) + "' @" + getLineNumber(stack) + ' :\n';
for (let i = 0; i < len; ++i) {
aimStr +=
(typeof arguments[i] === 'object'
? JSON.stringify(arguments[i])
: arguments[i]) + ' ';
}
console.log('\n' + aimStr);
}
};
exports.md5 = function(str) {
const hash = crypto.createHash('md5');
hash.update(str);
return hash.digest('hex');
};
/*
* 加密
*/
exports.cipher = function(algorithm, key, iv, data) {
key = new Buffer(key);
iv = new Buffer(iv ? iv : 0);
const cipher = crypto.createCipheriv(algorithm, key, iv);
cipher.setAutoPadding(true); // default true
let ciph = cipher.update(data, 'utf8', 'base64');
ciph += cipher.final('base64');
return ciph;
};
/*
* 解密
*/
exports.decipher = function(algorithm, key, iv, crypted) {
key = new Buffer(key);
iv = new Buffer(iv ? iv : '');
const decipher = crypto.createDecipheriv(algorithm, key, iv);
decipher.setAutoPadding(true);
let decoded = decipher.update(crypted, 'base64', 'utf8');
decoded += decipher.final('utf8');
return decoded;
};
exports.getDate = function(flag) {
if (!flag) {
flag = '';
}
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const mytimes = year + flag + month + flag + day;
return mytimes;
};
exports.dynamicSign = function(len) {
len = len || 5;
const chars = 'abcdefghijklmnopqrstuvwxyz';
const maxPos = chars.length;
let sign = '';
for (let i = 0; i < len; i++) {
sign += chars.charAt(Math.floor(Math.random() * maxPos));
}
return sign;
};
exports.toHump = function(str) {
let result = '';
const split = str.split('_');
result += split[0];
for (let i = 1; i < split.length; ++i) {
result += split[i][0].toUpperCase() + split[i].substr(1);
}
return result;
};
exports.tryJsonParse = function(jsonStr, cb) {
try {
cb(null, JSON.parse(jsonStr));
} catch (e) {
cb(e, null);
}
};
exports.mkdir = function(dirpath, dirname) {
// 判断是否是第一次调用
if (typeof dirname === 'undefined') {
if (fs.existsSync(dirpath)) {
return;
}
this.mkdir(dirpath, path.dirname(dirpath));
} else {
// 判断第二个参数是否正常,避免调用时传入错误参数
if (dirname !== path.dirname(dirpath)) {
this.mkdir(dirpath);
return;
}
if (fs.existsSync(dirname)) {
fs.mkdirSync(dirpath);
} else {
this.mkdir(dirname, path.dirname(dirname));
fs.mkdirSync(dirpath);
}
}
console.log('==> dir end', dirpath);
};
/*
* 获取目录下指定后缀的所有文件
* @param dir
* @param ext
* @return {Array}
*/
exports.getAllFiles = function(dir, ext) {
if (!dir) {
return [];
}
const self = this;
let extFiles = [];
const files = fs.readdirSync(dir);
files.forEach(function(file) {
const pathname = path.join(dir, file);
const stat = fs.lstatSync(pathname);
if (stat.isDirectory()) {
extFiles = extFiles.concat(self.getAllFiles(pathname, ext));
} else if (path.extname(pathname) === ext) {
extFiles.push(pathname.replace(cwd, '.'));
}
});
return extFiles;
};
/*
* 获取目录下所有文件夹
*/
exports.getDirs = function(dir) {
if (!dir) {
return [];
}
const components = [];
const files = fs.readdirSync(dir);
files.forEach(function(item, index) {
const stat = fs.lstatSync(dir + '/' + item);
if (stat.isDirectory() === true) {
components.push(item);
}
});
return components;
};
exports.fileExist = function(filePath) {
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
};
exports.delDir = function(path) {
let files = [];
if (fs.existsSync(path)) {
files = fs.readdirSync(path);
files.forEach((file, index) => {
const curPath = path + '/' + file;
if (fs.statSync(curPath).isDirectory()) {
this.delDir(curPath); // 递归删除文件夹
} else {
fs.unlinkSync(curPath); // 删除文件
}
});
fs.rmdirSync(path);
}
};
exports.chmodPath = function(path, mode) {
let files = [];
if (fs.existsSync(path)) {
files = fs.readdirSync(path);
files.forEach((file, index) => {
const curPath = path + '/' + file;
if (fs.statSync(curPath).isDirectory()) {
this.chmodPath(curPath, mode); // 递归删除文件夹
} else {
fs.chmodSync(curPath, mode);
}
});
fs.chmodSync(path, mode);
}
};
/**
* 判断是否是同一天
* @param d1
* @param d2
* @return {boolean}
*/
exports.isSameDay = function(d1, d2) {
return (
d1.getFullYear() === d2.getFullYear() &&
d1.getMonth() === d2.getMonth() &&
d1.getDate() === d2.getDate()
);
};
/*
* 判断是否在有效期
*/
exports.isInDate = function(createDate, days) {
const diffDays = this.diffDays(createDate) + 1;
return diffDays <= days;
};
/*
* differ days
* 返回两个日期相隔的天数
* 按0点算
* 1日0点与2日0点相隔为1天
*/
exports.diffDays = function(createDate) {
const tmp = new Date();
tmp.setHours(0, 0, 0, 0);
createDate.setHours(0, 0, 0, 0);
return (tmp - createDate) / 24 / 3600000;
};
/*
* differ weeks
* 判断两个日期是否在同一周
* add by mumu
*/
exports.isSameWeek = function(old, now) {
const oneDayTime = 1000 * 60 * 60 * 24;
const old_count = parseInt(old.getTime() / oneDayTime);
const now_other = parseInt(now.getTime() / oneDayTime);
return parseInt((old_count + 4) / 7) == parseInt((now_other + 4) / 7);
};
/**
* 读取json文件并解析
* @param path
* @return {any}
*/
exports.loadJson = function(path) {
return JSON.parse(fs.readFileSync(path).toString());
};
exports.getRandomArrayElements = function(arr, count) {
let shuffled = arr.slice(0),
i = arr.length,
min = i - count,
temp,
index;
while (i-- > min) {
index = Math.floor((i + 1) * Math.random());
temp = shuffled[index];
shuffled[index] = shuffled[i];
shuffled[i] = temp;
}
return shuffled.slice(min);
};
exports.getTodayExpireTime = function() {
const endTime = new Date(new Date().setHours(23, 59, 59, 0)) / 1000;
const expiresTime = endTime - Math.floor(new Date().getTime() / 1000);
return expiresTime;
};
exports.objKeySort = function(obj) {
const newkey = Object.keys(obj).sort();
const newObj = {};
for (let i = 0; i < newkey.length; i++) {
newObj[newkey[i]] = obj[newkey[i]];
}
return newObj;
};
exports.serialize = function(obj) {
const str = [];
for (const p in obj) {
if (obj.hasOwnProperty(p)) {
str.push(p + '=' + obj[p]);
}
}
return str.join('&');
};
exports.keepTwoDecimalFull = function(num) {
let result = parseFloat(num);
if (isNaN(result)) {
return false;
}
result = Math.round(num * 100) / 100;
let s_x = result.toString();
let pos_decimal = s_x.indexOf('.');
if (pos_decimal < 0) {
pos_decimal = s_x.length;
s_x += '.';
}
while (s_x.length <= pos_decimal + 2) {
s_x += '0';
}
return s_x;
};
exports.sleep = function(time = 0) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, time);
});
};
/*
* 按行读取文件内容
* 返回:字符串数组
* 参数fReadName:文件名路径
*/
exports.readFileToArr = async function(fReadName) {
const fRead = fs.createReadStream(fReadName);
const objReadline = readline.createInterface({
input: fRead,
});
return new Promise((resolve, reject) => {
const arr = [];
objReadline.on('line', function(line) {
arr.push(line);
});
objReadline.on('close', function() {
resolve(arr);
});
});
};
exports.compareVersion = function(version, bigVersion) {
version = version.split('.');
bigVersion = bigVersion.split('.');
for (let i = 0; i < version.length; i++) {
version[i] = +version[i];
bigVersion[i] = +bigVersion[i];
if (version[i] > bigVersion[i]) {
return false;
} else if (version[i] < bigVersion[i]) {
return true;
}
}
return false;
};
exports.handleVersion = function(version) {
if (!version) return version;
version = version + '';
if (version[0] === 'v') {
return version.substr(1);
}
return version;
};
/*
* 获取本机IP地址
*/
exports.getIPAddress = function() {
const interfaces = require('os').networkInterfaces();
for (const devName in interfaces) {
const iface = interfaces[devName];
for (let i = 0; i < iface.length; i++) {
const alias = iface[i];
if (
alias.family === 'IPv4' &&
alias.address !== '127.0.0.1' &&
!alias.internal
) {
return alias.address;
}
}
}
};
/*
* 判断IP是否在同一网段
*/
exports.isEqualIPAddress = function (addr1, addr2, mask = '255.255.255.0'){
if(!addr1 || !addr2 || !mask){
console.log("各参数不能为空");
return false;
}
var
res1 = [],
res2 = [];
addr1 = addr1.split(".");
addr2 = addr2.split(".");
mask = mask.split(".");
for(var i = 0,ilen = addr1.length; i < ilen ; i += 1){
res1.push(parseInt(addr1[i]) & parseInt(mask[i]));
res2.push(parseInt(addr2[i]) & parseInt(mask[i]));
}
if(res1.join(".") == res2.join(".")){
return true;
}else{
return false;
}
}
/*
* 端口是否被占用
*/
exports.portIsOccupied = function portIsOccupied(port) {
const server = net.createServer().listen(port, '0.0.0.0');
return new Promise((resolve, reject) => {
server.on('listening', () => {
console.log(`the server is runnint on port ${port}`);
server.close();
resolve(false);
});
server.on('error', err => {
if (err.code === 'EADDRINUSE') {
resolve(true);
console.log(`this port ${port} is occupied.try another.`);
} else {
resolve(true);
}
});
});
};

View File

@@ -1,42 +0,0 @@
'use strict';
// 正则校验规则集合
const regRule = require('./regRule');
// 校验规则
const validateRules = {
// 账号校验1手机号&&密码
accountType1: () => {
return {
email: {
type: 'string',
required: true,
allowEmpty: false,
format: regRule.emailReg,
},
password: {
type: 'string',
require: true,
allowEmpty: false,
format: regRule.passwordReg1,
},
};
},
// 账号校验2手机号&&验证码登录
accountType2: () => {
return {
// phone: {
// type: 'string',
// required: true,
// allowEmpty: false,
// format: regRule.phoneReg,
// },
code: {
type: 'string',
required: true,
allowEmpty: false,
},
};
},
};
module.exports = validateRules;

View File

@@ -1,101 +0,0 @@
'use strict';
const path = require('path');
const dayjs = require('dayjs');
const storage = require('./lib/storage');
const config = {
developmentMode: {
default: 'vue',
mode: {
vue: {
hostname: 'localhost',
port: 8080
},
react: {
hostname: 'localhost',
port: 3000
},
ejs: {
hostname: 'localhost',
port: 7068 // The same as the egg port
}
}
},
log: {
file: {
fileName: path.normalize(storage.getStorageDir() + 'logs/electron-' + dayjs().format('YYYY-MM-DD') + '.log'),
level: 'silly', // error, warn, info, verbose, debug, silly
format: '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}',
maxSize: '1048576' // 1048576 (1mb) by default.
}
},
windowsOption: {
width: 980,
height: 650,
minWidth: 800,
minHeight: 650,
webPreferences: {
//webSecurity: false,
contextIsolation: false, // 设置此项为false后才可在渲染进程中使用electron api
nodeIntegration: true
},
frame: true,
//titleBarStyle: 'hidden'
},
egg: {
title: 'electron-egg', // 进程的title属性标识默认你的应用名称-英文)
env: 'prod',
port: 7068,
hostname: 'localhost',
workers: 1
},
autoUpdate: {
windows: false, // windows可以开启macOs 需要签名验证
macOS: false,
linux: false,
options: {
provider: 'generic',
url: 'https://www.coding.net/' // resource dir
},
force: false, // 强制更新
},
awakeProtocol: {
protocol: 'electron-egg', // 自定义协议名(默认你的应用名称-英文)
args: []
},
crashReport: {
submitURL: "",
productName: "",
rateLimit: false,
uploadToServer: false,
ignoreSystemCrashHandler: true,
compress: false
},
remoteUrl: {
enable: false,
url: 'https://discuz.chat/' // Any web url
},
tray: {
title: 'EE程序', // 托盘显示标题
icon: '/asset/images/tray_logo.png' // 托盘图标
}
}
exports.get = function (flag = '', env = 'prod') {
if (flag === 'egg') {
const eggConfig = storage.getEggConfig();
if (env === 'prod' && eggConfig.port) {
config.egg.port = eggConfig.port;
}
return config.egg;
}
if (flag in config) {
return config[flag];
}
return {};
};
exports = module.exports;

View File

@@ -1,336 +0,0 @@
'use strict';
/**
* 前端(html)调用electron功能时建议使用该模块
*
* 定义的function 接收三个参数
* @param event ipcMain事件对象
* @param channel 频道
* @param arg 接收到的消息
*/
const {app, dialog, BrowserWindow, BrowserView, Notification, powerMonitor, screen, nativeTheme} = require('electron');
const path = require('path');
const _ = require('lodash');
const is = require('electron-is');
const config = require('../config');
let myTimer = null;
let browserViewObj = null;
let notificationObj = null;
exports.hello = function (event, channel, arg) {
let newMsg = arg + " +1"
let reply = ''
reply = '收到:' + arg + ',返回:' + newMsg
return reply
}
exports.messageShow = function (event, channel, arg) {
dialog.showMessageBoxSync({
type: 'info', // "none", "info", "error", "question" 或者 "warning"
title: '自定义标题-message',
message: '自定义消息内容',
detail: '其它的额外信息'
})
return '打开了消息框';
}
exports.messageShowConfirm = function (event, channel, arg) {
const res = dialog.showMessageBoxSync({
type: 'info',
title: '自定义标题-message',
message: '自定义消息内容',
detail: '其它的额外信息',
cancelId: 1, // 用于取消对话框的按钮的索引
defaultId: 0, // 设置默认选中的按钮
buttons: ['确认', '取消'], // 按钮及索引
})
let data = (res === 0) ? '点击确认按钮' : '点击取消按钮';
console.log('[electron] [ipc] [example] [messageShowConfirm] 结果:', res);
return data;
}
/**
* 长消息 - 开始
*/
exports.socketMessageStart = function (event, channel, arg) {
// 每隔1秒向前端页面发送消息
// 用定时器模拟
myTimer = setInterval(function(e, c, msg) {
let timeNow = Date.now();
let data = msg + ':' + timeNow;
e.reply(`${c}`, data)
}, 1000, event, channel, arg)
return '开始了'
}
/**
* 长消息 - 停止
*/
exports.socketMessageStop = function () {
clearInterval(myTimer);
return '停止了'
}
/**
* 加载视图内容
*/
exports.loadViewContent = function (event, channel, arg) {
let content = null;
if (arg.type == 'html') {
content = path.join('file://', app.getAppPath(), arg.content)
} else {
content = arg.content;
}
browserViewObj = new BrowserView();
MAIN_WINDOW.setBrowserView(browserViewObj)
browserViewObj.setBounds({
x: 300,
y: 170,
width: 650,
height: 400
});
browserViewObj.webContents.loadURL(content);
return true
}
/**
* 移除视图内容
*/
exports.removeViewContent = function () {
MAIN_WINDOW.removeBrowserView(browserViewObj);
return true
}
/**
* 打开新窗口
*/
exports.createWindow = function (event, channel, arg) {
let content = null;
if (arg.type == 'html') {
content = path.join('file://', app.getAppPath(), arg.content)
} else {
content = arg.content;
}
let winObj = new BrowserWindow({
x: 10,
y: 10,
width: 980,
height: 650
})
winObj.loadURL(content);
return winObj.id
}
/**
* 创建系统通知
*/
exports.sendNotification = function (event, channel, arg) {
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
}
/**
* 电源监控
*/
exports.initPowerMonitor = function (event, channel, arg) {
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
}
/**
* 获取屏幕信息
*/
exports.getScreen = function (event, channel, 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];
}
// console.log('[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;
}
/**
* 获取系统主题
*/
exports.getTheme = function (event, channel, arg) {
let theme = 'system';
if (nativeTheme.shouldUseHighContrastColors) {
theme = 'light';
} else if (nativeTheme.shouldUseInvertedColorScheme) {
theme = 'dark';
}
return theme;
}
/**
* 设置系统主题
*/
exports.setTheme = function (event, channel, arg) {
// TODO 好像没有什么明显效果
nativeTheme.themeSource = arg;
return arg;
}
/**
* 检查是否有新版本
*/
exports.checkForUpdater = function (event, channel, arg) {
const updateConfig = config.get('autoUpdate');
if ((is.windows() && updateConfig.windows) || (is.macOS() && updateConfig.macOS)
|| (is.linux() && updateConfig.linux)) {
const autoUpdater = require('../lib/autoUpdater');
autoUpdater.checkUpdate();
}
return;
}
/**
* 下载新版本
*/
exports.downloadApp = function (event, channel, arg) {
const updateConfig = config.get('autoUpdate');
if ((is.windows() && updateConfig.windows) || (is.macOS() && updateConfig.macOS)
|| (is.linux() && updateConfig.linux)) {
const autoUpdater = require('../lib/autoUpdater');
autoUpdater.download();
}
return;
}

View File

@@ -1,123 +0,0 @@
'use strict';
const updater = require("electron-updater");
const autoUpdater = updater.autoUpdater;
const config = require('../config');
const {app} = require('electron');
const eLogger = require('./eLogger').get();
const helper = require('./helper');
const constant = require('./constant');
const path = require('path');
/**
* 安装模块
*/
exports.setup = function () {
console.log('[electron-lib-autoUpater] [setup]');
const version = app.getVersion();
eLogger.info('[autoUpdater] [setup] current version: ', version);
// 设置下载服务器地址
const updateConfig = config.get('autoUpdate');
let server = updateConfig.options.url;
let lastChar = server.substring(server.length - 1);
server = lastChar === '/' ? server : server + "/";
eLogger.info('[autoUpdater] [setup] server: ', server);
updateConfig.options.url = server;
// 是否后台自动下载
autoUpdater.autoDownload = updateConfig.force ? true : false;
if (process.env.EE_SERVER_ENV == 'local') {
autoUpdater.updateConfigPath = path.join(__dirname, '../../out/dev-app-update.yml')
}
try {
autoUpdater.setFeedURL(updateConfig.options);
} catch (error) {
eLogger.error('[autoUpdater] [setup] setFeedURL error : ', error);
}
autoUpdater.on('checking-for-update', () => {
//sendStatusToWindow('正在检查更新...');
})
autoUpdater.on('update-available', (info) => {
info.status = constant.appUpdaterStatus.available;
info.desc = '有可用更新';
sendStatusToWindow(info);
})
autoUpdater.on('update-not-available', (info) => {
info.status = constant.appUpdaterStatus.noAvailable;
info.desc = '没有可用更新';
sendStatusToWindow(info);
})
autoUpdater.on('error', (err) => {
let info = {
status: constant.appUpdaterStatus.error,
desc: err
}
sendStatusToWindow(info);
})
autoUpdater.on('download-progress', (progressObj) => {
let percentNumber = parseInt(progressObj.percent);
let totalSize = bytesChange(progressObj.total);
let transferredSize = bytesChange(progressObj.transferred);
let text = '已下载 ' + percentNumber + '%';
text = text + ' (' + transferredSize + "/" + totalSize + ')';
let info = {
status: constant.appUpdaterStatus.downloading,
desc: text,
percentNumber: percentNumber,
totalSize: totalSize,
transferredSize: transferredSize
}
sendStatusToWindow(info);
})
autoUpdater.on('update-downloaded', (info) => {
info.status = constant.appUpdaterStatus.downloaded;
info.desc = '下载完成';
sendStatusToWindow(info);
// quit and update
helper.appQuit();
autoUpdater.quitAndInstall();
});
};
exports.checkUpdate = function () {
autoUpdater.checkForUpdates();
}
exports.download = function () {
autoUpdater.downloadUpdate();
}
function sendStatusToWindow(content = {}) {
const textJson = JSON.stringify(content);
eLogger.info(textJson);
MAIN_WINDOW.webContents.send(constant.ipcChannels.appUpdater, textJson);
}
function bytesChange (limit) {
let size = "";
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"
}
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;
}
exports = module.exports;

View File

@@ -1,21 +0,0 @@
module.exports = {
AutoLaunch: {
LOGIN_SETTING_OPTIONS: {
// For Windows
args: [
'--opened-at-login=1'
]
}
},
ipcChannels: {
appMessage: 'app.message',
appUpdater: 'app.updater'
},
appUpdaterStatus: {
error: -1,
available: 1,
noAvailable: 2,
downloading: 3,
downloaded: 4,
}
};

View File

@@ -1,64 +0,0 @@
'use strict';
const path = require('path');
const startCluster = require('egg-cluster').startCluster;
const {app} = require('electron');
exports = module.exports;
/**
* egg server start
*
* @param {Object} argv
* @return {Promise}
*/
exports.start = function (argv) {
const { env } = process;
let baseDir = app.getAppPath();
argv.baseDir = baseDir;
argv.framework = path.join(baseDir, 'node_modules/egg');
const appName = app.getName();
argv.title = argv.title || `egg-server-${appName}`;
// normalize env
env.NODE_ENV = 'production';
// it makes env big but more robust
env.PATH = env.Path = [
// for nodeinstall
path.join(baseDir, 'node_modules/.bin'),
// support `.node/bin`, due to npm5 will remove `node_modules/.bin`
path.join(baseDir, '.node/bin'),
// adjust env for win
env.PATH || env.Path,
].filter(x => !!x).join(path.delimiter);
// cli argv -> process.env.EGG_SERVER_ENV -> `undefined` then egg will use `prod`
if (argv.env) {
// if undefined, should not pass key due to `spwan`, https://github.com/nodejs/node/blob/master/lib/child_process.js#L470
env.EGG_SERVER_ENV = argv.env;
}
// remove unused properties from stringify, alias had been remove by `removeAlias`
const ignoreKeys = [ '_', '$0', 'env', 'daemon', 'stdout', 'stderr', 'timeout', 'ignore-stderr', 'node' ];
const clusterOptions = stringify(argv, ignoreKeys);
const options = JSON.parse(clusterOptions);
// console.log('[lanucher] options:', options)
return new Promise((resolve, reject) => {
startCluster(options, function(){
resolve('success');
});
});
};
function stringify(obj, ignore) {
const result = {};
Object.keys(obj).forEach(key => {
if (!ignore.includes(key)) {
result[key] = obj[key];
}
});
return JSON.stringify(result);
}

View File

@@ -1,36 +0,0 @@
'use strict';
const is = require('electron-is');
const config = require('./config');
const shortcut = require('./lib/shortcut');
const tray = require('./lib/tray');
const awaken = require('./lib/awaken');
const security = require('./lib/security');
const chromeExtension = require('./lib/chromeExtension');
module.exports = async () => {
// shortcut
shortcut.setup();
// tray
tray.setup();
// awaken
awaken.setup();
// security
security.setup();
// chrome extension
await chromeExtension.setup();
// check update
const updateConfig = config.get('autoUpdate');
if (updateConfig.force) {
if ((is.windows() && updateConfig.windows) || (is.macOS() && updateConfig.macOS)
|| (is.linux() && updateConfig.linux)) {
const autoUpdater = require('./lib/autoUpdater');
autoUpdater.checkUpdate();
}
}
}

View File

@@ -1,191 +0,0 @@
'use strict';
const path = require('path');
const fs = require('fs');
const fsPro = require('fs-extra');
const UglifyJS = require('uglify-js');
class CodeCompress {
constructor() {
this.dirs = [
'app',
'electron',
'config'
];
this.basePath = path.normalize(__dirname + '/..');
this.backupCodeDir = path.join(this.basePath, 'run/backup_code');
if (!fs.existsSync(this.backupCodeDir)) {
this.mkdir(this.backupCodeDir);
this.chmodPath(this.backupCodeDir, '777');
}
}
/**
* 备份 app、electron目录代码
*/
backup () {
console.log('[electron] [code_compress] [backup] start');
this.rmBackup();
for (let i = 0; i < this.dirs.length; i++) {
// check code dir
let codeDirPath = path.join(this.basePath, this.dirs[i]);
if (!fs.existsSync(codeDirPath)) {
console.log('[electron] [code_compress] [backup] ERROR: %s is not exist', codeDirPath);
return
}
// copy
let targetDir = path.join(this.backupCodeDir, this.dirs[i]);
console.log('[electron] [code_compress] [backup] targetDir:', targetDir);
if (!fs.existsSync(targetDir)) {
this.mkdir(targetDir);
this.chmodPath(targetDir, '777');
}
fsPro.copySync(codeDirPath, targetDir);
}
console.log('[electron] [code_compress] [backup] success');
}
/**
* 还原代码
*/
restore () {
console.log('[electron] [code_compress] [restore] start');
for (let i = 0; i < this.dirs.length; i++) {
let codeDirPath = path.join(this.backupCodeDir, this.dirs[i]);
let targetDir = path.join(this.basePath, this.dirs[i]);
fsPro.copySync(codeDirPath, targetDir);
}
console.log('[electron] [code_compress] [restore] success');
};
/**
* 压缩代码
*/
compress () {
console.log('[electron] [code_compress] [compress] start');
for (let i = 0; i < this.dirs.length; i++) {
let codeDirPath = path.join(this.basePath, this.dirs[i]);
this.compressLoop(codeDirPath);
}
console.log('[electron] [code_compress] [compress] success');
};
compressLoop (dirPath) {
let files = [];
if (fs.existsSync(dirPath)) {
files = fs.readdirSync(dirPath);
files.forEach((file, index) => {
let curPath = dirPath + '/' + file;
if (fs.statSync(curPath).isDirectory()) {
this.compressLoop(curPath);
} else {
if (path.extname(curPath) === '.js') {
this.miniFile(curPath);
}
}
});
}
}
miniFile (file) {
let code = fs.readFileSync(file, "utf8");
const options = {
mangle: {
toplevel: false,
},
};
let result = UglifyJS.minify(code, options);
fs.writeFileSync(file, result.code, "utf8");
}
/**
* 格式化参数
*/
formatArgvs () {
// argv
let argvs = [];
for (let i = 0; i < process.argv.length; i++) {
const tmpArgv = process.argv[i]
if (tmpArgv.indexOf('--') !== -1) {
argvs.push(tmpArgv.substr(2))
}
}
return argvs;
}
/**
* 移除备份
*/
rmBackup () {
fs.rmdirSync(this.backupCodeDir, {recursive: true});
return;
}
/**
* 检查文件是否存在
*/
fileExist (filePath) {
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
};
mkdir (dirpath, dirname) {
// 判断是否是第一次调用
if (typeof dirname === 'undefined') {
if (fs.existsSync(dirpath)) {
return;
}
this.mkdir(dirpath, path.dirname(dirpath));
} else {
// 判断第二个参数是否正常,避免调用时传入错误参数
if (dirname !== path.dirname(dirpath)) {
this.mkdir(dirpath);
return;
}
if (fs.existsSync(dirname)) {
fs.mkdirSync(dirpath);
} else {
this.mkdir(dirname, path.dirname(dirname));
fs.mkdirSync(dirpath);
}
}
};
chmodPath (path, mode) {
let files = [];
if (fs.existsSync(path)) {
files = fs.readdirSync(path);
files.forEach((file, index) => {
const curPath = path + '/' + file;
if (fs.statSync(curPath).isDirectory()) {
this.chmodPath(curPath, mode); // 递归删除文件夹
} else {
fs.chmodSync(curPath, mode);
}
});
fs.chmodSync(path, mode);
}
};
}
const cc = new CodeCompress();
let argvs = cc.formatArgvs();
console.log('[electron] [code_compress] argvs:', argvs);
if (argvs.indexOf('compress') != -1) {
cc.backup();
cc.compress();
} else if (argvs.indexOf('restore') != -1) {
cc.restore();
}
module.exports = CodeCompress;

View File

@@ -1,45 +0,0 @@
'use strict';
const path = require('path');
const fs = require('fs');
const fsPro = require('fs-extra');
console.log('[electron] [replace_dist] moving frontend asset to egg public dir');
console.log('[electron] [replace_dist] start');
// argv
let distDir = '';
for (let i = 0; i < process.argv.length; i++) {
const tmpArgv = process.argv[i]
if (tmpArgv.indexOf('--dist_dir=') !== -1) {
distDir = tmpArgv.substr(11)
}
}
const fileExist = (filePath) => {
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
};
const sourceDir = path.normalize(distDir);
const targetDir = path.normalize('./app/public');
const sourceIndexFile = path.normalize(sourceDir + '/index.html');
const targetIndexFile = path.normalize( './app/view/index.ejs');
if (!fileExist(sourceIndexFile)) {
console.log('[electron] [replace_dist] ERROR source dir is empty!!!');
return
}
console.log('[electron] [replace_dist] delete target dir:', targetDir);
fs.rmdirSync(targetDir, {recursive: true});
console.log('[electron] [replace_dist] copy :', sourceDir);
fsPro.copySync(sourceDir, targetDir);
// replace ejs
fsPro.copySync(sourceIndexFile, targetIndexFile);
console.log('[electron] [replace_dist] replace index.ejs');
console.log('[electron] [replace_dist] end');

View File

@@ -1,5 +0,0 @@
'use strict';
const path = require('path');
console.log('[electron] [code_compress] ERROR dir is empty!!!');
return;