diff --git a/electron/electron.js b/electron/electron.js index 43dc46579..047b1e3b1 100644 --- a/electron/electron.js +++ b/electron/electron.js @@ -72,14 +72,10 @@ let screenshotObj = null, // 窗口实例变量 let mainWindow = null, mainTray = null, - preloadWindow = null, mediaWindow = null; -// 独立子窗口管理 -let childWindow = []; - // 多窗口 Tab 管理 -// Map +// Map let webTabWindows = new Map(); let webTabWindowIdCounter = 1; // 标签名称到标签位置的映射,用于复用已存在的标签 @@ -435,241 +431,6 @@ function createUpdaterWindow(updateTitle) { } } -/** - * 创建预窗口 - */ -function preCreateChildWindow() { - if (preloadWindow) { - return; - } - - const browser = new BrowserWindow({ - width: 360, - height: 360, - minWidth: 360, - minHeight: 360, - center: true, - show: false, - autoHideMenuBar: true, - backgroundColor: utils.getDefaultBackgroundColor(), - webPreferences: { - preload: path.join(__dirname, 'electron-preload.js'), - webSecurity: true, - nodeIntegration: true, - contextIsolation: true, - } - }); - - // 关闭事件 - browser.addListener('closed', () => { - preloadWindow = null; - }) - - // 设置 UA - const originalUA = browser.webContents.session.getUserAgent() || browser.webContents.getUserAgent() - browser.webContents.setUserAgent(originalUA + " SubTaskWindow/" + process.platform + "/" + os.arch() + "/1.0"); - - utils.loadUrl(browser, serverUrl, '/preload') - - preloadWindow = browser; -} - -/** - * 创建子窗口 - * @param args {name, path, hash, force, userAgent, config, webPreferences} - * - config: {title, titleFixed, ...BrowserWindowConstructorOptions} - */ -function createChildWindow(args) { - if (!args) { - return; - } - - if (!utils.isJson(args)) { - args = {path: args, config: {}} - } - args.path = args.path || args.url; - - const name = args.name || "auto_" + utils.randomString(6); - const wind = childWindow.find(item => item.name == name); - let browser = wind ? wind.browser : null; - let isPreload = false; - // 清理已销毁但仍被引用的窗口,避免对失效对象调用方法 - if (browser && browser.isDestroyed && browser.isDestroyed()) { - const index = childWindow.findIndex(item => item.name == name); - if (index > -1) { - childWindow.splice(index, 1); - } - browser = null; - } - if (browser) { - browser.focus(); - if (args.force === false) { - return; - } - } else { - const config = args.config || {}; - const webPreferences = args.webPreferences || {}; - const options = Object.assign({ - width: 1280, - height: 800, - minWidth: 360, - minHeight: 360, - center: true, - show: false, - autoHideMenuBar: true, - backgroundColor: utils.getDefaultBackgroundColor(), - webPreferences: Object.assign({ - preload: path.join(__dirname, 'electron-preload.js'), - webSecurity: true, - nodeIntegration: true, - contextIsolation: true, - }, webPreferences), - }, config) - - options.width = utils.normalizeSize(options.width, 1280) - options.height = utils.normalizeSize(options.height, 800) - options.minWidth = utils.normalizeSize(options.minWidth, 360) - options.minHeight = utils.normalizeSize(options.minHeight, 360) - if (!options.webPreferences.contextIsolation) { - delete options.webPreferences.preload; - } - if (options.parent) { - options.parent = mainWindow - } - - if (preloadWindow && !preloadWindow.isDestroyed?.() && Object.keys(webPreferences).length === 0) { - // 使用预加载窗口 - browser = preloadWindow; - preloadWindow = null; - isPreload = true; - options.title && browser.setTitle(options.title); - options.parent && browser.setParentWindow(options.parent); - browser.setSize(options.width, options.height); - browser.setMinimumSize(options.minWidth, options.minHeight); - browser.center(); - browser.setAutoHideMenuBar(options.autoHideMenuBar); - browser.removeAllListeners("closed"); - setTimeout(() => onShowWindow(browser), 300) - process.nextTick(() => setTimeout(() => onShowWindow(browser), 50)); - } else { - // 创建新窗口 - browser = new BrowserWindow(options) - loger.info("create new window") - } - - browser.on('page-title-updated', (event, title) => { - if (title == "index.html" || options.titleFixed === true) { - event.preventDefault() - } - }) - - browser.on('focus', () => { - browser.webContents.send("browserWindowFocus", {}) - }) - - browser.on('blur', () => { - browser.webContents.send("browserWindowBlur", {}) - }) - - browser.on('close', event => { - if (!willQuitApp) { - utils.onBeforeUnload(event, browser).then(() => { - browser.hide() - setTimeout(() => { - browser.destroy() - }, 100) - }) - } - }) - - browser.on('closed', () => { - const index = childWindow.findIndex(item => item.browser === browser); - if (index > -1) { - childWindow.splice(index, 1) - } - }) - - browser.once('ready-to-show', () => { - onShowWindow(browser); - }) - - browser.webContents.once('dom-ready', () => { - onShowWindow(browser); - }) - - childWindow.push({ name, browser }) - } - - // 设置 UA - const originalUA = browser.webContents.session.getUserAgent() || browser.webContents.getUserAgent() - browser.webContents.setUserAgent(originalUA + " SubTaskWindow/" + process.platform + "/" + os.arch() + "/1.0" + (args.userAgent ? (" " + args.userAgent) : "")); - - // 新窗口处理 - browser.webContents.setWindowOpenHandler(({url}) => { - if (allowedCalls.test(url)) { - renderer.openExternal(url).catch(() => {}) - } else { - utils.onBeforeOpenWindow(browser.webContents, url).then(() => { - renderer.openExternal(url).catch(() => {}) - }) - } - return {action: 'deny'} - }) - - // 设置右键菜单 - electronMenu.webContentsMenu(browser.webContents) - - // 设置导航快捷键(返回/前进) - navigation.setup(browser) - - // 加载地址 - const hash = `${args.hash || args.path}`; - if (/^https?:/i.test(hash)) { - // 完整 URL 直接加载 - browser.loadURL(hash).then(_ => { }).catch(_ => { }) - } else if (isPreload) { - // preload 窗口尝试调用 __initializeApp,失败则 loadUrl - browser - .webContents - .executeJavaScript(`if(typeof window.__initializeApp === 'function'){window.__initializeApp('${hash}')}else{throw new Error('no function')}`, true) - .catch(() => { - utils.loadUrl(browser, serverUrl, hash) - }); - } else { - // 相对路径使用 loadUrl - utils.loadUrl(browser, serverUrl, hash) - } - - // 预创建下一个窗口 - preCreateChildWindow(); -} - -/** - * 更新子窗口 - * @param browser - * @param args - */ -function updateChildWindow(browser, args) { - if (!args) { - return; - } - - if (!utils.isJson(args)) { - args = {path: args, name: null} - } - - const hash = args.hash || args.path; - if (hash) { - utils.loadUrl(browser, serverUrl, hash) - } - if (args.name) { - const er = childWindow.find(item => item.browser == browser); - if (er) { - er.name = args.name; - } - } -} - /** * 创建媒体浏览器窗口 * @param args @@ -745,7 +506,10 @@ function createMediaWindow(args, type = 'image') { /** * 创建内置浏览器窗口(支持多窗口) - * @param args {url, windowId, position, afterId, insertIndex, name, force, userAgent, title, titleFixed, webPreferences, ...} + * @param args {url, windowId, position, afterId, insertIndex, name, force, userAgent, title, titleFixed, webPreferences, mode, ...} + * - mode: 'tab' | 'window' + * - 'window': 独立窗口模式(无导航栏) + * - 'tab': 标签页模式(默认,有导航栏) * @returns {number} 窗口ID */ function createWebTabWindow(args) { @@ -757,7 +521,10 @@ function createWebTabWindow(args) { args = {url: args} } - // 如果有 name,先查找是否已存在同名标签 + const mode = args.mode || 'tab'; + const isWindowMode = mode === 'window'; + + // 如果有 name,先查找是否已存在同名标签/窗口 if (args.name) { const existing = webTabNameMap.get(args.name); if (existing) { @@ -765,7 +532,7 @@ function createWebTabWindow(args) { if (existingWindowData && existingWindowData.window && !existingWindowData.window.isDestroyed()) { const viewItem = existingWindowData.views.find(v => v.id === existing.tabId); if (viewItem && viewItem.view && !viewItem.view.webContents.isDestroyed()) { - // 激活已存在的标签 + // 激活已存在的标签/窗口 if (existingWindowData.window.isMinimized()) { existingWindowData.window.restore(); } @@ -790,12 +557,12 @@ function createWebTabWindow(args) { let windowData = windowId ? webTabWindows.get(windowId) : null; let webTabWindow = windowData ? windowData.window : null; - // 如果没有指定窗口或窗口不存在,查找第一个可用窗口或创建新窗口 + // 如果没有指定窗口或窗口不存在,查找可用窗口或创建新窗口 if (!webTabWindow) { - // 如果没有指定窗口,尝试使用第一个可用窗口 - if (!windowId) { + // window 模式总是创建新窗口;tab 模式尝试使用第一个可用的 tab 窗口 + if (!isWindowMode && !windowId) { for (const [id, data] of webTabWindows) { - if (data.window && !data.window.isDestroyed()) { + if (data.window && !data.window.isDestroyed() && data.mode !== 'window') { windowId = id; windowData = data; webTabWindow = data.window; @@ -807,11 +574,21 @@ function createWebTabWindow(args) { // 如果还是没有窗口,创建新窗口 if (!webTabWindow) { windowId = webTabWindowIdCounter++; - webTabWindow = createWebTabWindowInstance(windowId, args.position); + // 从 args 中提取窗口尺寸 + const position = { + x: args.x, + y: args.y, + width: args.width, + height: args.height, + minWidth: args.minWidth, + minHeight: args.minHeight, + }; + webTabWindow = createWebTabWindowInstance(windowId, position, mode); windowData = { window: webTabWindow, views: [], - activeTabId: null + activeTabId: null, + mode: mode }; webTabWindows.set(windowId, windowData); } @@ -853,14 +630,17 @@ function createWebTabWindow(args) { }); } - utils.onDispatchEvent(webTabWindow.webContents, { - event: 'create', - id: browserView.webContents.id, - url: args.url, - afterId: args.afterId, - windowId: windowId, - title: args.title, - }).then(_ => { }); + // tab 模式通知标签栏创建标签;window 模式不需要 + if (!isWindowMode) { + utils.onDispatchEvent(webTabWindow.webContents, { + event: 'create', + id: browserView.webContents.id, + url: args.url, + afterId: args.afterId, + windowId: windowId, + title: args.title, + }).then(_ => { }); + } activateWebTabInWindow(windowId, browserView.webContents.id); return windowId; @@ -870,30 +650,40 @@ function createWebTabWindow(args) { * 创建 WebTabWindow 实例 * @param windowId * @param position {x, y, width, height} + * @param mode 'tab' | 'window' * @returns {BrowserWindow} */ -function createWebTabWindowInstance(windowId, position) { - const titleBarOverlay = { - height: webTabHeight - }; - if (nativeTheme.shouldUseDarkColors) { - titleBarOverlay.color = '#3B3B3D'; - titleBarOverlay.symbolColor = '#C5C5C5'; +function createWebTabWindowInstance(windowId, position, mode = 'tab') { + const isWindowMode = mode === 'window'; + + // mode='window': 根据屏幕分辨率动态计算默认值 + // mode='tab': 使用 userConf 保存值或固定默认值 + let defaultWidth, defaultHeight, defaultMinWidth, defaultMinHeight; + if (isWindowMode) { + const { width: screenWidth } = screen.getPrimaryDisplay().workAreaSize; + const isHighRes = screenWidth >= 2560; + defaultWidth = isHighRes ? 1920 : 1024; + defaultHeight = isHighRes ? 1080 : 768; + defaultMinWidth = 400; + defaultMinHeight = 300; + } else { + const savedBounds = userConf.get('webTabWindow') || {}; + defaultWidth = savedBounds.width ?? 1280; + defaultHeight = savedBounds.height ?? 800; + defaultMinWidth = 360; + defaultMinHeight = 360; } - const defaultBounds = userConf.get('webTabWindow') || {}; const hasExplicitPosition = position?.x !== undefined && position?.y !== undefined; const windowOptions = { - width: position?.width ?? defaultBounds.width ?? 1280, - height: position?.height ?? defaultBounds.height ?? 800, - minWidth: 360, - minHeight: 360, + width: position?.width ?? defaultWidth, + height: position?.height ?? defaultHeight, + minWidth: position?.minWidth ?? defaultMinWidth, + minHeight: position?.minHeight ?? defaultMinHeight, center: !hasExplicitPosition, show: false, autoHideMenuBar: true, - titleBarStyle: 'hidden', - titleBarOverlay, - backgroundColor: nativeTheme.shouldUseDarkColors ? '#575757' : '#FFFFFF', + backgroundColor: isWindowMode ? utils.getDefaultBackgroundColor() : (nativeTheme.shouldUseDarkColors ? '#575757' : '#FFFFFF'), webPreferences: { preload: path.join(__dirname, 'electron-preload.js'), webSecurity: true, @@ -902,6 +692,19 @@ function createWebTabWindowInstance(windowId, position) { }, }; + // tab 模式使用隐藏标题栏 + titleBarOverlay + if (!isWindowMode) { + const titleBarOverlay = { + height: webTabHeight + }; + if (nativeTheme.shouldUseDarkColors) { + titleBarOverlay.color = '#3B3B3D'; + titleBarOverlay.symbolColor = '#C5C5C5'; + } + windowOptions.titleBarStyle = 'hidden'; + windowOptions.titleBarOverlay = titleBarOverlay; + } + // 有明确位置时设置 x/y if (hasExplicitPosition) { windowOptions.x = position.x; @@ -944,7 +747,11 @@ function createWebTabWindowInstance(windowId, position) { return; } } - userConf.set('webTabWindow', webTabWindow.getBounds()); + // 只有 tab 模式才保存 bounds + const windowData = webTabWindows.get(windowId); + if (windowData && windowData.mode !== 'window') { + userConf.set('webTabWindow', webTabWindow.getBounds()); + } }); webTabWindow.on('closed', () => { @@ -996,7 +803,10 @@ function createWebTabWindowInstance(windowId, position) { return item ? item.view.webContents : null; }); - webTabWindow.loadFile('./render/tabs/index.html', {query: {windowId: String(windowId)}}).then(_ => { }).catch(_ => { }); + // tab 模式加载标签栏界面,window 模式不需要 + if (!isWindowMode) { + webTabWindow.loadFile('./render/tabs/index.html', {query: {windowId: String(windowId)}}).then(_ => { }).catch(_ => { }); + } return webTabWindow; } @@ -1012,12 +822,16 @@ function createWebTabView(windowId, args) { if (!windowData) return null; const webTabWindow = windowData.window; - const viewOptions = args.config || {}; - viewOptions.webPreferences = Object.assign({ - preload: path.join(__dirname, 'electron-preload.js'), - nodeIntegration: true, - contextIsolation: true - }, args.webPreferences || {}); + const isWindowMode = windowData.mode === 'window'; + const effectiveTabHeight = isWindowMode ? 0 : webTabHeight; + + const viewOptions = { + webPreferences: Object.assign({ + preload: path.join(__dirname, 'electron-preload.js'), + nodeIntegration: true, + contextIsolation: true + }, args.webPreferences || {}) + }; if (!viewOptions.webPreferences.contextIsolation) { delete viewOptions.webPreferences.preload; } @@ -1025,6 +839,8 @@ function createWebTabView(windowId, args) { const browserView = new WebContentsView(viewOptions); if (args.backgroundColor) { browserView.setBackgroundColor(args.backgroundColor); + } else if (isWindowMode) { + browserView.setBackgroundColor(utils.getDefaultBackgroundColor()); } else if (nativeTheme.shouldUseDarkColors) { browserView.setBackgroundColor('#575757'); } else { @@ -1032,9 +848,9 @@ function createWebTabView(windowId, args) { } browserView.setBounds({ x: 0, - y: webTabHeight, + y: effectiveTabHeight, width: webTabWindow.getContentBounds().width || 1280, - height: (webTabWindow.getContentBounds().height || 800) - webTabHeight, + height: (webTabWindow.getContentBounds().height || 800) - effectiveTabHeight, }); // 保存所属窗口ID和元数据 @@ -1063,7 +879,13 @@ function createWebTabView(windowId, args) { browserView.webContents.setWindowOpenHandler(({url}) => { if (allowedCalls.test(url)) { renderer.openExternal(url).catch(() => {}); + } else if (isWindowMode) { + // window 模式下打开外部浏览器 + utils.onBeforeOpenWindow(browserView.webContents, url).then(() => { + renderer.openExternal(url).catch(() => {}); + }); } else { + // tab 模式下创建新标签 createWebTabWindow({url, afterId: browserView.webContents.id, windowId}); } return {action: 'deny'}; @@ -1323,15 +1145,18 @@ function resizeWebTabInWindow(windowId, id) { if (!windowData || !windowData.window) return; const webTabWindow = windowData.window; + const isWindowMode = windowData.mode === 'window'; + const effectiveTabHeight = isWindowMode ? 0 : webTabHeight; + const item = id === 0 ? currentWebTabInWindow(windowId) : windowData.views.find(item => item.id == id); if (!item) { return; } item.view.setBounds({ x: 0, - y: webTabHeight, + y: effectiveTabHeight, width: webTabWindow.getContentBounds().width || 1280, - height: (webTabWindow.getContentBounds().height || 800) - webTabHeight, + height: (webTabWindow.getContentBounds().height || 800) - effectiveTabHeight, }); } @@ -1373,10 +1198,22 @@ function closeWebTabInWindow(windowId, id) { const webTabView = windowData.views; const webTabWindow = windowData.window; + const isWindowMode = windowData.mode === 'window'; + const item = id === 0 ? currentWebTabInWindow(windowId) : webTabView.find(item => item.id == id); if (!item) { return; } + + // window 模式下直接关闭整个窗口 + if (isWindowMode) { + webTabView.forEach(({name}) => { + if (name) webTabNameMap.delete(name); + }); + webTabWindow.destroy(); + return; + } + if (webTabView.length === 1) { webTabWindow.hide(); } @@ -1668,9 +1505,7 @@ function monitorThemeChanges() { // 更新背景 const backgroundColor = utils.getDefaultBackgroundColor() mainWindow?.setBackgroundColor(backgroundColor); - preloadWindow?.setBackgroundColor(backgroundColor); mediaWindow?.setBackgroundColor(backgroundColor); - childWindow.some(({browser}) => browser.setBackgroundColor(backgroundColor)) // 更新所有 webTab 窗口背景 for (const [, windowData] of webTabWindows) { windowData.window?.setBackgroundColor(nativeTheme.shouldUseDarkColors ? '#575757' : '#FFFFFF'); @@ -1706,8 +1541,6 @@ if (!getTheLock) { utils.useCookie() // 创建主窗口 createMainWindow() - // 预创建子窗口 - preCreateChildWindow() // 监听主题变化 monitorThemeChanges() // 创建托盘 @@ -1803,42 +1636,39 @@ ipcMain.on('windowQuit', (event) => { }) /** - * 显示预加载窗口(用于调试) - */ -ipcMain.on('showPreloadWindow', (event) => { - if (preloadWindow) { - onShowWindow(preloadWindow) - } - event.returnValue = "ok" -}) - -/** - * 更新路由窗口 - * @param args {?name, ?path} // name: 不是要更改的窗口名,是要把窗口名改成什么, path: 地址 - */ -ipcMain.on('updateChildWindow', (event, args) => { - const browser = BrowserWindow.fromWebContents(event.sender); - updateChildWindow(browser, args) - event.returnValue = "ok" -}) - -/** - * 获取路由窗口信息 + * 获取路由窗口信息(从 webTabWindows 中查找 mode='window' 的窗口) */ ipcMain.handle('getChildWindow', (event, args) => { - let child; + let windowData, viewItem; if (!args) { - const browser = BrowserWindow.fromWebContents(event.sender); - child = childWindow.find(({browser: win}) => win === browser) - } else { - child = childWindow.find(({name}) => name === args) - } - if (child) { - return { - name: child.name, - id: child.browser.webContents.id, - url: child.browser.webContents.getURL() + // 通过发送者查找 + const sender = event.sender; + for (const [, data] of webTabWindows) { + if (data.mode === 'window') { + const found = data.views.find(v => v.view.webContents === sender); + if (found) { + windowData = data; + viewItem = found; + break; + } + } } + } else { + // 通过名称查找 + const location = webTabNameMap.get(args); + if (location) { + windowData = webTabWindows.get(location.windowId); + if (windowData && windowData.mode === 'window') { + viewItem = windowData.views.find(v => v.id === location.tabId); + } + } + } + if (windowData && viewItem) { + return { + name: viewItem.name, + id: viewItem.view.webContents.id, + url: viewItem.view.webContents.getURL() + }; } return null; }); @@ -1857,17 +1687,12 @@ ipcMain.on('openMediaViewer', (event, args) => { * - url: 要打开的地址 * - name: 窗口/标签名称 * - mode: 'tab' | 'window' - * - 'window': 独立窗口模式 - * - 'tab': 标签页模式(默认) + * - 'window': 独立窗口模式(无导航栏) + * - 'tab': 标签页模式(默认,有导航栏) */ ipcMain.on('openWindow', (event, args) => { - if (args.mode === 'window') { - // 独立窗口模式 - createChildWindow(args) - } else { - // 标签页模式 - createWebTabWindow(args) - } + // 统一使用 createWebTabWindow,通过 mode 区分窗口类型 + createWebTabWindow(args) event.returnValue = "ok" }) @@ -2263,40 +2088,33 @@ ipcMain.on('windowDestroy', (event) => { }) /** - * 关闭所有子窗口 + * 关闭所有子窗口(mode='window' 的窗口) */ ipcMain.on('childWindowCloseAll', (event) => { - childWindow.some(({browser}) => { - browser && browser.close() - }) - preloadWindow?.close() + for (const [, data] of webTabWindows) { + if (data.mode === 'window' && data.window && !data.window.isDestroyed()) { + data.window.close(); + } + } mediaWindow?.close() electronDown.close() event.returnValue = "ok" }) /** - * 销毁所有子窗口 + * 销毁所有子窗口(mode='window' 的窗口) */ ipcMain.on('childWindowDestroyAll', (event) => { - childWindow.some(({browser}) => { - browser && browser.destroy() - }) - preloadWindow?.destroy() + for (const [, data] of webTabWindows) { + if (data.mode === 'window' && data.window && !data.window.isDestroyed()) { + data.window.destroy(); + } + } mediaWindow?.destroy() electronDown.destroy() event.returnValue = "ok" }) -/** - * 刷新预加载窗口(用于更换语言和主题时触发) - */ -ipcMain.on('reloadPreloadWindow', (event) => { - if (preloadWindow) { - preloadWindow.webContents.reload() - } - event.returnValue = "ok" -}) /** * 设置窗口尺寸 @@ -2637,10 +2455,11 @@ ipcMain.on('updateQuitAndInstall', (event, args) => { // 关闭所有子窗口 willQuitApp = true - childWindow.some(({browser}) => { - browser && browser.destroy() - }) - preloadWindow?.destroy() + for (const [, data] of webTabWindows) { + if (data.mode === 'window' && data.window && !data.window.isDestroyed()) { + data.window.destroy(); + } + } mediaWindow?.destroy() electronDown.destroy() diff --git a/resources/assets/js/components/MicroApps/index.vue b/resources/assets/js/components/MicroApps/index.vue index 10bfb178c..51c30c038 100644 --- a/resources/assets/js/components/MicroApps/index.vue +++ b/resources/assets/js/components/MicroApps/index.vue @@ -276,6 +276,19 @@ export default { params.path = params.url delete params.url } + // 兼容旧格式:将 config 扁平化 + if ($A.isJson(params.config)) { + const config = params.config + delete params.config + params = Object.assign({ + title: config.title, + titleFixed: config.titleFixed, + width: config.width, + height: config.height, + minWidth: config.minWidth, + minHeight: config.minHeight, + }, params) + } this.$store.dispatch('openWindow', params); }, openTabWindow: (url) => { @@ -482,16 +495,17 @@ export default { await $A.IDBSet("cacheMicroApps", $A.cloneJSON(apps)); if (this.$Electron) { + const mergedConfig = Object.assign({ + title: appConfig.title || ' ', + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), + }, $A.isJson(windowConfig) ? windowConfig : {}); await this.$store.dispatch('openWindow', { name: `single-apps-${$A.randomString(6)}`, path: path, - force: false, - config: Object.assign({ - title: appConfig.title || ' ', - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - }, $A.isJson(windowConfig) ? windowConfig : {}), + title: mergedConfig.title, + width: mergedConfig.width, + height: mergedConfig.height, }); } else if (this.$isEEUIApp) { await this.$store.dispatch('openAppChildPage', { @@ -517,13 +531,9 @@ export default { await this.$store.dispatch('openWindow', { name: `external-apps-${$A.randomString(6)}`, path: config.url, - force: false, - config: { - title: config.title || ' ', - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - }, + title: config.title || ' ', + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), }); } else if (this.$isEEUIApp) { await this.$store.dispatch('openAppChildPage', { @@ -783,7 +793,7 @@ export default { /** * 解析类型 - * @param type + * @param type */ resolveType(type) { if (typeof type === 'string') { diff --git a/resources/assets/js/language/index.js b/resources/assets/js/language/index.js index b065dd704..8b523daea 100644 --- a/resources/assets/js/language/index.js +++ b/resources/assets/js/language/index.js @@ -95,7 +95,7 @@ function setLanguage(language, silence = false) { if (silence) { utils.saveLanguage(language); (async () => { - await $A.IDBDel("callAt") + $A.IDBDel("callAt") $A.Electron?.sendMessage('reloadPreloadWindow'); $A.reloadUrl() })() diff --git a/resources/assets/js/pages/manage/components/DialogWrapper.vue b/resources/assets/js/pages/manage/components/DialogWrapper.vue index 9546a0698..cf44c6696 100644 --- a/resources/assets/js/pages/manage/components/DialogWrapper.vue +++ b/resources/assets/js/pages/manage/components/DialogWrapper.vue @@ -3784,15 +3784,11 @@ export default { this.$store.dispatch('openWindow', { name: `file-msg-${data.id}`, path: path, + title, + titleFixed: true, + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), userAgent: "/hideenOfficeTitle/", - force: false, - config: { - title, - titleFixed: true, - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - }, }); } else if (this.$isEEUIApp) { this.$store.dispatch('openAppChildPage', { diff --git a/resources/assets/js/pages/manage/components/FileHistory.vue b/resources/assets/js/pages/manage/components/FileHistory.vue index 051e9969e..1b9519ec0 100644 --- a/resources/assets/js/pages/manage/components/FileHistory.vue +++ b/resources/assets/js/pages/manage/components/FileHistory.vue @@ -184,15 +184,11 @@ export default { this.$store.dispatch('openWindow', { name: `file-${this.fileId}-${row.id}`, path: path, + title, + titleFixed: true, + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), userAgent: "/hideenOfficeTitle/", - force: false, - config: { - title, - titleFixed: true, - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - }, }); } else if (this.$isEEUIApp) { this.$store.dispatch('openAppChildPage', { diff --git a/resources/assets/js/pages/manage/components/MeetingManager/index.vue b/resources/assets/js/pages/manage/components/MeetingManager/index.vue index d79e37c9a..152d3126c 100644 --- a/resources/assets/js/pages/manage/components/MeetingManager/index.vue +++ b/resources/assets/js/pages/manage/components/MeetingManager/index.vue @@ -394,13 +394,6 @@ export default { }, }).then(linkRes => { // 使用子窗口打开会议 - const config = { - title: this.addData.name, - titleFixed: true, - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - } const meetingPath = $A.urlAddParams($A.removeMainUrlPrefix(linkRes.data), { type: 'direct', nickname: data.nickname, @@ -412,9 +405,10 @@ export default { this.$store.dispatch('openWindow', { name: `meeting-window`, path: meetingPath, - mode: 'window', - force: false, - config + title: this.addData.name, + titleFixed: true, + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), }); // 关闭弹窗 this.addShow = false; diff --git a/resources/assets/js/pages/manage/components/ProjectLog.vue b/resources/assets/js/pages/manage/components/ProjectLog.vue index bb89d0669..165d30802 100644 --- a/resources/assets/js/pages/manage/components/ProjectLog.vue +++ b/resources/assets/js/pages/manage/components/ProjectLog.vue @@ -222,13 +222,9 @@ export default { this.$store.dispatch('openWindow', { name: `project-log-${id}`, path: path, - force: false, - config: { - title: this.$L(title), - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - }, + title: this.$L(title), + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), }); } else if (this.$isEEUIApp) { e.preventDefault() diff --git a/resources/assets/js/pages/manage/components/Report.vue b/resources/assets/js/pages/manage/components/Report.vue index 69ea9cfd6..8c44e2374 100644 --- a/resources/assets/js/pages/manage/components/Report.vue +++ b/resources/assets/js/pages/manage/components/Report.vue @@ -104,18 +104,13 @@ export default { this.detailData = row; this.$emit("on-read"); if (this.$Electron) { - let config = { - title: row.title, - titleFixed: true, - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - } this.$store.dispatch('openWindow', { name: `report-detail-${row.id}`, path: `/single/report/detail/${row.id}`, - force: false, - config + title: row.title, + titleFixed: true, + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), }); } else { this.showDetailDrawer = true; @@ -128,17 +123,12 @@ export default { onEditReport(id) { if (this.$Electron) { - let config = { - title: this.$L(id > 0 ? '修改报告' : '新增报告'), - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - } this.$store.dispatch('openWindow', { name: `report-edit-${id}`, path: `/single/report/edit/${id}`, - force: false, - config + title: this.$L(id > 0 ? '修改报告' : '新增报告'), + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), }); } else { this.reportId = id; diff --git a/resources/assets/js/pages/manage/components/TaskContentHistory.vue b/resources/assets/js/pages/manage/components/TaskContentHistory.vue index 34a655347..d4c11a4de 100644 --- a/resources/assets/js/pages/manage/components/TaskContentHistory.vue +++ b/resources/assets/js/pages/manage/components/TaskContentHistory.vue @@ -172,14 +172,10 @@ export default { this.$store.dispatch('openWindow', { name: `task-content-${this.taskId}-${row.id}`, path: path, - force: false, - config: { - title: title, - titleFixed: true, - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - }, + title: title, + titleFixed: true, + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), }); } else if (this.$isEEUIApp) { this.$store.dispatch('openAppChildPage', { diff --git a/resources/assets/js/pages/manage/components/TaskDetail.vue b/resources/assets/js/pages/manage/components/TaskDetail.vue index 1ca3b07ad..75e401a90 100755 --- a/resources/assets/js/pages/manage/components/TaskDetail.vue +++ b/resources/assets/js/pages/manage/components/TaskDetail.vue @@ -1891,26 +1891,16 @@ export default { }, openNewWin() { - const config = { - title: this.taskDetail.name, - titleFixed: true, - parent: null, - width: Math.min(window.screen.availWidth * 0.8, this.$el.clientWidth + 72), - height: Math.min(window.screen.availHeight * 0.8, this.$el.clientHeight + 72), - minWidth: 600, - minHeight: 450, - autoZoom: true, - }; - if (this.hasOpenDialog) { - config.minWidth = 800; - config.minHeight = 600; - } this.$store.dispatch('openWindow', { name: `task-${this.taskDetail.id}`, path: `/single/task/${this.taskDetail.id}?navActive=${this.navActive}`, mode: 'window', - force: false, - config + title: this.taskDetail.name, + titleFixed: true, + width: Math.min(window.screen.availWidth * 0.8, this.$el.clientWidth + 72), + height: Math.min(window.screen.availHeight * 0.8, this.$el.clientHeight + 72), + minWidth: this.hasOpenDialog ? 800 : 600, + minHeight: this.hasOpenDialog ? 600 : 450, }); this.$store.dispatch('openTask', 0); }, @@ -1971,15 +1961,11 @@ export default { this.$store.dispatch('openWindow', { name: `file-task-${file.id}`, path: path, + title: `${file.name} (${$A.bytesToSize(file.size)})`, + titleFixed: true, + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), userAgent: "/hideenOfficeTitle/", - force: false, - config: { - title: `${file.name} (${$A.bytesToSize(file.size)})`, - titleFixed: true, - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - }, }); } else if (this.$isEEUIApp) { this.$store.dispatch('openAppChildPage', { diff --git a/resources/assets/js/pages/manage/file.vue b/resources/assets/js/pages/manage/file.vue index b5a4de6e1..4838bd9e0 100644 --- a/resources/assets/js/pages/manage/file.vue +++ b/resources/assets/js/pages/manage/file.vue @@ -1523,15 +1523,11 @@ export default { this.$store.dispatch('openWindow', { name: `file-${item.id}`, path: path, + title: $A.getFileName(item), + titleFixed: true, + width: Math.min(window.screen.availWidth, 1440), + height: Math.min(window.screen.availHeight, 900), userAgent: "/hideenOfficeTitle/", - force: false, // 如果窗口已存在不重新加载 - config: { - title: $A.getFileName(item), - titleFixed: true, - parent: null, - width: Math.min(window.screen.availWidth, 1440), - height: Math.min(window.screen.availHeight, 900), - }, }); } else if (this.$isEEUIApp) { this.$store.dispatch('openAppChildPage', { diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index 4649a2da0..398d0c20d 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -1385,12 +1385,15 @@ export default { /** * 打开窗口(客户端) * @param dispatch - * @param params {path, name, mode, force, config, userAgent, webPreferences} + * @param params {path, name, mode, force, title, titleFixed, width, height, minWidth, minHeight, userAgent, webPreferences} * - path: 要打开的地址(或直接传 URL 字符串) * - name: 窗口/标签名称 * - mode: 'tab' | 'window',默认 'tab' * - force: 是否强制刷新 - * - config: 窗口配置(独立窗口模式有效) + * - title: 窗口标题 + * - titleFixed: 是否固定标题 + * - width/height: 窗口尺寸(mode='window' 有效) + * - minWidth/minHeight: 最小尺寸(mode='window' 有效) * - userAgent: 自定义 UserAgent * - webPreferences: 网页偏好设置 */ @@ -1410,14 +1413,17 @@ export default { } $A.Electron.sendMessage('openWindow', { - url: params.path, name: params.name, + url: params.path, mode: params.mode, - force: params.force, - config: params.config, + title: params.title, + titleFixed: params.titleFixed, + width: params.width, + height: params.height, + minWidth: params.minWidth, + minHeight: params.minHeight, userAgent: params.userAgent, - title: params.config?.title, - titleFixed: params.config?.titleFixed, + force: params.force, webPreferences: params.webPreferences, }) }, @@ -3594,13 +3600,9 @@ export default { name: `dialog-${dialogId}`, path: `/single/dialog/${dialogId}`, mode: 'window', - force: false, - config: { - title: dialogData.name, - parent: null, - width: Math.min(window.screen.availWidth, 1024), - height: Math.min(window.screen.availHeight, 768), - }, + title: dialogData.name, + width: Math.min(window.screen.availWidth, 1024), + height: Math.min(window.screen.availHeight, 768), }); }, diff --git a/resources/assets/js/utils/file.js b/resources/assets/js/utils/file.js index 49f7f65d5..70d717f00 100644 --- a/resources/assets/js/utils/file.js +++ b/resources/assets/js/utils/file.js @@ -68,9 +68,12 @@ export function openFileInClient(vm, item, options = {}) { vm.$store.dispatch('openWindow', { name: windowName, path, + title: windowConfig.title, + titleFixed: windowConfig.titleFixed, + width: windowConfig.width, + height: windowConfig.height, userAgent: "/hideenOfficeTitle/", force: options.force === undefined ? false : options.force, - config: windowConfig, }); return; }