import { ipcMain,app } from 'electron'; import { getDeviceId, getWiredConnectionName, netmaskToCidr,simulateUpdate,performRealUpdate } from '../utils/utils'; import { BrowserWindow } from 'electron'; import { autoUpdater } from 'electron-updater'; import request from '../utils/request'; const { exec } = require('child_process'); const { promisify } = require('util'); const execAsync = promisify(exec); const window = getBrowserWindowRuntime(); let currentServerIp: string | undefined; // 添加处理窗口调整 ipcMain.handle('adjust-window-for-normal', async (event) => { try { const window = BrowserWindow.fromWebContents(event.sender); if (window) { // 调整窗口大小和配置 window.setKiosk(false); // 退出全屏模式 window.setMinimumSize(1200, 800); window.setSize(1200, 800); window.setResizable(true); window.setMaximizable(true); window.setMinimizable(true); // 保持无边框和隐藏标题栏的设置 window.setFullScreen(false); } return { success: true }; } catch (error) { console.error('调整窗口失败:', error); return { success: false, }; } }); /**拖动窗口 */ ipcMain.handle('drag-window', (event) => { const focusedWindow = BrowserWindow.getFocusedWindow(); if (focusedWindow) { // 通知渲染进程开始拖拽 focusedWindow.webContents.send('start-drag'); } }); // 监听渲染进程发送的消息 ipcMain.handle('getPlatform', () => { return `hi, i'm from ${process.platform}`; }); // 窗口控制:最小化,退出全屏,关闭, // 获取窗口最大化状态 ipcMain.handle('get-window-maximized', (event) => { const window = BrowserWindow.fromWebContents(event.sender); return window?.isMaximized() || false; }); ipcMain.on('close-app', () => { app.quit(); }); // 最小化 ipcMain.on('minimize-app', () => { const focusedWindow = BrowserWindow.getFocusedWindow(); if (focusedWindow) { focusedWindow.minimize(); } // window?.minimize(); }); // 退出全屏 ipcMain.on('restore-window', () => { const focusedWindow = BrowserWindow.getFocusedWindow(); if (focusedWindow) { focusedWindow.unmaximize(); } // if (window) { // window.setFullScreen(false); // } }); // 设置全屏 ipcMain.on('maximize-window', () => { const focusedWindow = BrowserWindow.getFocusedWindow(); if (focusedWindow) { focusedWindow.maximize(); } }) // 监听窗口状态变化并通知渲染进程 ipcMain.on('register-window-state-listeners', (event) => { const window = BrowserWindow.fromWebContents(event.sender); if (window) { window.on('maximize', () => { event.sender.send('window-maximized'); }); window.on('unmaximize', () => { event.sender.send('window-unmaximized'); }); } }); ipcMain.handle('get-device-id',async()=>{ const deviceId = await getDeviceId(); console.log(`Using device ID: ${deviceId}`); // TODO:传给后端 }) /* 1. 平台网络配置:IPC 处理应用有线网络配置 */ ipcMain.handle('apply-wired-config',async(event,config)=>{ // return { // success: true, // message: '网络配置已成功应用' // }; try{ console.log('应用网络配置:', config); // 获取有线连接名称 const connectionName = await getWiredConnectionName(); console.log('有线连接名称:', connectionName); if(config.method==='static'){ // 使用nmcli配置静态IP,需要使用sudo权限,一次性设置所有参数 let modifyCmd = `echo "unis@123" | sudo -S nmcli connection modify "${connectionName}" ipv4.method manual ipv4.addresses "${config.ipv4}/${netmaskToCidr(config.subnetMask)}" ipv4.gateway "${config.ipv4Gateway}"`; const dnsServers = [config.primaryDns, config.secondaryDns].filter(Boolean).join(','); modifyCmd += ` ipv4.dns "${dnsServers}"`; // 添加 IPv6 配置(如果存在 ipv6Gateway)????ipv6和长度需要吗?ui只写了ipv6网关 // ipv6PrefixLength 是 IPv6 地址的前缀长度,类似于 IPv4 中的子网掩码。???? if (config.ipv6 && config.ipv6Gateway) { const ipv6PrefixLength = config.ipv6PrefixLength && config.ipv6PrefixLength >= 0 && config.ipv6PrefixLength <= 128 ? config.ipv6PrefixLength : 64; // 默认使用64 modifyCmd += ` ipv6.method manual ipv6.addresses "${config.ipv6}/${ipv6PrefixLength}" ipv6.gateway "${config.ipv6Gateway}"`; }else if (config.ipv6 || config.ipv6Gateway) { console.warn('IPv6配置不完整:需要同时提供IPv6地址和网关'); } // 执行配置命令 console.log('执行命令:', modifyCmd.replace('unis@123', '***')); await execAsync(modifyCmd); // 重新激活连接 await execAsync(`echo "unis@123" | sudo -S nmcli connection up "${connectionName}"`); }else{ // DHCP配置,一次性设置所有参数 const modifyCmd = `echo "unis@123" | sudo -S nmcli connection modify "${connectionName}" ipv4.method auto ipv4.addresses "" ipv4.gateway "" ipv4.dns ""`; // 执行配置命令 console.log('执行命令:', modifyCmd.replace('unis@123', '***')); await execAsync(modifyCmd); // 重新激活连接 await execAsync(`echo "unis@123" | sudo -S nmcli connection up "${connectionName}"`); } return { success: true, message: '网络配置已成功应用' }; }catch(error:unknown){ console.error('应用网络配置失败:', error); return { success: false, message: `配置失败: ${error instanceof Error ? error.message : String(error || '未知错误')}` }; } }) /**2. 服务器配置 */ ipcMain.handle('connect-server', async (event, { serverIp }) => { console.log(`Connecting to server: ${serverIp}`); try { // 获取设备ID const deviceId = await getDeviceId(); console.log(`Using device ID: ${deviceId}`); // 构建新的API地址,使用POST请求 const apiUrl = `http://${serverIp}:8113/api/nex/v1/client/authentication`; console.log(`Testing API endpoint: ${apiUrl}`); // 调用Authentication接口进行连接验证(POST请求) const response = await request(apiUrl, { method: 'POST', timeout: 10000, // 10秒超时 headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ device_id: deviceId }) }); console.log('API response received:', response); // 解析响应数据 let responseData; try { responseData = JSON.parse((response as any).data); } catch (parseError) { console.error('Failed to parse authentication response:', parseError); return { success: false, message: '服务器响应格式错误' }; } console.log('Parsed authentication response:', responseData); // 检查认证结果 - 只有code等于200时才算成功 if (responseData.code === '200' || responseData.code === 200) { // 认证成功,存储服务器IP currentServerIp = serverIp; console.log('Authentication successful, server IP stored:', serverIp); return { success: true, message: `已连接到服务器 ${serverIp}`, serverIp: serverIp }; } else { // 认证失败,返回服务器提供的错误信息 const errorMessage = responseData.message || responseData.msg || responseData.error || '服务器认证失败'; console.log('Authentication failed:', errorMessage); return { success: false, message: errorMessage }; } } catch (error:any) { console.error('Server connection error details:', { message: error.message, code: error.code, errno: error.errno, syscall: error.syscall, address: error.address, port: error.port }); // 根据具体错误提供更准确的提示 let errorMessage = '请输入正确服务器ip或者联系管理员'; if (error.message.includes('ECONNREFUSED')) { errorMessage = `无法连接到服务器 ${serverIp}:8113,请检查服务器是否运行`; } else if (error.message.includes('ENOTFOUND')) { errorMessage = `无法解析服务器地址 ${serverIp},请检查IP地址是否正确`; } else if (error.message.includes('请求超时')) { errorMessage = `连接服务器 ${serverIp}:8113 超时,请检查网络连接`; } else if (error.message.includes('ENETUNREACH')) { errorMessage = `网络不可达,无法连接到服务器 ${serverIp}`; } else if (error.message.includes('HTTP 404')) { errorMessage = `服务器返回404错误,Authentication接口路径可能不正确`; } else if (error.message.includes('HTTP')) { errorMessage = `服务器返回错误: ${error.message}`; } return { success: false, message: errorMessage }; } }); // 服务器IP获取 ipcMain.handle('get-current-server-ip', () => { return currentServerIp; }); /**3. 侦测管理平台 */ // 下载并更新客户端 let updateDownloadedInfo: any = null; // 修改 download-and-update 处理器中的事件监听器 ipcMain.handle('download-and-update', async (event, url) => { console.log('下载并更新客户端:', url); // 重置更新状态 updateDownloadedInfo = null; if (process.env.NODE_ENV === 'development') { // 开发环境下使用模拟更新 return simulateUpdate(event, url); } else { // 生产环境下使用真实更新 // 清除之前的事件监听器,避免重复注册 autoUpdater.removeAllListeners('update-downloaded'); // 监听更新下载完成事件 autoUpdater.on('update-downloaded', (info) => { console.log('更新已下载=====>', info); updateDownloadedInfo = info; }); return performRealUpdate(event, url); } }); // 安装更新并重启应用 ipcMain.on('install-update-and-restart', () => { console.log('安装更新并重启应用...'); if (process.env.NODE_ENV === 'development') { // 开发环境下使用模拟更新 console.log('开发环境:模拟重启应用'); // 直接调用,添加小延迟 app.quit(); } else { // 生产环境下使用真实更新 if (!updateDownloadedInfo) { console.warn('没有已完成下载的更新'); // 可以选择不执行重启或提示用户 const focusedWindow = BrowserWindow.getFocusedWindow(); if (focusedWindow) { focusedWindow.webContents.send('update-not-available', { message: '没有已完成下载的更新,请先下载更新' }); } return; } console.log('生产环境:安装更新并重启'); try { autoUpdater.quitAndInstall(false, true); } catch (installError) { console.error('自动更新安装失败,降级到手动重启:', installError); // app.relaunch(); // app.quit(); const focusedWindow = BrowserWindow.getFocusedWindow(); if (focusedWindow) { focusedWindow.webContents.send('update-install-error', { message: '更新安装失败: ' + (installError instanceof Error ? installError.message : String(installError)) }); } } } });