feat: 客户端子窗口数据同步到主窗口

This commit is contained in:
kuaifan 2021-12-28 01:03:38 +08:00
parent ed32f9994d
commit 9bfa680fa4
13 changed files with 137 additions and 75 deletions

80
electron/main.js vendored
View File

@ -42,7 +42,7 @@ function randomString(len) {
return pwd;
}
function createWindow() {
function createMainWindow() {
mainWindow = new BrowserWindow({
width: 1280,
height: 800,
@ -53,6 +53,7 @@ function createWindow() {
contextIsolation: false
}
})
mainWindow.webContents.setUserAgent(mainWindow.webContents.getUserAgent() + " MainTaksWindow/1.0");
if (devloadUrl) {
mainWindow.loadURL(devloadUrl).then(r => {
@ -76,24 +77,24 @@ function createWindow() {
})
}
function createRouter(arg) {
if (!arg) {
function createSubWindow(args) {
if (!args) {
return;
}
if (typeof arg !== "object") {
arg = {
path: arg,
if (typeof args !== "object") {
args = {
path: args,
config: {},
}
}
let name = arg.name || "auto_" + randomString(6);
let name = args.name || "auto_" + randomString(6);
let item = subWindow.find(item => item.name == name);
let browser = item ? item.browser : null;
if (browser) {
browser.focus();
if (arg.force === false) {
if (args.force === false) {
return;
}
} else {
@ -104,11 +105,11 @@ function createRouter(arg) {
parent: mainWindow,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
devTools: arg.devTools !== false,
devTools: args.devTools !== false,
nodeIntegration: true,
contextIsolation: false
}
}, arg.config || {}))
}, args.config || {}))
browser.on('close', function () {
let index = subWindow.findIndex(item => item.name == name);
if (index > -1) {
@ -117,14 +118,15 @@ function createRouter(arg) {
})
subWindow.push({ name, browser })
}
browser.webContents.setUserAgent(browser.webContents.getUserAgent() + " SubTaskWindow/1.0" + (args.userAgent ? (" " + args.userAgent) : ""));
if (devloadUrl) {
browser.loadURL(devloadUrl + '#' + (arg.hash || arg.path)).then(r => {
browser.loadURL(devloadUrl + '#' + (args.hash || args.path)).then(r => {
})
} else {
browser.loadFile('./public/index.html', {
hash: arg.hash || arg.path
hash: args.hash || args.path
}).then(r => {
})
@ -132,10 +134,10 @@ function createRouter(arg) {
}
app.whenReady().then(() => {
createWindow()
createMainWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
if (BrowserWindow.getAllWindows().length === 0) createMainWindow()
})
})
@ -154,8 +156,8 @@ ipcMain.on('inheritClose', (event) => {
event.returnValue = "ok"
})
ipcMain.on('windowRouter', (event, arg) => {
createRouter(arg)
ipcMain.on('windowRouter', (event, args) => {
createSubWindow(args)
event.returnValue = "ok"
})
@ -170,34 +172,45 @@ ipcMain.on('windowClose', (event) => {
event.returnValue = "ok"
})
ipcMain.on('windowSize', (event, arg) => {
ipcMain.on('windowSize', (event, args) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
if (arg.width || arg.height) {
win.setSize(arg.width || win.getSize()[0], arg.height || win.getSize()[1])
if (args.width || args.height) {
win.setSize(args.width || win.getSize()[0], args.height || win.getSize()[1], args.animate === true)
}
if (arg.minWidth || arg.minHeight) {
win.setMinimumSize(arg.minWidth || win.getMinimumSize()[0], arg.minHeight || win.getMinimumSize()[1])
if (args.minWidth || args.minHeight) {
win.setMinimumSize(args.minWidth || win.getMinimumSize()[0], args.minHeight || win.getMinimumSize()[1])
}
if (arg.maxWidth || arg.maxHeight) {
win.setMaximumSize(arg.maxWidth || win.getMaximumSize()[0], arg.maxHeight || win.getMaximumSize()[1])
if (args.maxWidth || args.maxHeight) {
win.setMaximumSize(args.maxWidth || win.getMaximumSize()[0], args.maxHeight || win.getMaximumSize()[1])
}
if (args.center === true) {
win.center();
}
}
event.returnValue = "ok"
})
ipcMain.on('windowMinSize', (event, arg) => {
ipcMain.on('windowMinSize', (event, args) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
win.setMinimumSize(arg.width || win.getMinimumSize()[0], arg.height || win.getMinimumSize()[1])
win.setMinimumSize(args.width || win.getMinimumSize()[0], args.height || win.getMinimumSize()[1])
}
event.returnValue = "ok"
})
ipcMain.on('windowMaxSize', (event, arg) => {
ipcMain.on('windowMaxSize', (event, args) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
win.setMaximumSize(arg.width || win.getMaximumSize()[0], arg.height || win.getMaximumSize()[1])
win.setMaximumSize(args.width || win.getMaximumSize()[0], args.height || win.getMaximumSize()[1])
}
event.returnValue = "ok"
})
ipcMain.on('windowCenter', (event, args) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
win.center();
}
event.returnValue = "ok"
})
@ -212,13 +225,20 @@ ipcMain.on('windowMax', (event) => {
event.returnValue = "ok"
})
ipcMain.on('setDockBadge', (event, arg) => {
ipcMain.on('sendForwardMain', (event, args) => {
if (mainWindow) {
mainWindow.webContents.send(args.channel, args.data)
}
event.returnValue = "ok"
})
ipcMain.on('setDockBadge', (event, args) => {
if(process.platform !== 'darwin'){
// Mac only
return;
}
if (runNum(arg) > 0) {
app.dock.setBadge(String(arg))
if (runNum(args) > 0) {
app.dock.setBadge(String(args))
} else {
app.dock.setBadge("")
}

View File

@ -173,10 +173,10 @@ export default {
},
electronEvents() {
if (!this.isElectron) {
if (!this.$Electron) {
return;
}
const {ipcRenderer} = this.$electron;
const {ipcRenderer} = this.$Electron;
ipcRenderer.send('inheritClose');
ipcRenderer.on('windowClose', () => {
if (this.$Modal.removeLast()) {
@ -188,6 +188,13 @@ export default {
}
ipcRenderer.send('windowHidden');
})
ipcRenderer.on('dispatch', (event, args) => {
if (!this.$store.state.method.isJson(args)) {
return;
}
let {action, data} = args;
this.$store.dispatch(action, data);
})
}
}
}

View File

@ -46,12 +46,6 @@ Vue.component('EDropdown', Dropdown);
Vue.component('EDropdownMenu', DropdownMenu);
Vue.component('EDropdownItem', DropdownItem);
Vue.prototype.isElectron = false;
if (!!__IS_ELECTRON) {
Vue.prototype.isElectron = true;
Vue.prototype.$electron = require('electron')
}
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
@ -96,6 +90,8 @@ Vue.prototype.goBack = function (number) {
};
Vue.prototype.$A = $A;
Vue.prototype.$Electron = !!__IS_ELECTRON ? require('electron') : null;
Vue.config.productionTip = false;
const app = new Vue({
@ -115,3 +111,14 @@ $A.Notice = app.$Notice;
$A.Modal = app.$Modal;
$A.store = app.$store;
$A.L = app.$L;
$A.Electron = app.$Electron;
$A.execMainDispatch = (action, data) => {
const navigator = window.navigator && window.navigator.userAgent
if ($A.Electron && navigator && /\s+SubTaskWindow\//.test(navigator)) {
$A.Electron.ipcRenderer.send('sendForwardMain', {
channel: 'dispatch',
data: {action, data},
});
}
};

View File

@ -1,6 +1,6 @@
<template>
<div v-if="repoStatus && !$store.state.windowMax768" class="common-app-down">
<div v-if="isElectron" class="common-app-down-link" @click="openExternal(repoData.html_url)">
<div v-if="$Electron" class="common-app-down-link" @click="openExternal(repoData.html_url)">
<Icon type="md-download"/> {{$L(repoTitle)}}
</div>
<a v-else class="common-app-down-link" :href="repoData.html_url" target="_blank">
@ -41,7 +41,7 @@ export default {
this.repoStatus = 0;
return;
}
if (!this.isElectron) {
if (!this.$Electron) {
//
this.repoStatus = 1;
return;
@ -183,7 +183,7 @@ export default {
openExternal(url) {
try {
this.$electron.shell.openExternal(url);
this.$Electron.shell.openExternal(url);
} catch (e) {
window.location.href = url;
}

View File

@ -272,8 +272,8 @@ export default {
bookType: bookType || "xlsx"
}
const filename = bookName + "." + (bookType == 'xlml' ? 'xls' : bookType);
if (this.isElectron) {
this.$electron.ipcRenderer.send('saveSheet', data, filename, opts);
if (this.$Electron) {
this.$Electron.ipcRenderer.send('saveSheet', data, filename, opts);
} else {
XLSX.writeFile(data, filename, opts);
}

View File

@ -10,7 +10,7 @@
<div v-else class="login-subtitle">{{$L('输入您的凭证以访问您的帐户。')}}</div>
<div class="login-input">
<Input v-if="isElectron && cacheServerUrl" :value="cacheServerUrl" prefix="ios-globe-outline" size="large" readonly clearable @on-clear="onServerUrlClear"/>
<Input v-if="$Electron && cacheServerUrl" :value="cacheServerUrl" prefix="ios-globe-outline" size="large" readonly clearable @on-clear="onServerUrlClear"/>
<Input v-model="email" prefix="ios-mail-outline" :placeholder="$L('输入您的电子邮件')" size="large" @on-enter="onLogin" @on-blur="onBlur" />
<Input v-model="password" prefix="ios-lock-outline" :placeholder="$L('输入您的密码')" type="password" size="large" @on-enter="onLogin" />
@ -43,7 +43,7 @@
</div>
</div>
<div class="login-right-bottom">
<Button v-if="isElectron" icon="ios-globe-outline" type="primary" @click="onServerUrlInput">{{$L('自定义服务器')}}</Button>
<Button v-if="$Electron" icon="ios-globe-outline" type="primary" @click="onServerUrlInput">{{$L('自定义服务器')}}</Button>
<AppDown/>
</div>
</div>
@ -78,7 +78,7 @@ export default {
mounted() {
this.getDemoAccount();
//
if (!this.isElectron && this.cacheServerUrl) {
if (!this.$Electron && this.cacheServerUrl) {
this.onServerUrlClear();
}
},

View File

@ -259,8 +259,8 @@ export default {
//
document.addEventListener('keydown', this.shortcutEvent);
//
if (this.isElectron) {
this.$electron.ipcRenderer.send('setDockBadge', 0);
if (this.$Electron) {
this.$Electron.ipcRenderer.send('setDockBadge', 0);
}
},
@ -361,14 +361,14 @@ export default {
},
msgAllUnread() {
if (this.isElectron) {
this.$electron.ipcRenderer.send('setDockBadge', this.msgAllUnread + this.dashboardTotal);
if (this.$Electron) {
this.$Electron.ipcRenderer.send('setDockBadge', this.msgAllUnread + this.dashboardTotal);
}
},
dashboardTotal() {
if (this.isElectron) {
this.$electron.ipcRenderer.send('setDockBadge', this.msgAllUnread + this.dashboardTotal);
if (this.$Electron) {
this.$Electron.ipcRenderer.send('setDockBadge', this.msgAllUnread + this.dashboardTotal);
}
},

View File

@ -867,16 +867,10 @@ export default {
}
this.$set(this.columnLoad, column.id, true);
//
this.$store.dispatch("call", {
url: 'project/column/remove',
data: {
column_id: column.id,
},
}).then(({data, msg}) => {
this.$store.dispatch("removeColumn", column.id).then(({data, msg}) => {
$A.messageSuccess(msg);
this.$set(this.columnLoad, column.id, false);
this.$Modal.remove();
this.$store.dispatch("forgetColumn", data.id);
}).catch(({msg}) => {
$A.modalError(msg, 301);
this.$set(this.columnLoad, column.id, false);

View File

@ -112,7 +112,7 @@
transfer>
<Button type="primary">{{$L('我要领取任务')}}</Button>
</Poptip>
<ETooltip v-if="isElectron" :content="$L('新窗口打开')">
<ETooltip v-if="$Electron" :content="$L('新窗口打开')">
<i class="taskfont open" @click="openNewWin">&#xe776;</i>
</ETooltip>
<EDropdown
@ -1122,7 +1122,7 @@ export default {
}).then(({data}) => {
this.$store.dispatch("saveTask", data);
this.$store.dispatch("getDialogOne", data.dialog_id);
if (this.isElectron) {
if (this.$Electron) {
this.resizeDialog();
return;
}
@ -1156,7 +1156,7 @@ export default {
this.sendLoad = false;
this.$store.dispatch("saveTask", data);
this.$store.dispatch("getDialogOne", data.dialog_id);
if (this.isElectron) {
if (this.$Electron) {
this.resizeDialog();
return;
}
@ -1188,7 +1188,7 @@ export default {
},
openNewWin() {
if (!this.isElectron) {
if (!this.$Electron) {
return;
}
let config = {
@ -1202,25 +1202,27 @@ export default {
config.minWidth = 800;
config.minHeight = 600;
}
this.$electron.ipcRenderer.send('windowRouter', {
this.$Electron.ipcRenderer.send('windowRouter', {
name: 'task-' + this.taskDetail.id,
path: "/single/task/" + this.taskDetail.id,
force: false, //
force: false,
devTools: false,
userAgent: "ElectronSubwindow",
config
});
this.$store.dispatch('openTask', 0);
},
resizeDialog() {
if (!this.isElectron) {
if (!this.$Electron) {
return;
}
this.$electron.ipcRenderer.sendSync('windowSize', {
this.$Electron.ipcRenderer.sendSync('windowSize', {
width: Math.max(1100, window.innerWidth),
height: Math.max(720, window.innerHeight),
minWidth: 800,
minHeight: 600
minHeight: 600,
center: true,
});
if (this.msgText) {
let num = 0;

View File

@ -666,7 +666,7 @@ export default {
this.searchKey = '';
this.pid = item.id;
} else {
if (this.isElectron) {
if (this.$Electron) {
this.openSingle(item);
} else {
this.editInfo = item;
@ -676,7 +676,7 @@ export default {
},
openSingle(item) {
this.$electron.ipcRenderer.send('windowRouter', {
this.$Electron.ipcRenderer.send('windowRouter', {
name: 'file-' + item.id,
path: "/single/file/" + item.id,
force: false, //

View File

@ -59,7 +59,7 @@ export default {
$A.modalError({
content: msg,
onOk: () => {
if (this.isElectron) {
if (this.$Electron) {
window.close();
}
}

View File

@ -76,7 +76,7 @@ export default {
$A.modalError({
content: msg,
onOk: () => {
if (this.isElectron) {
if (this.$Electron) {
window.close();
}
}

View File

@ -139,6 +139,8 @@ export default {
* @param data|{key, project_id}
*/
toggleTablePanel({state}, data) {
$A.execMainDispatch("toggleTablePanel", data)
//
let key = data;
let project_id = state.projectId;
if (state.method.isJson(data)) {
@ -295,6 +297,8 @@ export default {
* @param data
*/
saveUserBasic({state}, data) {
$A.execMainDispatch("saveUserBasic", data)
//
let index = state.cacheUserBasic.findIndex(({userid}) => userid == data.userid);
if (index > -1) {
data = Object.assign(state.cacheUserBasic[index], data)
@ -414,6 +418,8 @@ export default {
* @param data
*/
saveFile({state, dispatch}, data) {
$A.execMainDispatch("saveFile", data)
//
if (state.method.isArray(data)) {
data.forEach((file) => {
dispatch("saveFile", file);
@ -435,6 +441,8 @@ export default {
* @param file_id
*/
forgetFile({state, dispatch}, file_id) {
$A.execMainDispatch("forgetFile", file_id)
//
state.files = state.files.filter((file) => file.id != file_id);
state.files.forEach((file) => {
if (file.pid == file_id) {
@ -504,6 +512,8 @@ export default {
* @param data
*/
saveProject({state, dispatch}, data) {
$A.execMainDispatch("saveProject", data)
//
if (state.method.isArray(data)) {
data.forEach((project) => {
dispatch("saveProject", project)
@ -531,6 +541,8 @@ export default {
* @param project_id
*/
forgetProject({state}, project_id) {
$A.execMainDispatch("forgetProject", project_id)
//
let index = state.projects.findIndex(({id}) => id == project_id);
if (index > -1) {
state.projects.splice(index, 1);
@ -562,7 +574,7 @@ export default {
reject({msg: 'Parameter error'});
return;
}
if (state.cacheProjects.length > 0) {
if (state.projects.length === 0 && state.cacheProjects.length > 0) {
state.projects = state.cacheProjects;
}
dispatch("call", {
@ -705,6 +717,8 @@ export default {
* @param data
*/
saveColumn({state, dispatch}, data) {
$A.execMainDispatch("saveColumn", data)
//
if (state.method.isArray(data)) {
data.forEach((column) => {
dispatch("saveColumn", column)
@ -729,6 +743,8 @@ export default {
* @param column_id
*/
forgetColumn({state, dispatch}, column_id) {
$A.execMainDispatch("forgetColumn", column_id)
//
let index = state.columns.findIndex(({id}) => id == column_id);
if (index > -1) {
dispatch('getProjectOne', state.columns[index].project_id)
@ -753,7 +769,7 @@ export default {
reject({msg: 'Parameter error'})
return;
}
if (state.cacheColumns.length > 0) {
if (state.columns.length === 0 && state.cacheColumns.length > 0) {
state.columns = state.cacheColumns;
}
state.projectLoad++;
@ -829,6 +845,8 @@ export default {
* @param data
*/
saveTask({state, dispatch}, data) {
$A.execMainDispatch("saveTask", data)
//
if (state.method.isArray(data)) {
data.forEach((task) => {
dispatch("saveTask", task)
@ -867,6 +885,8 @@ export default {
* @param task_id
*/
forgetTask({state, dispatch}, task_id) {
$A.execMainDispatch("forgetTask", task_id)
//
let index = state.tasks.findIndex(({id}) => id == task_id);
let key = 'tasks';
if (index === -1) {
@ -898,6 +918,8 @@ export default {
* @param dialog_id
*/
increaseTaskMsgNum({state}, dialog_id) {
$A.execMainDispatch("increaseTaskMsgNum", dialog_id)
//
const task = state.tasks.find((task) => task.dialog_id === dialog_id);
if (task) task.msg_num++;
},
@ -913,7 +935,7 @@ export default {
state.tasks = [];
return;
}
if (state.cacheTasks.length > 0) {
if (state.tasks.length == 0 && state.cacheTasks.length > 0) {
state.tasks = state.cacheTasks;
}
if (data.project_id) {
@ -1324,6 +1346,8 @@ export default {
* @param data
*/
saveDialog({state, dispatch}, data) {
$A.execMainDispatch("saveDialog", data)
//
if (state.method.isArray(data)) {
data.forEach((dialog) => {
dispatch("saveDialog", dialog)
@ -1348,6 +1372,8 @@ export default {
* @param data
*/
updateDialogLastMsg({state, dispatch}, data) {
$A.execMainDispatch("updateDialogLastMsg", data)
//
let dialog = state.dialogs.find(({id}) => id == data.dialog_id);
if (dialog) {
dispatch("saveDialog", {
@ -1442,6 +1468,8 @@ export default {
* @param dialog_id
*/
moveDialogTop({state}, dialog_id) {
$A.execMainDispatch("moveDialogTop", dialog_id)
//
const index = state.dialogs.findIndex(({id}) => id == dialog_id);
if (index > -1) {
const tmp = state.method.cloneJSON(state.dialogs[index]);
@ -1456,6 +1484,8 @@ export default {
* @param dialog_id
*/
forgetDialog({state}, dialog_id) {
$A.execMainDispatch("forgetDialog", dialog_id)
//
let index = state.dialogs.findIndex(({id}) => id == dialog_id);
if (index > -1) {
state.dialogs.splice(index, 1);
@ -1479,6 +1509,8 @@ export default {
* @param data
*/
saveDialogMsg({state, dispatch}, data) {
$A.execMainDispatch("saveDialogMsg", data)
//
if (state.method.isArray(data)) {
data.forEach((msg) => {
dispatch("saveDialogMsg", msg)