perf: 优化客户端自动更新
This commit is contained in:
parent
c6ebe994cc
commit
2a8e030fb4
117
electron/main.js
117
electron/main.js
@ -14,7 +14,7 @@ let mainWindow = null,
|
||||
devloadUrl = "",
|
||||
devloadCachePath = path.resolve(__dirname, ".devload"),
|
||||
downloadList = [],
|
||||
downloadCacheFile = path.join(app.getPath('cache'), config.name + '.downloadCache');
|
||||
downloadCacheFile = path.join(app.getPath('cache'), config.name, '.downloadCache');
|
||||
|
||||
if (fs.existsSync(devloadCachePath)) {
|
||||
devloadUrl = fs.readFileSync(devloadCachePath, 'utf8')
|
||||
@ -23,6 +23,39 @@ if (fs.existsSync(downloadCacheFile)) {
|
||||
downloadList = utils.jsonParse(fs.readFileSync(downloadCacheFile, 'utf8'), [])
|
||||
}
|
||||
|
||||
function downloadUpdate(item) {
|
||||
const chain = item.getURLChain()
|
||||
if (chain.length == 0) {
|
||||
return
|
||||
}
|
||||
let currentState = item.getState()
|
||||
if (currentState == "progressing" && item.isPaused()) {
|
||||
currentState = "paused"
|
||||
}
|
||||
//
|
||||
const downloadItem = downloadList.find(item => item.url == chain[0])
|
||||
if (downloadItem && downloadItem.state != currentState) {
|
||||
downloadItem.state = currentState;
|
||||
downloadItem.result = {
|
||||
url: item.getURL(),
|
||||
name: item.getFilename(),
|
||||
savePath: item.getSavePath(),
|
||||
mimeType: item.getMimeType(),
|
||||
totalBytes: item.getTotalBytes(),
|
||||
chain,
|
||||
};
|
||||
fs.writeFileSync(downloadCacheFile, utils.jsonStringify(downloadList), 'utf8');
|
||||
//
|
||||
if (currentState == 'completed') {
|
||||
mainWindow.webContents.send("downloadDone", downloadItem)
|
||||
log.info("下载完成", downloadItem)
|
||||
} else {
|
||||
mainWindow.webContents.send("downloadUpdate", downloadItem)
|
||||
log.info("下载更新", downloadItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createMainWindow() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
@ -69,37 +102,12 @@ function createMainWindow() {
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('will-download', (event, item) => {
|
||||
item.setSavePath(path.join(app.getPath('cache'), item.getFilename()));
|
||||
item.on('done', (event, state) => {
|
||||
try {
|
||||
const info = {
|
||||
state,
|
||||
name: item.getFilename(),
|
||||
url: item.getURL(),
|
||||
chain: item.getURLChain(),
|
||||
savePath: item.getSavePath(),
|
||||
mimeType: item.getMimeType(),
|
||||
totalBytes: item.getTotalBytes(),
|
||||
};
|
||||
mainWindow.webContents.send("downloadDone", info)
|
||||
//
|
||||
if (info.state == "completed") {
|
||||
// 下载完成
|
||||
info.chain.some(url => {
|
||||
let download = downloadList.find(item => item.url == url)
|
||||
if (download) {
|
||||
download.status = "completed"
|
||||
download.info = info
|
||||
}
|
||||
})
|
||||
fs.writeFileSync(downloadCacheFile, utils.jsonStringify(downloadList), 'utf8');
|
||||
} else {
|
||||
// 下载失败
|
||||
info.chain.some(url => {
|
||||
downloadList = downloadList.filter(item => item.url != url)
|
||||
})
|
||||
}
|
||||
} catch (e) { }
|
||||
item.setSavePath(path.join(app.getPath('cache'), config.name, item.getFilename()));
|
||||
item.on('updated', () => {
|
||||
downloadUpdate(item)
|
||||
})
|
||||
item.on('done', () => {
|
||||
downloadUpdate(item)
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -201,26 +209,33 @@ ipcMain.on('inheritClose', (event) => {
|
||||
* @param args {url}
|
||||
*/
|
||||
ipcMain.on('downloadFile', (event, args) => {
|
||||
const download = downloadList.find(({url}) => url == args.url);
|
||||
if (download) {
|
||||
if (download.status == "completed") {
|
||||
if (fs.existsSync(download.info.savePath)) {
|
||||
log.warn("已下载完成", args)
|
||||
mainWindow.webContents.send("downloadDone", download.info)
|
||||
} else {
|
||||
log.info("开始重新下载", args)
|
||||
download.status = "progressing"
|
||||
mainWindow.webContents.downloadURL(args.url);
|
||||
}
|
||||
} else {
|
||||
log.warn("已在下载列表中", args)
|
||||
}
|
||||
} else {
|
||||
log.info("开始下载", args)
|
||||
downloadList.push(Object.assign(args, { status: "progressing" }))
|
||||
mainWindow.webContents.downloadURL(args.url);
|
||||
}
|
||||
event.returnValue = "ok"
|
||||
//
|
||||
let appendJson = {state: "progressing", startTime: utils.Time()}
|
||||
let downloadItem = downloadList.find(({url}) => url == args.url)
|
||||
if (downloadItem) {
|
||||
switch (downloadItem.state) {
|
||||
case "completed":
|
||||
if (fs.existsSync(downloadItem.result.savePath)) { // 下载完成,文件存在
|
||||
log.info("下载已完成", downloadItem)
|
||||
mainWindow.webContents.send("downloadDone", downloadItem)
|
||||
return
|
||||
}
|
||||
break;
|
||||
case "progressing":
|
||||
if (downloadItem.startTime + 480 > utils.Time()) { // 下载中,未超时(超时时间8分钟)
|
||||
log.info("下载已存在", downloadItem)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
downloadItem = Object.assign(downloadItem, appendJson)
|
||||
} else {
|
||||
downloadList.push(downloadItem = Object.assign(args, appendJson))
|
||||
}
|
||||
fs.writeFileSync(downloadCacheFile, utils.jsonStringify(downloadList), 'utf8');
|
||||
mainWindow.webContents.downloadURL(downloadItem.url);
|
||||
log.info("下载开始", downloadItem)
|
||||
})
|
||||
|
||||
/**
|
||||
|
@ -252,4 +252,21 @@ module.exports = {
|
||||
let domain = (weburl + "").match(urlReg);
|
||||
return ((domain != null && domain.length > 0) ? domain[2] : "");
|
||||
},
|
||||
|
||||
/**
|
||||
* 返回10位数时间戳
|
||||
* @param v
|
||||
* @returns {number}
|
||||
* @constructor
|
||||
*/
|
||||
Time(v = undefined) {
|
||||
let time
|
||||
if (typeof v === "string" && this.strExists(v, "-")) {
|
||||
v = v.replace(/-/g, '/');
|
||||
time = new Date(v).getTime();
|
||||
} else {
|
||||
time = new Date().getTime();
|
||||
}
|
||||
return Math.round(time / 1000)
|
||||
},
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div v-if="$Electron" class="common-app-down-link" @click="releasesNotification">
|
||||
<Icon type="md-download"/> {{$L(repoTitle)}}
|
||||
</div>
|
||||
<a v-else class="common-app-down-link" :href="releases.html_url" target="_blank">
|
||||
<a v-else class="common-app-down-link" :href="repoReleases.html_url" target="_blank">
|
||||
<Icon type="md-download"/> {{$L(repoTitle)}}
|
||||
</a>
|
||||
</div>
|
||||
@ -15,7 +15,6 @@ import MarkdownPreview from "./MDEditor/components/preview";
|
||||
import axios from "axios";
|
||||
Vue.component('MarkdownPreview', MarkdownPreview)
|
||||
|
||||
import {Store} from "le5le-store";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
@ -26,19 +25,19 @@ export default {
|
||||
|
||||
repoName: 'kuaifan/dootask',
|
||||
repoData: {},
|
||||
repoStatus: 0, // 0 没有,1有客户端,2客户端有新版本
|
||||
repoReleases: {},
|
||||
|
||||
status: 0, // 0 没有,1有客户端,2客户端有新版本
|
||||
releases: {},
|
||||
downInfo: {},
|
||||
downloadResult: {},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getReleases();
|
||||
//
|
||||
if (this.$Electron) {
|
||||
this.$Electron.ipcRenderer.on('downloadDone', (event, args) => {
|
||||
if (args.name == this.repoData.name) {
|
||||
this.downInfo = args;
|
||||
this.$Electron.ipcRenderer.on('downloadDone', (event, {result}) => {
|
||||
if (result.name == this.repoData.name) {
|
||||
this.downloadResult = result;
|
||||
this.releasesNotification()
|
||||
}
|
||||
})
|
||||
@ -49,10 +48,10 @@ export default {
|
||||
'wsOpenNum',
|
||||
]),
|
||||
repoTitle() {
|
||||
return this.status == 2 ? '更新客户端' : '客户端下载';
|
||||
return this.repoStatus == 2 ? '更新客户端' : '客户端下载';
|
||||
},
|
||||
showButton() {
|
||||
return this.status && !this.$store.state.windowMax768 && ['login', 'manage-dashboard'].includes(this.$route.name)
|
||||
return this.repoStatus && !this.$store.state.windowMax768 && ['login', 'manage-dashboard'].includes(this.$route.name)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -108,7 +107,7 @@ export default {
|
||||
},
|
||||
|
||||
getReleases() {
|
||||
if (this.status > 0) {
|
||||
if (this.repoStatus > 0) {
|
||||
return;
|
||||
}
|
||||
if (this.loadIng > 0) {
|
||||
@ -116,10 +115,11 @@ export default {
|
||||
}
|
||||
//
|
||||
let cache = $A.getStorageJson("cacheAppdown");
|
||||
let timeout = 1800;
|
||||
let timeout = 600;
|
||||
if (cache.time && cache.time + timeout > Math.round(new Date().getTime() / 1000)) {
|
||||
this.releases = cache.data;
|
||||
this.repoReleases = cache.data;
|
||||
this.chackReleases()
|
||||
setTimeout(this.getReleases, timeout * 1000)
|
||||
return;
|
||||
}
|
||||
//
|
||||
@ -127,22 +127,24 @@ export default {
|
||||
axios.get("https://api.github.com/repos/" + this.repoName + "/releases/latest").then(({status, data}) => {
|
||||
this.loadIng--;
|
||||
if (status === 200) {
|
||||
$A.setStorage("cacheAppdown", {
|
||||
cache = {
|
||||
time: Math.round(new Date().getTime() / 1000),
|
||||
data: data
|
||||
});
|
||||
this.releases = data;
|
||||
this.chackReleases();
|
||||
setTimeout(this.getReleases, timeout)
|
||||
}
|
||||
$A.setStorage("cacheAppdown", cache);
|
||||
this.repoReleases = cache.data;
|
||||
this.chackReleases()
|
||||
}
|
||||
setTimeout(this.getReleases, timeout * 1000)
|
||||
}).catch(() => {
|
||||
this.loadIng--;
|
||||
setTimeout(this.getReleases, timeout * 1000)
|
||||
});
|
||||
},
|
||||
|
||||
chackReleases() {
|
||||
let hostName = $A.getDomain(window.systemInfo.apiUrl);
|
||||
if (hostName == "" || hostName == '127.0.0.1') {
|
||||
if (hostName == "" || $A.leftExists(hostName, '127.0.0.1')) {
|
||||
hostName = "public"
|
||||
}
|
||||
if (this.$Electron) {
|
||||
@ -153,18 +155,18 @@ export default {
|
||||
}
|
||||
let artifactName = null;
|
||||
if (match[2] === 'darwin') {
|
||||
artifactName = `${hostName}-${this.releases.tag_name}-mac-${match[3]}.pkg`;
|
||||
artifactName = `${hostName}-${this.repoReleases.tag_name}-mac-${match[3]}.pkg`;
|
||||
} else if (match[2] === 'win32') {
|
||||
artifactName = `${hostName}-${this.releases.tag_name}-win-${match[3]}.exe`;
|
||||
artifactName = `${hostName}-${this.repoReleases.tag_name}-win-${match[3]}.exe`;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
this.repoData = (this.releases.assets || []).find(({name}) => name == artifactName);
|
||||
this.repoData = (this.repoReleases.assets || []).find(({name}) => name == artifactName);
|
||||
if (!this.repoData) {
|
||||
return;
|
||||
}
|
||||
let currentVersion = window.systemInfo.version;
|
||||
let latestVersion = $A.leftDelete(this.releases.tag_name.toLowerCase(), "v")
|
||||
let latestVersion = $A.leftDelete(this.repoReleases.tag_name.toLowerCase(), "v")
|
||||
if (this.compareVersion(latestVersion, currentVersion) === 1) {
|
||||
// 有新版本
|
||||
console.log("New version: " + latestVersion);
|
||||
@ -174,26 +176,23 @@ export default {
|
||||
}
|
||||
} else {
|
||||
// 网页版(提示有客户端下载)
|
||||
this.repoData = (this.releases.assets || []).find(({name}) => $A.strExists(name, hostName));
|
||||
this.repoData = (this.repoReleases.assets || []).find(({name}) => $A.strExists(name, hostName));
|
||||
if (this.repoData) {
|
||||
let latestVersion = $A.leftDelete(this.releases.tag_name.toLowerCase(), "v")
|
||||
let latestVersion = $A.leftDelete(this.repoReleases.tag_name.toLowerCase(), "v")
|
||||
console.log("Exist client: " + latestVersion);
|
||||
this.status = 1;
|
||||
this.repoStatus = 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
releasesNotification() {
|
||||
if (this.downInfo.state != "completed") {
|
||||
return;
|
||||
}
|
||||
$A.modalConfirm({
|
||||
okText: this.$L('立即更新'),
|
||||
onOk: () => {
|
||||
this.installApplication();
|
||||
},
|
||||
onCancel: () => {
|
||||
this.status = 2;
|
||||
this.repoStatus = 2;
|
||||
},
|
||||
render: (h) => {
|
||||
return h('div', {
|
||||
@ -209,12 +208,12 @@ export default {
|
||||
props: {
|
||||
color: 'volcano'
|
||||
}
|
||||
}, this.releases.tag_name)
|
||||
}, this.repoReleases.tag_name)
|
||||
]),
|
||||
h('MarkdownPreview', {
|
||||
class: 'notification-body',
|
||||
props: {
|
||||
initialValue: this.releases.body
|
||||
initialValue: this.repoReleases.body
|
||||
}
|
||||
}),
|
||||
])
|
||||
@ -227,7 +226,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
this.$Electron.ipcRenderer.send('openFile', {
|
||||
path: this.downInfo.savePath
|
||||
path: this.downloadResult.savePath
|
||||
});
|
||||
this.$Electron.ipcRenderer.send('windowQuit');
|
||||
}
|
||||
|
@ -28,7 +28,8 @@
|
||||
}
|
||||
.notification-body {
|
||||
max-height: 210px;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
margin: 18px 0;
|
||||
.markdown-preview {
|
||||
margin: -20px -12px;
|
||||
|
Loading…
x
Reference in New Issue
Block a user