From b3d77ba14d7a4323208ded5a3ad07268c1288bc3 Mon Sep 17 00:00:00 2001 From: "LUOJIE\\coolp" Date: Mon, 2 Feb 2026 19:08:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.lgzs_test | 2 +- src/main/ipc.js | 22 ++--- src/main/window.js | 196 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 183 insertions(+), 37 deletions(-) diff --git a/.env.lgzs_test b/.env.lgzs_test index 00e2400..18eb189 100644 --- a/.env.lgzs_test +++ b/.env.lgzs_test @@ -1,2 +1,2 @@ -VITE_h5_client_url=http://10.101.27.243:18900 +VITE_h5_client_url=http://10.102.9.139:18901 VITE_HsAppCode=1 diff --git a/src/main/ipc.js b/src/main/ipc.js index d0eca56..2260f91 100644 --- a/src/main/ipc.js +++ b/src/main/ipc.js @@ -25,9 +25,11 @@ export function setupIPC() { logger.info('=======================================initClientData') logger.info(data) + setStoreValue("h5_data", data); setStoreValue("token", data.token); setStoreValue("dify_access_token:", data.dify_access_token); setStoreValue("dify_refresh_token", data.dify_refresh_token); + setStoreValue("dify_csrf_token", data.dify_csrf_token); setStoreValue("userInfo", data.userInfo); setStoreValue("apiUrl", data.apiUrl); @@ -207,7 +209,7 @@ export function setupIPC() { newWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => { console.error('页面加载失败:', errorDescription); failLoadCount++; - + if (failLoadCount <= maxRetries) { console.log(`页面加载失败,${retryDelay}ms后进行第${failLoadCount}次重试...`); setTimeout(() => { @@ -252,7 +254,7 @@ export function setupIPC() { newWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => { console.error('页面加载失败:', errorDescription); failLoadCount2++; - + if (failLoadCount2 <= maxRetries2) { console.log(`页面加载失败,${retryDelay2}ms后进行第${failLoadCount2}次重试...`); setTimeout(() => { @@ -307,7 +309,7 @@ export function setupIPC() { const urlParts = fileUrl.split('/'); fileName = urlParts[urlParts.length - 1] || ''; } - + // 解码文件名,解决中文乱码问题 try { fileName = decodeURIComponent(fileName); @@ -315,7 +317,7 @@ export function setupIPC() { // 如果解码失败,保持原文件名 logger.warn(`文件名解码失败: ${fileName}`); } - + // 如果提取的文件名为空,使用时间戳生成默认名称 if (!fileName || fileName === '') { fileName = `downloaded_file_${Date.now()}`; @@ -323,12 +325,12 @@ export function setupIPC() { // 获取用户下载目录 const downloadDir = path.join(os.homedir(), 'Downloads'); - + // 确保下载目录存在 if (!fs.existsSync(downloadDir)) { fs.mkdirSync(downloadDir, { recursive: true }); } - + const outputLocationPath = path.join(downloadDir, fileName); const writer = fs.createWriteStream(outputLocationPath); let receivedBytes = 0; @@ -385,11 +387,11 @@ export function setupIPC() { try { // 标记为正在重启,避免其他退出逻辑干扰 app.isRestarting = true; - + // 确保所有窗口都被正确关闭 const windows = BrowserWindow.getAllWindows(); logger.info(`准备关闭 ${windows.length} 个窗口`); - + windows.forEach(window => { if (!window.isDestroyed()) { try { @@ -400,7 +402,7 @@ export function setupIPC() { } } }); - + // 延迟执行重启,确保窗口关闭完成 setTimeout(() => { try { @@ -417,7 +419,7 @@ export function setupIPC() { } } }, 1000); - + return { success: true }; } catch (error) { logger.error(`重启软件失败: ${error.message}`); diff --git a/src/main/window.js b/src/main/window.js index 9e603bb..ca04819 100644 --- a/src/main/window.js +++ b/src/main/window.js @@ -17,6 +17,8 @@ let difyfullScreenWindow = null let drageWindow = null let apiConfigWindow = null let configWindow = null + +let cookieLogTimer = null import { clearAllSessionData } from './utils/cacheUtils.js' // 权限授权 async function checkMediaAccess(mediaType){ @@ -85,7 +87,18 @@ export async function createWindow() { // 创建菜单 createMenu(mainWindow, difyfullScreenWindow) - let code = `localStorage.setItem("IsHsAiApp","IsHsAiApp");localStorage.setItem("HsAppCode",${import.meta.env.VITE_HsAppCode});` + + + const isDebugger=getStoreValue("isDebugger"); + + + const localStorageStatements = [ + `localStorage.setItem("IsHsAiApp","IsHsAiApp");`, + `localStorage.setItem("HsAppCode",${import.meta.env.VITE_HsAppCode});`, + `localStorage.setItem("isDebugger",${isDebugger});` + ].join('\n'); + + let code = `${localStorageStatements};`; const isAdmin = getStoreValue("isAdmin") @@ -107,12 +120,17 @@ export async function createWindow() { // 监听快捷键 F12 来打开/关闭 DevTools mainWindow.webContents.on('before-input-event', (event, input) => { - if (input.key === 'F12') { - mainWindow.webContents.toggleDevTools() - } else if (input.key === 'F5') { - logger.info('主窗口 F5 快捷键触发') - mainWindow.reload() + + const isDebugger=getStoreValue("isDebugger"); + if (isDebugger==1){ + if (input.key === 'F12') { + mainWindow.webContents.toggleDevTools() + } else if (input.key === 'F5') { + logger.info('全屏窗口 F5 快捷键触发') + mainWindow.reload() + } } + }) @@ -174,10 +192,10 @@ export async function createWindow() { mainWindow.webContents.on('did-fail-load', async (event, errorCode, errorDescription, validatedURL) => { logger.error(`主窗口页面加载失败: code=${errorCode}, desc=${errorDescription}, url=${validatedURL}, 失败次数: ${failLoadCount + 1}`) - + // 增加失败计数 failLoadCount++; - + if (failLoadCount <= maxRetries) { logger.info(`页面加载失败,${retryDelay}ms后进行第${failLoadCount}次重试...`); setTimeout(async () => { @@ -291,19 +309,30 @@ function registerShortcuts(window=null) { logger.info(`F5快捷键注册${success ? '成功' : '失败'}`) - const isRegistered_F12 = globalShortcut.isRegistered('F12'); - logger.info(`Is F12 registered: ${isRegistered_F12}`); + + + const isDebugger=getStoreValue("isDebugger"); + if (isDebugger==1){ + const isRegistered_F12 = globalShortcut.isRegistered('F12'); + logger.info(`Is F12 registered: ${isRegistered_F12}`); + } + + // 桌面端快要退出的时候,注销快捷键 app.on('will-quit', () => { globalShortcut.unregisterAll() // 注销所有快捷键 }) + + + } export async function createNewWindow(url, access_token, refresh_token,sandbox=false) { const origin_url = url logger.info('==========createNewWindow') logger.info('==========createNewWindow sandbox',sandbox) + const csrf_token=getStoreValue("dify_csrf_token") await checkAndApplyDeviceAccessPrivilege() @@ -313,6 +342,7 @@ export async function createNewWindow(url, access_token, refresh_token,sandbox=f show: false, icon: icon, webPreferences: { + partition: 'persist:my-shared-session', contextIsolation: false, nodeIntegration: true, nodeIntegrationInWorker: true, @@ -329,9 +359,25 @@ export async function createNewWindow(url, access_token, refresh_token,sandbox=f registerShortcuts(difyfullScreenWindow) }) - let code = `localStorage.setItem("IsHsAiApp","IsHsAiApp");localStorage.setItem("console_token","${access_token}");localStorage.setItem("refresh_token","12");` - const isAdmin = getStoreValue("isAdmin") const hs_version = getStoreValue("hs_version") + const dify_csrf_token = getStoreValue("dify_csrf_token") + + const cookieStatements = [ + `document.cookie = "access_token=${access_token}; path=/";`, + `document.cookie = "refresh_token=${refresh_token}; path=/";`, + `document.cookie = "csrf_token=${dify_csrf_token}; path=/";`, + `document.cookie = "hs_version=${hs_version}; path=/";` + ].join('\n'); + + const localStorageStatements = [ + `localStorage.setItem("IsHsAiApp", "IsHsAiApp");`, + `localStorage.setItem("console_token", "${access_token}");`, + `localStorage.setItem("refresh_token", "12");` + ].join('\n'); + + let code = `${localStorageStatements}\n${cookieStatements};`; + + const isAdmin = getStoreValue("isAdmin") let display=''; if (isAdmin==true){ @@ -354,7 +400,7 @@ export async function createNewWindow(url, access_token, refresh_token,sandbox=f ` } - code=code+`document.cookie="hs_version=${hs_version}";` + code=code+`;document.cookie="hs_version=${hs_version}; path=/";` difyfullScreenWindow.webContents.on('did-finish-load', () => { difyfullScreenWindow.webContents @@ -364,6 +410,7 @@ export async function createNewWindow(url, access_token, refresh_token,sandbox=f .catch((error) => { console.error('Error:', error) }) + startCookieLogger(2000) let times = 0 let timer = setInterval(() => { if (times > 3) { @@ -387,12 +434,16 @@ export async function createNewWindow(url, access_token, refresh_token,sandbox=f // 监听快捷键 F12 来打开/关闭 DevTools difyfullScreenWindow.webContents.on('before-input-event', (event, input) => { - if (input.key === 'F12') { - difyfullScreenWindow.webContents.toggleDevTools() - } else if (input.key === 'F5') { - logger.info('全屏窗口 F5 快捷键触发') - difyfullScreenWindow.reload() + const isDebugger=getStoreValue("isDebugger"); + if (isDebugger==1){ + if (input.key === 'F12') { + difyfullScreenWindow.webContents.toggleDevTools() + } else if (input.key === 'F5') { + logger.info('全屏窗口 F5 快捷键触发') + difyfullScreenWindow.reload() + } } + }) difyfullScreenWindow.webContents.setWindowOpenHandler((details) => { @@ -403,6 +454,10 @@ export async function createNewWindow(url, access_token, refresh_token,sandbox=f difyfullScreenWindow.on('closed', () => { logger.info('主窗口已关闭') difyfullScreenWindow = null + if (cookieLogTimer) { + clearInterval(cookieLogTimer) + cookieLogTimer = null + } }) difyfullScreenWindow.webContents.on('did-navigate', (event, url) => { @@ -503,18 +558,18 @@ export async function createNewWindow(url, access_token, refresh_token,sandbox=f difyfullScreenWindow.webContents.on('did-fail-load', async (event, errorCode, errorDescription, validatedURL) => { logger.error(`全屏窗口页面加载失败: code=${errorCode}, desc=${errorDescription}, url=${validatedURL}, 失败次数: ${failLoadCount + 1}`) - + failLoadCount++; - + if (failLoadCount <= maxRetries) { logger.info(`全屏窗口页面加载失败,${retryDelay}ms后进行第${failLoadCount}次重试...`); - + setTimeout(async () => { try { // 在重试前先检查网络连接 const { checkDefaultClientConnection } = await import('./utils/networkUtils.js'); const isNetworkConnected = await checkDefaultClientConnection(3000); - + if (isNetworkConnected) { logger.info('网络连接正常,重新加载全屏窗口页面'); difyfullScreenWindow.reload(); @@ -544,6 +599,93 @@ export async function createNewWindow(url, access_token, refresh_token,sandbox=f } +/** + * 获取并打印全屏窗口的 Cookie 数据 + * 每次调用从当前页面会话中读取 Cookie 并输出到控制台 + */ +export async function logDifyFullScreenCookies() { + try { + if (!difyfullScreenWindow || difyfullScreenWindow.isDestroyed()) { + return + } + const wc = difyfullScreenWindow.webContents + const currentURL = wc.getURL() + const sess = wc.session + let cookies = [] + if (currentURL && typeof currentURL === 'string' && currentURL.length > 0) { + cookies = await sess.cookies.get({ url: currentURL }) + } else { + cookies = await sess.cookies.get({}) + } + const simplified = cookies.map(c => ({ + name: c.name, + value: c.value, + domain: c.domain, + path: c.path, + httpOnly: c.httpOnly, + secure: c.secure, + sameSite: c.sameSite + })) + + logger.info('difyfullScreenWindow cookies:', simplified) + + const needSync = new Set(['access_token', 'csrf_token', 'refresh_token']) + for (const c of cookies) { + if (needSync.has(c.name)) { + + if (c.name === 'access_token') { + setStoreValue('dify_access_token', c.value) + } else if (c.name === 'csrf_token') { + setStoreValue('dify_csrf_token', c.value) + } else if (c.name === 'refresh_token') { + setStoreValue('dify_refresh_token', c.value) + } + await setCookieToMainWindow(c.name, c.value) + } + } + } catch (error) { + logger.error('获取 Cookie 失败:', error) + } +} + +/** + * 启动 Cookie 轮询打印 + * 以指定间隔定时获取并打印 Cookie,默认 2000ms + * 如果已在运行则不会重复启动 + */ +export function startCookieLogger(intervalMs = 2000) { + if (cookieLogTimer) { + return + } + cookieLogTimer = setInterval(() => { + logDifyFullScreenCookies() + }, intervalMs) +} + +/** + * 将指定名称和值的 Cookie 写入主窗口 + */ +async function setCookieToMainWindow(name, value) { + try { + if (!mainWindow || mainWindow.isDestroyed()) { + return + } + const targetBase = getStoreValue('h5_client_url') || '' + const targetUrl = targetBase ? `${targetBase}/` : (mainWindow.webContents.getURL() || 'http://localhost/') + const msess = mainWindow.webContents.session + await msess.cookies.set({ + url: targetUrl, + name, + value, + path: '/' + }) + await mainWindow.webContents.executeJavaScript(`document.cookie = "${name}=${value}; path=/";`) + logger.info(`已写入主窗口 Cookie: ${name}`) + } catch (error) { + logger.error('写入主窗口 Cookie 失败:', error) + } +} + export function createDrageWindow() { logger.info('开始创建悬浮窗口') @@ -564,6 +706,7 @@ export function createDrageWindow() { alwaysOnTop: true, autoHideMenuBar: true, webPreferences: { + partition: 'persist:my-shared-session', contextIsolation: false, nodeIntegration: true, nodeIntegrationInWorker: true, @@ -606,18 +749,18 @@ export function createDrageWindow() { drageWindow.webContents.on('did-fail-load', async (event, errorCode, errorDescription, validatedURL) => { logger.error(`悬浮窗口页面加载失败: code=${errorCode}, desc=${errorDescription}, url=${validatedURL}, 失败次数: ${drageFailLoadCount + 1}`) - + drageFailLoadCount++; - + if (drageFailLoadCount <= drageMaxRetries) { logger.info(`悬浮窗口页面加载失败,${drageRetryDelay}ms后进行第${drageFailLoadCount}次重试...`); - + setTimeout(async () => { try { // 在重试前先检查网络连接 const { checkDefaultClientConnection } = await import('./utils/networkUtils.js'); const isNetworkConnected = await checkDefaultClientConnection(3000); - + if (isNetworkConnected) { logger.info('网络连接正常,重新加载悬浮窗口页面'); drageWindow.reload(); @@ -761,6 +904,7 @@ export function createConfigWindow() { parent: getMainWindow(), modal: true, webPreferences: { + partition: 'persist:my-shared-session', contextIsolation: false, nodeIntegration: true, nodeIntegrationInWorker: true,