This commit is contained in:
2025-09-29 15:01:01 +08:00
parent 96b396500e
commit 9719228d6d
8 changed files with 1092 additions and 433 deletions

View File

@@ -1,11 +1,11 @@
import {app, BrowserWindow, ipcMain, Menu, screen, dialog} from 'electron';
import {existsSync, createWriteStream, promises as fs} from 'fs';
import {join, dirname} from 'path';
import {spawn, ChildProcessWithoutNullStreams} from 'child_process';
import {spawn, ChildProcess} from 'child_process';
import * as https from 'https';
import * as http from 'http';
let springProcess: ChildProcessWithoutNullStreams | null = null;
let springProcess: ChildProcess | null = null;
let mainWindow: BrowserWindow | null = null;
let splashWindow: BrowserWindow | null = null;
let appOpened = false;
@@ -17,40 +17,133 @@ let downloadedFilePath: string | null = null;
function openAppIfNotOpened() {
if (appOpened) return;
appOpened = true;
// SpringBoot 启动完成,现在加载前端页面
if (mainWindow) {
mainWindow.webContents.once('did-finish-load', () => {
setTimeout(() => {
mainWindow?.show();
mainWindow?.focus();
if (splashWindow) {
splashWindow.close();
splashWindow = null;
}
}, 1000);
});
if (process.env.NODE_ENV === 'development') {
const rendererPort = process.argv[2] || 8083;
mainWindow.loadURL(`http://localhost:${rendererPort}`);
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'));
}
mainWindow.show();
mainWindow.focus();
}
if (splashWindow) {
splashWindow.close();
splashWindow = null;
}
}
function startSpringBoot() {
const jarPath = join(__dirname, '../../public/erp_client_sb-2.4.7.jar');
springProcess = spawn('java', ['-jar', jarPath], {
cwd: dirname(jarPath),
detached: false
});
springProcess.stdout.on('data', (data) => {
if (data.toString().includes('Started Success')) {
openAppIfNotOpened();
}
});
function getJavaExecutablePath(): string {
if (process.env.NODE_ENV === 'development') {
return 'java';
}
springProcess.on('close', (code) => {
mainWindow ? mainWindow.close() : app.quit();
});
const bundledJavaPath = join(process.resourcesPath, 'app.asar.unpacked/public/jre/bin/java.exe');
if (existsSync(bundledJavaPath)) {
return bundledJavaPath;
}
const devJavaPath = join(__dirname, '../../public/jre/bin/java.exe');
if (existsSync(devJavaPath)) {
return devJavaPath;
}
return 'java';
}
function getJarFilePath(): string {
if (process.env.NODE_ENV === 'development') {
return join(__dirname, '../../public/erp_client_sb-2.4.7.jar');
}
const bundledJarPath = join(process.resourcesPath, 'app.asar.unpacked/public/erp_client_sb-2.4.7.jar');
if (existsSync(bundledJarPath)) {
return bundledJarPath;
}
return join(__dirname, '../../public/erp_client_sb-2.4.7.jar');
}
function getSplashPath(): string {
if (process.env.NODE_ENV === 'development') {
return join(__dirname, '../../public/splash.html');
}
const bundledSplashPath = join(process.resourcesPath, 'app.asar.unpacked/public/splash.html');
if (existsSync(bundledSplashPath)) {
return bundledSplashPath;
}
return join(__dirname, '../../public/splash.html');
}
function getIconPath(): string {
if (process.env.NODE_ENV === 'development') {
return join(__dirname, '../../public/icon/icon.png');
}
const bundledIconPath = join(process.resourcesPath, 'app.asar.unpacked/public/icon/icon.png');
if (existsSync(bundledIconPath)) {
return bundledIconPath;
}
return join(__dirname, '../renderer/icon/icon.png');
}
function startSpringBoot() {
const jarPath = getJarFilePath();
const javaPath = getJavaExecutablePath();
if (!existsSync(jarPath)) {
dialog.showErrorBox('启动失败', `JAR 文件不存在:\n${jarPath}`);
app.quit();
return;
}
try {
springProcess = spawn(javaPath, ['-jar', jarPath], {
cwd: dirname(jarPath),
detached: false
});
let startupCompleted = false;
springProcess.stdout?.on('data', (data) => {
const output = data.toString();
if (!startupCompleted && (output.includes('Started Success') || output.includes('Started ErpClientSbApplication'))) {
startupCompleted = true;
openAppIfNotOpened();
}
});
springProcess.on('close', (code) => {
mainWindow ? mainWindow.close() : app.quit();
});
springProcess.on('error', (error) => {
let errorMessage = '启动 Java 应用失败';
if (error.message.includes('ENOENT')) {
errorMessage = '找不到 Java 运行环境\n请确保应用包含 JRE 或系统已安装 Java';
}
dialog.showErrorBox('启动失败', errorMessage);
app.quit();
});
setTimeout(() => {
if (!startupCompleted) {
openAppIfNotOpened();
}
}, 15000);
} catch (error) {
dialog.showErrorBox('启动异常', `无法启动应用: ${error}`);
app.quit();
}
}
startSpringBoot();
@@ -81,7 +174,7 @@ function createWindow() {
height: 800,
show: false,
autoHideMenuBar: true,
icon: join(__dirname, '../renderer/icon/icon.png'),
icon: getIconPath(),
webPreferences: {
preload: join(__dirname, 'preload.js'),
nodeIntegration: false,
@@ -89,7 +182,6 @@ function createWindow() {
}
});
mainWindow.webContents.openDevTools();
Menu.setApplicationMenu(null);
mainWindow.setMenuBarVisibility(false);
@@ -97,12 +189,7 @@ function createWindow() {
setTimeout(() => checkPendingUpdate(), 500);
});
if (process.env.NODE_ENV === 'development') {
const rendererPort = process.argv[2] || 8083;
mainWindow.loadURL(`http://localhost:${rendererPort}`);
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'));
}
// 不立即加载页面,等 SpringBoot 启动完成后再加载
}
app.whenReady().then(() => {
@@ -115,12 +202,17 @@ app.whenReady().then(() => {
frame: false,
transparent: false,
resizable: false,
alwaysOnTop: true,
alwaysOnTop: false,
show: true,
center: true,
icon: getIconPath(),
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
}
});
const splashPath = join(__dirname, '../../public', 'splash.html');
const splashPath = getSplashPath();
if (existsSync(splashPath)) {
splashWindow.loadFile(splashPath);
}