vdi/pc-fe/src/main/ipc/platform.ts

328 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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))
});
}
}
}
});