diff --git a/packages/core/src/shell/scripts/set-system-proxy/index.js b/packages/core/src/shell/scripts/set-system-proxy/index.js index 842c797..8838c1f 100644 --- a/packages/core/src/shell/scripts/set-system-proxy/index.js +++ b/packages/core/src/shell/scripts/set-system-proxy/index.js @@ -37,7 +37,7 @@ async function _winUnsetProxy (exec) { // eslint-disable-next-line no-constant-condition if (true) { const proxyPath = getProxyExePath() - await execFile(proxyPath, ['off']) + await execFile(proxyPath, ['set', '1']) return } const regKey = new Registry({ diff --git a/packages/gui/src/background.js b/packages/gui/src/background.js index 531878c..dcefa2d 100644 --- a/packages/gui/src/background.js +++ b/packages/gui/src/background.js @@ -1,11 +1,10 @@ 'use strict' /* global __static */ import path from 'path' -import { app, protocol, BrowserWindow, Menu, Tray, ipcMain } from 'electron' +import { app, protocol, BrowserWindow, Menu, Tray, ipcMain, dialog } from 'electron' import { createProtocol } from 'vue-cli-plugin-electron-builder/lib' -import bridge from './bridge/index' -import updateHandle from './bridge/update-handle' -import { ebtMain } from './tongji' +import backend from './bridge/backend' +import DevSidecar from '@docmirror/dev-sidecar' import log from './utils/util.log' // eslint-disable-next-line no-unused-vars const isMac = process.platform === 'darwin' @@ -113,7 +112,7 @@ function createWindow () { } async function beforeQuit () { - return bridge.devSidecar.api.shutdown() + return DevSidecar.api.shutdown() } async function quit (app, callback) { if (tray) { @@ -136,12 +135,6 @@ if (!isFirstInstance) { } else { app.on('before-quit', async (event) => { log.info('before-quit') - // event.preventDefault() - // // if (tray) { - // // tray.displayBalloon({ title: '正在关闭,请稍候...', content: '正在关闭中,请稍候。。。' }) - // // } - // await bridge.devSidecar.api.shutdown() - // app.exit() }) app.on('second-instance', (event, commandLine, workingDirectory) => { log.info('new app started', commandLine) @@ -180,24 +173,13 @@ if (!isFirstInstance) { // log.error('Vue Devtools failed to install:', e.toString()) // } } - createWindow() - bridge.init(win) - - let updateUrl = 'https://dev-sidecar.docmirror.cn/update/' - if (process.env.NODE_ENV === 'development') { - Object.defineProperty(app, 'isPackaged', { - get () { - return true - } - }) - updateUrl = 'https://dev-sidecar.docmirror.cn/update/' - // updateUrl = 'http://localhost/dev-sidecar/' + try { + createWindow() + const context = { win, app, beforeQuit, ipcMain, dialog,log } + backend.install(context) // 模块安装 + } catch (err) { + log.info('err', err) } - // 自动更新 - updateHandle(app, win, beforeQuit, updateUrl) - - // 百度分析 - ebtMain(ipcMain, isDevelopment) try { // 最小化到托盘 diff --git a/packages/gui/src/bridge/index.js b/packages/gui/src/bridge/api/backend.js similarity index 90% rename from packages/gui/src/bridge/index.js rename to packages/gui/src/bridge/api/backend.js index f539e33..727bb1c 100644 --- a/packages/gui/src/bridge/index.js +++ b/packages/gui/src/bridge/api/backend.js @@ -1,13 +1,13 @@ import lodash from 'lodash' import DevSidecar from '@docmirror/dev-sidecar' -import { ipcMain, Menu } from 'electron' +import { ipcMain } from 'electron' import fs from 'fs' import JSON5 from 'json5' import path from 'path' -const pk = require('../../package.json') +const pk = require('../../../package.json') const mitmproxyPath = path.join(__dirname, 'mitmproxy.js') process.env.DS_SYSPROXY_PATH = path.join(__dirname, '../extra/sysproxy.exe') -const log = require('../utils/util.log') +const log = require('../../utils/util.log') const getDefaultConfigBasePath = function () { return DevSidecar.api.config.get().server.setting.userBasePath } @@ -171,25 +171,29 @@ function doMerge (defObj, newObj) { return newObj2 } +function invoke (api, param) { + let target = lodash.get(localApi, api) + if (target == null) { + target = lodash.get(DevSidecar.api, api) + } + if (target == null) { + log.info('找不到此接口方法:', api) + } + const ret = target(param) + // log.info('api:', api, 'ret:', ret) + return ret +} + export default { - init (win) { + install ({ win }) { // 接收view的方法调用 ipcMain.handle('apiInvoke', async (event, args) => { const api = args[0] - let target = lodash.get(localApi, api) - if (target == null) { - target = lodash.get(DevSidecar.api, api) - } - if (target == null) { - log.info('找不到此接口方法:', api) - } let param if (args.length >= 2) { param = args[1] } - const ret = target(param) - // log.info('api:', api, 'ret:', ret) - return ret + return invoke(api, param) }) // 注册从core里来的事件,并转发给view DevSidecar.api.event.register('status', (event) => { @@ -206,5 +210,6 @@ export default { // 启动所有 localApi.startup() }, - devSidecar: DevSidecar + devSidecar: DevSidecar, + invoke } diff --git a/packages/gui/src/bridge/backend.js b/packages/gui/src/bridge/backend.js new file mode 100644 index 0000000..3976466 --- /dev/null +++ b/packages/gui/src/bridge/backend.js @@ -0,0 +1,19 @@ +import api from './api/backend' +import tongji from './tongji/backend' +import update from './update/backend' +import fileSelector from './file-selector/backend' + +const modules = { + api, // 核心接口模块 + fileSelector, // 文件选择模块 + tongji, // 统计模块 + update // 自动更新 +} +export default { + install (context) { + for (const module in modules) { + modules[module].install(context) + } + }, + ...modules +} diff --git a/packages/gui/src/view/modules/error/index.js b/packages/gui/src/bridge/error/front.js similarity index 100% rename from packages/gui/src/view/modules/error/index.js rename to packages/gui/src/bridge/error/front.js diff --git a/packages/gui/src/bridge/file-selector/backend.js b/packages/gui/src/bridge/file-selector/backend.js new file mode 100644 index 0000000..63ba83d --- /dev/null +++ b/packages/gui/src/bridge/file-selector/backend.js @@ -0,0 +1,21 @@ +export default { + install (context) { + const { ipcMain, dialog, log } = context + ipcMain.on('file-selector', function (event, message) { + if (message.key === 'open') { + dialog.showOpenDialog({ + properties: ['openFile'], + ...message + }).then(result => { + if (result.canceled) { + event.sender.send('file-selector', { key: 'canceled' }) + } else { + event.sender.send('file-selector', { key: 'selected', value: result.filePaths }) + } + }).catch(err => { + log.error('选择文件失败', err) + }) + } + }) + } +} diff --git a/packages/gui/src/bridge/file-selector/front.js b/packages/gui/src/bridge/file-selector/front.js new file mode 100644 index 0000000..284cdce --- /dev/null +++ b/packages/gui/src/bridge/file-selector/front.js @@ -0,0 +1,23 @@ + +function install (app, api) { + api.fileSelector = { + open (value, options) { + return new Promise((resolve, reject) => { + api.ipc.send('file-selector', { key: 'open', value: value, ...options }) + api.ipc.on('file-selector', (event, message) => { + console.log('selector', message) + if (message.key === 'selected') { + resolve(message.value) + } else { + reject(new Error('没有选择文件')) + } + api.ipc.on('file-selector', () => {}) + }) + }) + } + } +} + +export default { + install +} diff --git a/packages/gui/src/bridge/front.js b/packages/gui/src/bridge/front.js new file mode 100644 index 0000000..18e360a --- /dev/null +++ b/packages/gui/src/bridge/front.js @@ -0,0 +1,21 @@ +// import api from './api/front' +import error from './error/front' +import tongji from './tongji/front' +import update from './update/front' +import fileSelector from './file-selector/front' + +const modules = { + // api, // 核心接口模块 + error, + fileSelector, // 文件选择模块 + tongji, // 统计模块 + update // 自动更新 +} +export default { + install (app, api, router) { + for (const module in modules) { + modules[module].install(app, api, router) + } + }, + ...modules +} diff --git a/packages/gui/src/bridge/tongji/backend.js b/packages/gui/src/bridge/tongji/backend.js new file mode 100644 index 0000000..294badb --- /dev/null +++ b/packages/gui/src/bridge/tongji/backend.js @@ -0,0 +1,55 @@ + +/** + * first step + * @param {*} ipcMain + */ +const ebtMain = (ipcMain) => { + const isDevelopment = process.env.NODE_ENV !== 'production' + const request = require('request') + /* istanbul ignore else */ + if (!(ipcMain && ipcMain.on)) { + throw new TypeError('require ipcMain') + } + + // step 2 + ipcMain.on('electron-baidu-tongji-message', (event, arg) => { + // electron 生产模式下是直接请求文件系统,没有 http 地址 + // 前台拿不到 hm.js 的内容 + request({ + url: `https://hm.baidu.com/hm.js?${arg}`, + method: 'GET', + headers: { + Referer: 'https://hm.baidu.com/' + } + }, + (err, response, body) => { + if (err) { + console.error('百度统计请求出错', err) + return + } + const rource = '(h.c.b.su=h.c.b.u||document.location.href),h.c.b.u=f.protocol+"//"+document.location.host+' + /* istanbul ignore else */ + if (body && body.indexOf(rource) >= 0) { + // step 3 + let text = body + + /* istanbul ignore else */ + if (!isDevelopment) { + // 百度统计可能改规则了,不统计 file:// 开始的请求 + // 这里强制替换为 https + const target = '(h.c.b.su=h.c.b.u||"https://"+c.dm[0]+a[1]),h.c.b.u="https://"+c.dm[0]+' + const target2 = '"https://"+c.dm[0]+window.location.pathname+window.location.hash' + text = body.replace(rource, target).replace(/window.location.href/g, target2) + } + console.log('baidu tonji: ret') + event.sender.send('electron-baidu-tongji-reply', { text, isDevelopment }) + } + }) + }) +} + +export default { + install (context) { + ebtMain(context.ipcMain) + } +} diff --git a/packages/gui/src/bridge/tongji/front.js b/packages/gui/src/bridge/tongji/front.js new file mode 100644 index 0000000..023db8b --- /dev/null +++ b/packages/gui/src/bridge/tongji/front.js @@ -0,0 +1,62 @@ + +/** + * second step + * @param {*} ipcRenderer + * @param {*} siteId + * @param {*} router + */ +const ebtRenderer = (ipcRenderer, siteId, router) => { + /* istanbul ignore else */ + if (!(ipcRenderer && ipcRenderer.on && ipcRenderer.send)) { + throw new TypeError('require ipcRenderer') + } + + /* istanbul ignore else */ + if (!(siteId && typeof siteId === 'string')) { + throw new TypeError('require siteId') + } + + // step 4 + ipcRenderer.on('electron-baidu-tongji-reply', (_, { text, isDevelopment }) => { + console.log('electron-baidu-tongji-reply') + /* istanbul ignore else */ + if (isDevelopment) { document.body.classList.add('electron-baidu-tongji_dev') } + + window._hmt = window._hmt || [] + + const hm = document.createElement('script') + hm.text = text + + const head = document.getElementsByTagName('head')[0] + head.appendChild(hm) + + // Vue单页应用时,监听router的每次变化 + // 把虚拟的url地址赋给百度统计的API接口 + + /* istanbul ignore else */ + if (router && router.beforeEach) { + router.beforeEach((to, _, next) => { + /* istanbul ignore else */ + if (to.path) { + window._hmt.push(['_trackPageview', '/#' + to.fullPath]) + console.log('baidu trace', to.fullPath) + } + + next() + }) + } + }) + + // step 1 + ipcRenderer.send('electron-baidu-tongji-message', siteId) +} + +export default { + install (app, api, router) { + const BAIDU_SITE_ID = 'f2d170ce560aef0005b689f28697f852' + // 百度统计 + const { ipcRenderer } = require('electron') + ebtRenderer(ipcRenderer, BAIDU_SITE_ID, router) + }, + ebtRenderer +} diff --git a/packages/gui/src/bridge/update-handle.js b/packages/gui/src/bridge/update/backend.js similarity index 85% rename from packages/gui/src/bridge/update-handle.js rename to packages/gui/src/bridge/update/backend.js index 1dc2d2f..2cb0efa 100644 --- a/packages/gui/src/bridge/update-handle.js +++ b/packages/gui/src/bridge/update/backend.js @@ -1,6 +1,5 @@ -import { ipcMain, dialog } from 'electron' +import { ipcMain } from 'electron' import { autoUpdater } from 'electron-updater' -import log from '../utils/util.log' import path from 'path' // win是所有窗口的引用 // const path = require('path') // 引入path模块 @@ -8,7 +7,7 @@ import path from 'path' // eslint-disable-next-line no-unused-vars const isMac = process.platform === 'darwin' // 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写 -function updateHandle (app, win, beforeQuit, updateUrl) { +function updateHandle (app, win, beforeQuit, updateUrl,log) { // // 更新前,删除本地安装包 ↓ // const updaterCacheDirName = 'dev-sidecar-updater' // const updatePendingPath = path.join(autoUpdater.app.baseCachePath, updaterCacheDirName, 'pending') @@ -95,4 +94,20 @@ function updateHandle (app, win, beforeQuit, updateUrl) { log.info('auto update inited') return autoUpdater } -export default updateHandle + +export default { + install (context) { + const { app, win, beforeQuit,log } = context + let updateUrl = 'https://dev-sidecar.docmirror.cn/update/' + if (process.env.NODE_ENV === 'development') { + Object.defineProperty(app, 'isPackaged', { + get () { + return true + } + }) + updateUrl = 'https://dev-sidecar.docmirror.cn/update/' + // updateUrl = 'http://localhost/dev-sidecar/' + } + updateHandle(app, win, beforeQuit, updateUrl,log) + } +} diff --git a/packages/gui/src/view/modules/update/index.js b/packages/gui/src/bridge/update/front.js similarity index 100% rename from packages/gui/src/view/modules/update/index.js rename to packages/gui/src/bridge/update/front.js diff --git a/packages/gui/src/main.js b/packages/gui/src/main.js index d78a8c4..87e11ff 100644 --- a/packages/gui/src/main.js +++ b/packages/gui/src/main.js @@ -7,9 +7,6 @@ import VueRouter from 'vue-router' import routes from './view/router' import DsContainer from './view/components/container' import './view/style/index.scss' -import { ipcRenderer } from 'electron' - -const tongji = require('./tongji') Vue.config.productionTip = false Vue.use(antd) @@ -28,12 +25,7 @@ view.initApi().then(async (api) => { router, render: h => h(App) }).$mount('#app') - - const BAIDU_SITE_ID = 'f2d170ce560aef0005b689f28697f852' - // 百度统计 - tongji.ebtRenderer(ipcRenderer, BAIDU_SITE_ID, router) - - view.initModules(app) + view.initModules(app, router) }) // fix vue-router NavigationDuplicated diff --git a/packages/gui/src/tongji.js b/packages/gui/src/tongji.js deleted file mode 100644 index 6ca5aa0..0000000 --- a/packages/gui/src/tongji.js +++ /dev/null @@ -1,103 +0,0 @@ - -const request = require('request') - -/** - * first step - * @param {*} ipcMain - */ -const ebtMain = (ipcMain, isDevelopment) => { - /* istanbul ignore else */ - if (!(ipcMain && ipcMain.on)) { - throw new TypeError('require ipcMain') - } - - // step 2 - ipcMain.on('electron-baidu-tongji-message', (event, arg) => { - // electron 生产模式下是直接请求文件系统,没有 http 地址 - // 前台拿不到 hm.js 的内容 - request({ - url: `https://hm.baidu.com/hm.js?${arg}`, - method: 'GET', - headers: { - Referer: 'https://hm.baidu.com/' - } - }, - (err, response, body) => { - if (err) { - console.error('百度统计请求出错', err) - return - } - const rource = '(h.c.b.su=h.c.b.u||document.location.href),h.c.b.u=f.protocol+"//"+document.location.host+' - /* istanbul ignore else */ - if (body && body.indexOf(rource) >= 0) { - // step 3 - let text = body - - /* istanbul ignore else */ - if (!isDevelopment) { - // 百度统计可能改规则了,不统计 file:// 开始的请求 - // 这里强制替换为 https - const target = '(h.c.b.su=h.c.b.u||"https://"+c.dm[0]+a[1]),h.c.b.u="https://"+c.dm[0]+' - const target2 = '"https://"+c.dm[0]+window.location.pathname+window.location.hash' - text = body.replace(rource, target).replace(/window.location.href/g, target2) - } - console.log('baidu tonji: ret') - event.sender.send('electron-baidu-tongji-reply', { text, isDevelopment }) - } - }) - }) -} - -/** - * second step - * @param {*} ipcRenderer - * @param {*} siteId - * @param {*} router - */ -const ebtRenderer = (ipcRenderer, siteId, router) => { - /* istanbul ignore else */ - if (!(ipcRenderer && ipcRenderer.on && ipcRenderer.send)) { - throw new TypeError('require ipcRenderer') - } - - /* istanbul ignore else */ - if (!(siteId && typeof siteId === 'string')) { - throw new TypeError('require siteId') - } - - // step 4 - ipcRenderer.on('electron-baidu-tongji-reply', (_, { text, isDevelopment }) => { - console.log('electron-baidu-tongji-reply') - /* istanbul ignore else */ - if (isDevelopment) { document.body.classList.add('electron-baidu-tongji_dev') } - - window._hmt = window._hmt || [] - - const hm = document.createElement('script') - hm.text = text - - const head = document.getElementsByTagName('head')[0] - head.appendChild(hm) - - // Vue单页应用时,监听router的每次变化 - // 把虚拟的url地址赋给百度统计的API接口 - - /* istanbul ignore else */ - if (router && router.beforeEach) { - router.beforeEach((to, _, next) => { - /* istanbul ignore else */ - if (to.path) { - window._hmt.push(['_trackPageview', '/#' + to.fullPath]) - console.log('baidu trace', to.fullPath) - } - - next() - }) - } - }) - - // step 1 - ipcRenderer.send('electron-baidu-tongji-message', siteId) -} - -module.exports = { ebtMain, ebtRenderer } diff --git a/packages/gui/src/view/index.js b/packages/gui/src/view/index.js index 45fb91e..153dbde 100644 --- a/packages/gui/src/view/index.js +++ b/packages/gui/src/view/index.js @@ -1,5 +1,5 @@ import api, { apiInit } from './api' -import modules from './modules' +import modules from '../bridge/front' import status from './status' export default { initApi: apiInit, @@ -9,7 +9,7 @@ export default { Vue.prototype.$global = { setting } await status.install(api) }, - initModules (app) { - modules.install(app, api) + initModules (app, router) { + modules.install(app, api, router) } } diff --git a/packages/gui/src/view/modules/index.js b/packages/gui/src/view/modules/index.js deleted file mode 100644 index 522310a..0000000 --- a/packages/gui/src/view/modules/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import update from './update' -import error from './error' - -export default { - install (app, api) { - error.install(app, api) - update.install(app, api) - } -} diff --git a/packages/gui/src/view/pages/server.vue b/packages/gui/src/view/pages/server.vue index bf8233b..926e901 100644 --- a/packages/gui/src/view/pages/server.vue +++ b/packages/gui/src/view/pages/server.vue @@ -38,8 +38,8 @@