Skip to content

Commit 3bb692b

Browse files
committed
①增加自动更新功能②程序打包成安装包(Mac与Windows)③优化代码
1 parent c46e5cd commit 3bb692b

27 files changed

+1595
-84
lines changed

app/crashTempate.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const electron = require('electron')
2+
const crashReporter = electron.crashReporter
3+
4+
5+
exports.start = function() {
6+
crashReporter.start({
7+
productName: 'xcel',
8+
companyName: 'o2team',
9+
submitURL: 'http://localhost:4000/crash/',
10+
autoSubmit: true
11+
})
12+
}

app/electron.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@
22

33
const electron = require('electron')
44
const path = require('path')
5-
const menuTemplate = require("./menuTemplate")
6-
const ipcMainSets = require("./ipcMainSets")
7-
// const config = require('../config');
8-
5+
const menuTemplate = require('./menuTemplate')
6+
const ipcMainSets = require('./ipcMainSets')
7+
const crashTempate = require('./crashTempate')
98
const app = electron.app
109
const BrowserWindow = electron.BrowserWindow
1110
const Menu = electron.Menu
12-
let mainWindow
13-
let backgroundWindow
14-
var windowBounds = {}
1511

12+
let mainWindow // 主窗口
13+
let backgroundWindow // 执行耗时运算的 背后窗口
14+
let updateWindow // 更新的下载窗口
15+
var windowBounds = {} // 主窗口的尺寸信息
1616
let config = {}
17+
1718
if (process.env.NODE_ENV === 'development') {
1819
config = require('../config')
1920
config.mainUrl = `http://localhost:${config.port}`
@@ -23,7 +24,7 @@ if (process.env.NODE_ENV === 'development') {
2324
}
2425
config.backUrl = `file://${__dirname}/dist/background/index.html`
2526
config.isDev = process.env.NODE_ENV === 'development'
26-
console.log("主进程pid:", process.pid)
27+
2728

2829
function createMainWindow () {
2930
var win = new BrowserWindow({
@@ -74,6 +75,7 @@ function createBackgroundWindow () {
7475
return win
7576
}
7677

78+
7779
app.on('ready', () => {
7880
console.log("ready")
7981
mainWindow = createMainWindow()
@@ -99,3 +101,7 @@ app.on('activate', () => {
99101
backgroundWindow = createBackgroundWindow()
100102
}
101103
})
104+
105+
crashTempate.start()
106+
107+
console.log("主进程pid:", process.pid)

app/ipcMainSets.js

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,136 @@ const shortid = require('shortid')
22
const xlsx = require('xlsx')
33
const path = require('path')
44
const electron = require('electron')
5+
const os = require('os')
56
const app = electron.app
67
const BrowserWindow = electron.BrowserWindow
78
const dialog = electron.dialog
89
const ipcMain = electron.ipcMain
9-
let savePath = ''
10-
10+
const shell = electron.shell
11+
let savePath = '',
12+
downloadsPath = app.getPath('downloads'),
13+
platform = os.platform() + '_' + os.arch(),
14+
version = app.getVersion(),
15+
updateWindow,
16+
updateItem,
17+
downloadsFullPath
18+
console.log(version)
1119
shortid.characters('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$@')
1220

1321
module.exports = function(mainWindow, backgroundWindow) {
1422

23+
ipcMain.on('will-download-handler', (ipcEvent, arg) => {
24+
if(!updateWindow || updateWindow.isDestroyed()) {
25+
updateWindow = createUpdateWindow()
26+
}
27+
if(!updateWindow.isDestroyed()) {
28+
updateWindow.webContents.session.removeAllListeners()
29+
updateWindow.webContents.session.on('will-download', (event, item, webContents) => {
30+
updateItem = item
31+
downloadsFullPath = downloadsPath + item.getFilename()
32+
item.setSavePath(downloadsFullPath)
33+
console.log('getTotalBytes', item.getTotalBytes())
34+
item.on('updated', (event, state) => {
35+
if(state === 'interrupted') {
36+
console.log('Download is interrupted but can be resumed')
37+
} else if (state === 'progressing') {
38+
if(item.isPaused()) {
39+
console.log('Download is paused')
40+
} else {
41+
console.log(`Received bytes: ${item.getReceivedBytes()}`)
42+
}
43+
}
44+
if(!updateWindow.isDestroyed()) {
45+
updateWindow.webContents.send('will-download-response', {
46+
curReceivedBytes: item.getReceivedBytes(),
47+
totalBytes: item.getTotalBytes(),
48+
downloadStatus: state
49+
})
50+
}
51+
})
52+
53+
item.once('done', (event, state) => {
54+
if(state === 'completed') {
55+
console.log('Download successfully')
56+
if( !shell.openItem(downloadsFullPath) ){
57+
shell.showItemInFolder(downloadsPath)
58+
}
59+
if(!updateWindow.isDestroyed()) {
60+
updateWindow.close()
61+
}
62+
} else {
63+
console.log(`Download failed: ${state}`)
64+
}
65+
item.removeAllListeners()
66+
updateItem.removeAllListeners()
67+
updateItem = null
68+
item = null
69+
})
70+
})
71+
if(process.env.NODE_ENV === 'development') {
72+
updateWindow.webContents.downloadURL(arg.url)
73+
console.log(arg.url)
74+
// updateWindow.webContents.downloadURL('https://jdc.jd.com/lab/xcel/xcel/XCel-darwin-x64.zip')
75+
} else {
76+
// updateWindow.webContents.downloadURL()
77+
}
78+
}
79+
})
80+
function createUpdateWindow () {
81+
var win = new BrowserWindow({
82+
height: 160,
83+
width: 550,
84+
title: '下载最新版的XCel',
85+
backgroundColor: "#f5f5f5"
86+
})
87+
win.loadURL(`file://${__dirname}/dist/update/index.html`)
88+
win.once('closed', closeUpdateWindow)
89+
return win
90+
}
91+
function closeUpdateWindow (event) {
92+
console.log(updateItem)
93+
if(updateItem) {
94+
updateItem.removeAllListeners()
95+
updateItem.cancel() // cancel 后,DownloadItem 就是 null 了
96+
updateItem = null
97+
}
98+
}
99+
ipcMain.on('update-switch', (event, arg) => {
100+
if(updateItem) {
101+
let status = ''
102+
if(updateItem.isPaused()) {
103+
if(updateItem.canResume()) {
104+
updateItem.resume()
105+
status = '暂停'
106+
}
107+
} else {
108+
updateItem.pause()
109+
status = '继续'
110+
}
111+
event.sender.send('update-switch-response', {
112+
text: status
113+
})
114+
}
115+
})
116+
117+
ipcMain.on('update-cancel', (event, arg) => {
118+
if(updateItem) {
119+
updateItem.removeAllListeners()
120+
updateItem.cancel()
121+
updateWindow.close()
122+
updateItem = null
123+
}
124+
})
125+
126+
ipcMain.on('update-checkout', (event, arg) => {
127+
if(updateItem) {
128+
updateItem.cancel()
129+
shell.openExternal('https://xcel.aotu.io/')
130+
updateWindow.close()
131+
updateItem = null
132+
}
133+
})
134+
15135
ipcMain.on("readFile-response", (event, arg) => {
16136
console.log("触发readFile-response")
17137
mainWindow.webContents.send("readFile-response", arg)

app/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
{
22
"name": "xcel",
33
"product": "XCel",
4-
"version": "1.0.0",
4+
"version": "1.2.1",
55
"description": "An ultimate excel data filter",
66
"author": "AOTULabs <[email protected]>",
77
"main": "electron.js",
88
"dependencies": {
9+
"compare-versions": "^3.0.0",
910
"font-awesome": "^4.6.3",
1011
"lodash": "^4.17.2",
12+
"markdown": "^0.5.0",
1113
"moment": "^2.15.0",
14+
"request": "^2.79.0",
1215
"shortid": "^2.2.6",
1316
"vue": "^2.0.0",
1417
"vue-electron": "^1.0.0",
15-
"vue-resource": "^1.0.3",
1618
"vue-router": "^2.0.0",
1719
"vuex": "^1.0.0",
1820
"xlsx": "^0.8.0"

app/src/App.vue

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,66 @@
66
<keep-alive>
77
<router-view></router-view>
88
</keep-alive>
9+
<update-dialog></update-dialog>
910
</div>
1011
</template>
1112

1213
<script>
14+
1315
import windowTop from './components/common/WindowTop'
16+
import crashTempate from '../crashTempate'
17+
import UpdateDialog from './components/common/UpdateDialog'
18+
import { getColSelectDialogStatus, getUpdateDialogStatus, getSideBarStatus } from './vuex/getters'
19+
import { setColSelectDialogStatus, toggleUpdateDialog, toggleSideBar } from './vuex/actions'
1420
21+
// crashTempate.start()
1522
export default {
1623
components: {
17-
windowTop
24+
windowTop,
25+
UpdateDialog
26+
},
27+
vuex: {
28+
getters: {
29+
isShowColSelectDialog: getColSelectDialogStatus,
30+
isShowUpdateDialog: getUpdateDialogStatus,
31+
isShowSideBar: getSideBarStatus
32+
},
33+
actions: {
34+
setColSelectDialogStatus,
35+
toggleUpdateDialog,
36+
toggleSideBar
37+
}
38+
},
39+
mounted() {
40+
document.body.addEventListener('keyup', this.keyupHandler , false)
41+
},
42+
methods: {
43+
keyupHandler(event) {
44+
let keyCode = event.keyCode
45+
if(keyCode === 27) {
46+
if(this.isShowUpdateDialog) {
47+
this.toggleUpdateDialog(false)
48+
return
49+
}
50+
if(this.isShowColSelectDialog) {
51+
this.setColSelectDialogStatus(false)
52+
return
53+
}
54+
if(this.isShowSideBar) {
55+
this.toggleSideBar(false)
56+
return
57+
}
58+
}
59+
}
1860
}
1961
}
2062
</script>
2163

22-
2364
<style lang="scss">
2465
@import './components/common/assets/common.scss';
2566
@import './components/common/assets/content.scss';
2667
@import './components/common/assets/table.scss';
2768
@import './components/common/assets/tabs.scss';
2869
@import './components/common/assets/select.scss';
70+
@import './components/common/assets/markdown.scss';
2971
</style>

app/src/components/FirstScreenPageView.vue

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
<main :class="{isShowSideBar: sideBarStatus}">
55
<excel-display></excel-display>
66
</main>
7-
<v-footer class="footer"></v-footer>
7+
<keep-alive>
8+
<v-footer class="footer"></v-footer>
9+
</keep-alive>
810
<filter-panel id="filter-panel"></filter-panel>
911
<side-bar class="sibebar"></side-bar>
1012
<col-sel-dialog></col-sel-dialog>
@@ -20,7 +22,6 @@
2022
import ExcelDisplay from './FirstScreenPageView/ExcelDisplay'
2123
import FilterPanel from './FirstScreenPageView/FilterPanel'
2224
import ColSelDialog from './FirstScreenPageView/ColSelDialog'
23-
import { toggleSideBar } from '../vuex/actions'
2425
import { getSideBarStatus } from '../vuex/getters'
2526
import os from 'os'
2627
console.log('主页面pid:', process.pid)
@@ -43,9 +44,6 @@
4344
vuex: {
4445
getters: {
4546
sideBarStatus: getSideBarStatus
46-
},
47-
actions: {
48-
toggleSideBar
4947
}
5048
}
5149
}

app/src/components/FirstScreenPageView/ColSelDialog.vue

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="col_sel_modal" @keyup :class="{'active': colSelectDialogStatus}">
2+
<div class="col_sel_modal" :class="{'active': colSelectDialogStatus}">
33
<div class="col_sel_dialog">
44
<div class="col_sel_dialog_header">
55
<div>
@@ -70,17 +70,6 @@ import { ipcRenderer } from 'electron'
7070
setColSelectDialogStatus
7171
}
7272
},
73-
mounted(){
74-
document.body.addEventListener('keyup', (event) => {
75-
let keyCode = event.keyCode
76-
if(keyCode === 27) {
77-
this.closeDialog()
78-
}
79-
else if(keyCode === 13) {
80-
this.submit()
81-
}
82-
}, false)
83-
},
8473
computed: {
8574
selectedGroupStr() {
8675
return this.selectedGroup.map((item, index) => {

app/src/components/InstructionsPageView/Instructions.vue

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<table class="table is_bordered is_striped is_narrow">
5656
<tr>
5757
<th>大于(或等于)</th>
58-
<td>对数字和字母进行大于(或等于)比较操作,列的值若大于指定值就保留/该行数据。其中字母之间的比较是根据 <a @click="openURL('ascii')">ASCII表</a> 进行比较(如:a > A)</td>
58+
<td>对数字和字母进行大于(或等于)比较操作,列的值若大于指定值就保留/该行数据。其中字母之间的比较是根据 <a @click="openExternal('ascii')">ASCII表</a> 进行比较(如:a > A)</td>
5959
</tr>
6060
<tr>
6161
<th>小于(或等于)</th>
@@ -140,9 +140,9 @@
140140

141141
<!-- 2.4 -->
142142
<h3>联系</h3>
143-
<p>如遇软件使用上的问题,请联系 <a @click="openURL('aotu')">凹凸实验室</a>。同时,也欢迎你提出宝贵的意见。</p>
143+
<p>如遇软件使用上的问题,请联系 <a @click="openExternal('aotu')">凹凸实验室</a>。同时,也欢迎你提出宝贵的意见。</p>
144144
<p>咚咚:刘健超</p>
145-
<p>问题提交地址(可选):<a @click="openURL('github')">https://github.com/JChehe/XCel/issues</a></p>
145+
<p>问题提交地址:<a @click="openExternal('issues')">问题提交链接</a></p>
146146
<div>
147147
<img src="./assets/qrcode.jpg" alt="凹凸实验室二维码">
148148
</div>
@@ -152,20 +152,10 @@
152152

153153

154154
<script>
155-
const { shell } = require('electron')
156-
const ASCII_URL = 'http://tool.oschina.net/commons?type=4'
157-
const AOTU_URL = 'https://aotu.io/'
158-
const GITHUB = 'https://github.com/JChehe/XCel/issues'
155+
import { openExternal } from '../../utils/openExternal'
159156
export default {
160157
methods: {
161-
openURL(args){
162-
switch (args){
163-
case 'ascii': shell.openExternal(ASCII_URL); break;
164-
case 'aotu': shell.openExternal(AOTU_URL); break;
165-
case 'github': shell.openExternal(GITHUB); break;
166-
default: console.log('无该地址');
167-
}
168-
}
158+
openExternal
169159
}
170160
}
171161
</script>

0 commit comments

Comments
 (0)