Update 2026-06-23 10:40:10
Build and Push Docker Images / Build Backend Image (push) Has been cancelled
Build and Push Docker Images / Build Frontend Image (push) Has been cancelled
Build and Push Docker Images / Notify Build Complete (push) Has been cancelled

This commit is contained in:
yi
2026-06-23 10:40:10 +08:00
parent 864efb7f9d
commit e9bff9beb3
56 changed files with 295 additions and 292 deletions
+1 -1
View File
@@ -81,7 +81,7 @@ function parseArgs() {
function showHelp() {
console.log(`
${colors.bright}IDC设备管理系统 - 安装部署脚本 v${SCRIPT_VERSION}${colors.reset}
${colors.bright}云睿资产管理系统 - 安装部署脚本 v${SCRIPT_VERSION}${colors.reset}
用法: node install.js [选项]
+10 -10
View File
@@ -29,7 +29,7 @@ async function configureDatabase(cmdArgs) {
config.dbConfig.port = process.env.MYSQL_PORT || '3306';
config.dbConfig.username = process.env.MYSQL_USER || 'root';
config.dbConfig.password = process.env.MYSQL_PASSWORD || '';
config.dbConfig.database = process.env.MYSQL_DATABASE || 'idc_management';
config.dbConfig.database = process.env.MYSQL_DATABASE || 'yunrui_management';
log.info(`MySQL 配置: ${config.dbConfig.host}:${config.dbConfig.port}/${config.dbConfig.database}`);
} else {
const mysqlOption = await select('MySQL 配置方式:', [
@@ -74,13 +74,13 @@ async function configureDatabase(cmdArgs) {
async function configureExistingMySQL() {
console.log('\n' + colors.yellow + '请确保 MySQL 服务已启动并创建了数据库' + colors.reset);
console.log(colors.gray + '创建数据库命令: CREATE DATABASE idc_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' + colors.reset + '\n');
console.log(colors.gray + '创建数据库命令: CREATE DATABASE yunrui_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' + colors.reset + '\n');
config.dbConfig.host = await ask('MySQL 主机地址', config.dbConfig.host || 'localhost');
config.dbConfig.port = await ask('MySQL 端口', config.dbConfig.port || '3306');
config.dbConfig.username = await ask('MySQL 用户名', config.dbConfig.username || 'root');
config.dbConfig.password = await askPassword('MySQL 密码');
config.dbConfig.database = await ask('数据库名称', config.dbConfig.database || 'idc_management');
config.dbConfig.database = await ask('数据库名称', config.dbConfig.database || 'yunrui_management');
}
async function installMySQL() {
@@ -94,7 +94,7 @@ async function installMySQL() {
console.log(' 1. 下载 MySQL: https://dev.mysql.com/downloads/mysql/');
console.log(' 2. 或使用 XAMPP/WAMP 等集成环境');
console.log(' 3. 安装后创建数据库:');
console.log(colors.gray + ' CREATE DATABASE idc_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' + colors.reset);
console.log(colors.gray + ' CREATE DATABASE yunrui_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' + colors.reset);
return { success: false };
}
@@ -135,7 +135,7 @@ async function installMySQL() {
config.dbConfig.port = '3306';
config.dbConfig.username = 'root';
config.dbConfig.password = mysqlRootPassword;
config.dbConfig.database = 'idc_management';
config.dbConfig.database = 'yunrui_management';
log.subStep('创建数据库...');
await createMySQLDatabase(mysqlRootPassword);
@@ -148,7 +148,7 @@ async function installMySQL() {
port: '3306',
username: 'root',
password: mysqlRootPassword,
database: 'idc_management'
database: 'yunrui_management'
}
};
} catch (error) {
@@ -191,14 +191,14 @@ async function installMySQLRHEL(rootPassword) {
async function createMySQLDatabase(rootPassword) {
log.subStep('创建数据库...');
const createDbSql = 'CREATE DATABASE IF NOT EXISTS idc_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;';
const createDbSql = 'CREATE DATABASE IF NOT EXISTS yunrui_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;';
try {
execSync(`mysql -u root -p'${rootPassword}' -e "${createDbSql}"`, {
shell: '/bin/bash',
stdio: ['pipe', 'pipe', 'pipe']
});
log.success('数据库 idc_management 创建成功');
log.success('数据库 yunrui_management 创建成功');
return;
} catch (error) {
const errorMsg = error.stderr ? error.stderr.toString() : error.message;
@@ -210,7 +210,7 @@ async function createMySQLDatabase(rootPassword) {
shell: '/bin/bash',
stdio: ['pipe', 'pipe', 'pipe']
});
log.success('数据库 idc_management 创建成功');
log.success('数据库 yunrui_management 创建成功');
return;
} catch (e2) {
log.warning(`无密码连接也失败: ${e2.message}`);
@@ -220,7 +220,7 @@ async function createMySQLDatabase(rootPassword) {
log.warning(`数据库自动创建失败: ${errorMsg.trim()}`);
log.info('请手动创建数据库:');
console.log(colors.cyan + ' mysql -u root -p' + colors.reset);
console.log(colors.cyan + ' CREATE DATABASE idc_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' + colors.reset);
console.log(colors.cyan + ' CREATE DATABASE yunrui_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' + colors.reset);
}
}
+8 -8
View File
@@ -11,7 +11,7 @@ function generateBackendEnv() {
try {
const jwtSecret = generateSecretKey(64);
let envContent = `# IDC设备管理系统 - 环境配置
let envContent = `# 云睿资产管理系统 - 环境配置
# 生成时间: ${new Date().toISOString()}
# ==============================================
@@ -42,7 +42,7 @@ DB_TYPE=${config.dbType}
if (config.dbType === 'sqlite') {
envContent += `
# SQLite 配置
DB_PATH=./idc_management.db
DB_PATH=./yunrui_management.db
`;
} else {
envContent += `
@@ -85,7 +85,7 @@ function generatePM2Config() {
const pm2Config = {
apps: [{
name: 'idc-backend',
name: 'yunrui_asset-backend',
script: './server.js',
cwd: path.join(__dirname, '..', 'backend'),
instances: 1,
@@ -106,7 +106,7 @@ function generatePM2Config() {
if (config.frontendDeploy === 'pm2') {
pm2Config.apps.push({
name: 'idc-frontend',
name: 'yunrui_asset-frontend',
script: 'serve',
cwd: path.join(__dirname, '..', 'frontend'),
args: `-s dist -l ${config.frontendPort}`,
@@ -145,12 +145,12 @@ function generateNginxConfig() {
if (isWindows) {
frontendPath = path.join(__dirname, '..', 'frontend', 'dist').replace(/\\/g, '/');
} else {
frontendPath = '/var/www/idc';
frontendPath = '/var/www/yunrui_asset';
}
config.nginxRoot = frontendPath;
const nginxConfig = `# IDC设备管理系统 - Nginx配置
const nginxConfig = `# 云睿资产管理系统 - Nginx配置
# 生成时间: ${new Date().toISOString()}
server {
@@ -210,8 +210,8 @@ server {
}
`;
fs.writeFileSync(path.join(deployDir, 'nginx-idc.conf'), nginxConfig);
log.success('Nginx 配置文件已生成 (deploy/nginx-idc.conf)');
fs.writeFileSync(path.join(deployDir, 'nginx-yunrui.conf'), nginxConfig);
log.success('Nginx 配置文件已生成 (deploy/nginx-yunrui.conf)');
if (isWindows) {
log.info('Windows Nginx 配置路径示例:');
+4 -4
View File
@@ -35,9 +35,9 @@ function printSummary() {
log.section('服务管理命令');
console.log(` ${ICONS.pipe} ${colors.cyan}pm2 status${colors.reset} 查看服务状态`);
console.log(` ${ICONS.pipe} ${colors.cyan}pm2 logs idc-backend${colors.reset} 查看后端日志`);
console.log(` ${ICONS.pipe} ${colors.cyan}pm2 restart idc-backend${colors.reset} 重启后端`);
console.log(` ${ICONS.pipe} ${colors.cyan}pm2 stop idc-backend${colors.reset} 停止后端`);
console.log(` ${ICONS.pipe} ${colors.cyan}pm2 logs yunrui_asset-backend${colors.reset} 查看后端日志`);
console.log(` ${ICONS.pipe} ${colors.cyan}pm2 restart yunrui_asset-backend${colors.reset} 重启后端`);
console.log(` ${ICONS.pipe} ${colors.cyan}pm2 stop yunrui_asset-backend${colors.reset} 停止后端`);
log.divider();
@@ -70,7 +70,7 @@ async function main() {
initLogFile(LOG_DIR);
log.banner(
'IDC 设备管理系统',
'云睿资产管理系统',
'安装部署脚本',
SCRIPT_VERSION
);
+10 -10
View File
@@ -180,25 +180,25 @@ async function startServices() {
log.info('停止已有服务...');
const stopCmd = process.platform === 'win32'
? 'pm2 stop idc-backend idc-frontend 2>nul || exit 0'
: 'pm2 stop idc-backend idc-frontend 2>/dev/null || true';
? 'pm2 stop yunrui_asset-backend yunrui_asset-frontend 2>nul || exit 0'
: 'pm2 stop yunrui_asset-backend yunrui_asset-frontend 2>/dev/null || true';
runCommand(stopCmd, { silent: true });
log.info('启动后端服务...');
const backendResult = runCommand(
`pm2 start server.js --name "idc-backend" --env ${config.nodeEnv}`,
`pm2 start server.js --name "yunrui_asset-backend" --env ${config.nodeEnv}`,
{ cwd: path.join(__dirname, '..', 'backend') }
);
if (backendResult.success) {
log.success(`后端服务已启动 (端口: ${config.backendPort})`);
rollbackSteps.push(() => {
runCommand('pm2 stop idc-backend', { silent: true });
runCommand('pm2 delete idc-backend', { silent: true });
runCommand('pm2 stop yunrui_asset-backend', { silent: true });
runCommand('pm2 delete yunrui_asset-backend', { silent: true });
});
} else {
log.error('后端服务启动失败');
log.info('请检查后端日志: pm2 logs idc-backend');
log.info('请检查后端日志: pm2 logs yunrui_asset-backend');
throw new Error('Backend service start failed');
}
@@ -208,19 +208,19 @@ async function startServices() {
log.info('启动前端服务...');
const frontendResult = runCommand(
`pm2 start serve --name "idc-frontend" -- -s dist -l ${config.frontendPort}`,
`pm2 start serve --name "yunrui_asset-frontend" -- -s dist -l ${config.frontendPort}`,
{ cwd: path.join(__dirname, '..', 'frontend') }
);
if (frontendResult.success) {
log.success(`前端服务已启动 (端口: ${config.frontendPort})`);
rollbackSteps.push(() => {
runCommand('pm2 stop idc-frontend', { silent: true });
runCommand('pm2 delete idc-frontend', { silent: true });
runCommand('pm2 stop yunrui_asset-frontend', { silent: true });
runCommand('pm2 delete yunrui_asset-frontend', { silent: true });
});
} else {
log.error('前端服务启动失败');
log.info('请检查前端日志: pm2 logs idc-frontend');
log.info('请检查前端日志: pm2 logs yunrui_asset-frontend');
throw new Error('Frontend service start failed');
}
}
+5 -5
View File
@@ -200,8 +200,8 @@ async function autoConfigureNginx() {
if (!installed) {
log.error('Nginx 自动安装失败');
log.info('请手动安装 Nginx 后执行:');
console.log(` ${colors.cyan}sudo cp deploy/nginx-idc.conf /etc/nginx/sites-available/idc${colors.reset}`);
console.log(` ${colors.cyan}sudo ln -sf /etc/nginx/sites-available/idc /etc/nginx/sites-enabled/idc${colors.reset}`);
console.log(` ${colors.cyan}sudo cp deploy/nginx-yunrui.conf /etc/nginx/sites-available/yunrui_asset${colors.reset}`);
console.log(` ${colors.cyan}sudo ln -sf /etc/nginx/sites-available/yunrui_asset /etc/nginx/sites-enabled/yunrui_asset${colors.reset}`);
console.log(` ${colors.cyan}sudo nginx -t && sudo systemctl restart nginx${colors.reset}`);
return;
}
@@ -222,7 +222,7 @@ async function autoConfigureNginx() {
wwwDir = '/www/wwwroot/idc';
log.info('检测到宝塔面板 Nginx 环境');
} else {
wwwDir = '/var/www/idc';
wwwDir = '/var/www/yunrui_asset';
}
const distDir = path.join(__dirname, '..', 'frontend', 'dist');
@@ -244,7 +244,7 @@ async function autoConfigureNginx() {
config.nginxRoot = wwwDir;
const configSource = path.join(__dirname, '..', 'deploy', 'nginx-idc.conf');
const configSource = path.join(__dirname, '..', 'deploy', 'nginx-yunrui.conf');
if (!fs.existsSync(configSource)) {
log.error('Nginx 配置文件不存在,请先运行安装脚本');
@@ -282,7 +282,7 @@ async function autoConfigureNginx() {
if (useSitesAvailable) {
log.info('创建站点软链接...');
runCommand(`${sudoPrefix}ln -sf "${configDest}" /etc/nginx/sites-enabled/idc.conf`);
runCommand(`${sudoPrefix}ln -sf "${configDest}" /etc/nginx/sites-enabled/yunrui_asset.conf`);
if (fs.existsSync('/etc/nginx/sites-enabled/default')) {
log.info('删除默认站点配置...');
+1 -1
View File
@@ -32,7 +32,7 @@ async function rollback() {
const configFiles = [
path.join(__dirname, '..', 'backend', '.env'),
path.join(__dirname, '..', 'ecosystem.config.js'),
path.join(__dirname, '..', 'deploy', 'nginx-idc.conf'),
path.join(__dirname, '..', 'deploy', 'nginx-yunrui.conf'),
];
for (const file of configFiles) {