修正启动
This commit is contained in:
190
baota_panel_start.js
Normal file
190
baota_panel_start.js
Normal file
@@ -0,0 +1,190 @@
|
||||
// 宝塔面板NODE项目启动文件 - 同时启动前端和后端服务
|
||||
import { spawn } from 'child_process';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import http from 'http';
|
||||
|
||||
// 获取当前文件的目录路径
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
// 获取项目根目录
|
||||
const rootDir = __dirname;
|
||||
console.log('项目根目录:', rootDir);
|
||||
|
||||
// 确保server目录存在
|
||||
const serverDir = path.join(rootDir, 'server');
|
||||
if (!fs.existsSync(serverDir)) {
|
||||
console.error('错误: server目录不存在!');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 确保前端构建目录存在
|
||||
const distDir = path.join(rootDir, 'dist');
|
||||
const serverDistDir = path.join(serverDir, 'dist');
|
||||
|
||||
// 如果server/dist目录不存在,则创建
|
||||
if (!fs.existsSync(serverDistDir)) {
|
||||
console.log('创建server/dist目录...');
|
||||
fs.mkdirSync(serverDistDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 如果前端已构建(dist目录存在),则复制到server/dist
|
||||
if (fs.existsSync(distDir)) {
|
||||
console.log('复制前端构建文件到server/dist...');
|
||||
|
||||
// 递归复制函数
|
||||
function copyFolderSync(from, to) {
|
||||
// 创建目标文件夹
|
||||
if (!fs.existsSync(to)) {
|
||||
fs.mkdirSync(to, { recursive: true });
|
||||
}
|
||||
|
||||
// 读取源文件夹中的所有文件和子文件夹
|
||||
const files = fs.readdirSync(from);
|
||||
|
||||
// 遍历并复制每个文件/文件夹
|
||||
files.forEach(file => {
|
||||
const srcPath = path.join(from, file);
|
||||
const destPath = path.join(to, file);
|
||||
|
||||
// 检查是文件还是文件夹
|
||||
if (fs.statSync(srcPath).isDirectory()) {
|
||||
// 递归复制子文件夹
|
||||
copyFolderSync(srcPath, destPath);
|
||||
} else {
|
||||
// 复制文件
|
||||
fs.copyFileSync(srcPath, destPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 执行复制
|
||||
copyFolderSync(distDir, serverDistDir);
|
||||
console.log('前端文件复制完成');
|
||||
} else {
|
||||
console.warn('警告: 前端文件未构建! 请先运行 npm run build');
|
||||
|
||||
// 创建一个临时的index.html文件,提示用户构建前端
|
||||
const tempIndexPath = path.join(serverDistDir, 'index.html');
|
||||
const tempIndexContent = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>抽奖系统 - 前端未构建</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
|
||||
.warning { color: #e74c3c; }
|
||||
.code { background: #f8f9fa; padding: 10px; border-radius: 5px; display: inline-block; margin: 20px 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="warning">前端文件未构建!</h1>
|
||||
<p>请在项目根目录运行以下命令构建前端文件:</p>
|
||||
<div class="code">npm run build</div>
|
||||
<p>构建完成后重启服务</p>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
fs.writeFileSync(tempIndexPath, tempIndexContent);
|
||||
console.log('已创建临时index.html文件');
|
||||
}
|
||||
|
||||
// 检查数据库文件是否存在
|
||||
const dbPath = path.join(serverDir, 'lottery.db');
|
||||
if (!fs.existsSync(dbPath)) {
|
||||
console.log('数据库文件不存在,将在服务启动时自动创建');
|
||||
}
|
||||
|
||||
// 定义日志目录和文件
|
||||
const logDir = path.join(rootDir, 'logs');
|
||||
if (!fs.existsSync(logDir)) {
|
||||
fs.mkdirSync(logDir, { recursive: true });
|
||||
}
|
||||
|
||||
const logFile = path.join(logDir, `server-${new Date().toISOString().split('T')[0]}.log`);
|
||||
const logStream = fs.createWriteStream(logFile, { flags: 'a' });
|
||||
|
||||
// 记录日志的函数
|
||||
function log(message) {
|
||||
const timestamp = new Date().toISOString();
|
||||
const logMessage = `[${timestamp}] ${message}`;
|
||||
console.log(logMessage);
|
||||
logStream.write(logMessage + '\n');
|
||||
}
|
||||
|
||||
// 启动后端服务器
|
||||
log('正在启动服务器...');
|
||||
|
||||
const serverPath = path.join(serverDir, 'index.js');
|
||||
const server = spawn('node', [serverPath], {
|
||||
cwd: rootDir,
|
||||
stdio: ['ignore', 'pipe', 'pipe']
|
||||
});
|
||||
|
||||
// 处理服务器输出
|
||||
server.stdout.on('data', (data) => {
|
||||
const output = data.toString().trim();
|
||||
log(`[服务器输出] ${output}`);
|
||||
|
||||
// 检测服务器是否已启动
|
||||
if (output.includes('Server running') || output.includes('listening')) {
|
||||
const match = output.match(/localhost:(\d+)/);
|
||||
if (match) {
|
||||
const port = match[1];
|
||||
log(`服务器已在端口 ${port} 启动`);
|
||||
checkServerStatus(port);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
server.stderr.on('data', (data) => {
|
||||
log(`[服务器错误] ${data.toString().trim()}`);
|
||||
});
|
||||
|
||||
// 处理服务器退出
|
||||
server.on('close', (code) => {
|
||||
log(`服务器进程已退出,退出码: ${code}`);
|
||||
logStream.end();
|
||||
process.exit(code);
|
||||
});
|
||||
|
||||
// 检查服务器状态
|
||||
function checkServerStatus(port) {
|
||||
setTimeout(() => {
|
||||
const req = http.request({
|
||||
hostname: 'localhost',
|
||||
port: port,
|
||||
path: '/',
|
||||
method: 'GET'
|
||||
}, (res) => {
|
||||
log(`服务器状态检查: HTTP ${res.statusCode}`);
|
||||
if (res.statusCode === 200) {
|
||||
log('服务器运行正常,可以通过浏览器访问');
|
||||
log(`访问地址: http://localhost:${port}`);
|
||||
}
|
||||
});
|
||||
|
||||
req.on('error', (err) => {
|
||||
log(`服务器状态检查失败: ${err.message}`);
|
||||
});
|
||||
|
||||
req.end();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// 处理进程退出信号
|
||||
process.on('SIGINT', () => {
|
||||
log('接收到中断信号,正在关闭服务...');
|
||||
server.kill('SIGINT');
|
||||
});
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
log('接收到终止信号,正在关闭服务...');
|
||||
server.kill('SIGTERM');
|
||||
});
|
||||
|
||||
log('启动脚本执行完毕,服务器正在运行中...');
|
||||
Reference in New Issue
Block a user