Files
pqs-9100_client/scripts/config-generator.js

212 lines
6.8 KiB
JavaScript
Raw Normal View History

2025-10-16 20:18:20 +08:00
const fs = require('fs');
const path = require('path');
/**
* 配置文件生成器
* 根据应用实际安装路径生成Spring Boot配置文件
*/
class ConfigGenerator {
constructor() {
// 开发环境:项目根目录
// 打包后应用根目录win-unpacked
const isDev = !process.resourcesPath;
const baseDir = isDev
? path.join(__dirname, '..')
: path.dirname(process.resourcesPath);
// 开发环境build/extraResources/java
// 打包后resources/extraResources/java
this.javaPath = isDev
? path.join(baseDir, 'build', 'extraResources', 'java')
: path.join(process.resourcesPath, 'extraResources', 'java');
this.templatePath = path.join(this.javaPath, 'application.yml.template');
this.configPath = path.join(this.javaPath, 'application.yml');
// 数据目录使用应用所在盘符的根目录下的data文件夹
this.dataPath = this.getDataPath(baseDir);
}
/**
* 获取数据目录路径
* @param {string} baseDir 应用基础目录
* @returns {string} 数据目录路径
*/
getDataPath(baseDir) {
2025-11-26 08:50:22 +08:00
// 数据目录设置在应用目录内的 NPQS9100_Data 文件夹
return path.join(baseDir, 'NPQS9100_Data');
2025-10-16 20:18:20 +08:00
}
/**
* 生成配置文件
* @param {object} options - 配置选项
* @param {number} options.mysqlPort - MySQL 端口
* @param {number} options.javaPort - Java 应用端口
2025-11-26 08:50:22 +08:00
* @param {number} options.websocketPort - WebSocket 端口
2025-10-16 20:18:20 +08:00
* @param {string} options.mysqlPassword - MySQL 密码
*/
generateConfig(options = {}) {
return new Promise((resolve, reject) => {
try {
// 读取模板文件
if (!fs.existsSync(this.templatePath)) {
throw new Error(`Template file not found: ${this.templatePath}`);
}
let template = fs.readFileSync(this.templatePath, 'utf-8');
// 替换占位符
// Windows路径需要转义反斜杠
const dataPathEscaped = this.dataPath.replace(/\\/g, '\\\\');
template = template.replace(/\{\{APP_DATA_PATH\}\}/g, dataPathEscaped);
// 替换MySQL密码
const mysqlPassword = options.mysqlPassword || 'njcnpqs';
template = template.replace(/\{\{MYSQL_PASSWORD\}\}/g, mysqlPassword);
// 替换端口(如果提供)
if (options.mysqlPort) {
// 支持两种格式localhost:3306 和 {{MYSQL_PORT}}
template = template.replace(/\{\{MYSQL_PORT\}\}/g, options.mysqlPort);
template = template.replace(/localhost:3306/g, `localhost:${options.mysqlPort}`);
}
if (options.javaPort) {
template = template.replace(/port:\s*18092/g, `port: ${options.javaPort}`);
}
2025-11-26 08:50:22 +08:00
// 替换 WebSocket 端口
if (options.websocketPort) {
template = template.replace(/port:\s*7777/g, `port: ${options.websocketPort}`);
}
2025-10-16 20:18:20 +08:00
// 写入配置文件
fs.writeFileSync(this.configPath, template, 'utf-8');
// 创建必要的目录
this.createDirectories();
console.log('[ConfigGenerator] Configuration file generated successfully');
console.log('[ConfigGenerator] Data path:', this.dataPath);
console.log('[ConfigGenerator] MySQL port:', options.mysqlPort || 3306);
console.log('[ConfigGenerator] MySQL password:', options.mysqlPassword || 'njcnpqs');
2025-12-10 18:47:17 +08:00
console.log('[ConfigGenerator] Java port:', options.javaPort || 18093);
console.log('[ConfigGenerator] WebSocket port:', options.websocketPort || 7778);
2025-10-16 20:18:20 +08:00
resolve({
configPath: this.configPath,
dataPath: this.dataPath,
mysqlPort: options.mysqlPort || 3306,
2025-12-10 18:47:17 +08:00
javaPort: options.javaPort || 18093,
websocketPort: options.websocketPort || 7778
2025-10-16 20:18:20 +08:00
});
} catch (error) {
console.error('[ConfigGenerator] Failed to generate config:', error);
reject(error);
}
});
}
/**
* 创建必要的目录
*/
createDirectories() {
const dirs = [
this.dataPath,
path.join(this.dataPath, 'logs'),
path.join(this.dataPath, 'template'),
path.join(this.dataPath, 'report'),
path.join(this.dataPath, 'data')
];
dirs.forEach(dir => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
console.log('[ConfigGenerator] Created directory:', dir);
}
});
2025-12-10 18:47:17 +08:00
// 复制内置的报告模板文件
this.copyBuiltInTemplates();
}
/**
* 复制内置的报告模板文件到用户数据目录
*/
copyBuiltInTemplates() {
try {
const isDev = !process.resourcesPath;
const baseDir = isDev
? path.join(__dirname, '..')
: path.dirname(process.resourcesPath);
// 内置模板源路径
const templateSource = isDev
? path.join(baseDir, 'build', 'extraResources', 'templates')
: path.join(process.resourcesPath, 'extraResources', 'templates');
// 目标路径:用户数据目录/template/
const templateDest = path.join(this.dataPath, 'template');
// 检查源模板是否存在
if (!fs.existsSync(templateSource)) {
console.log('[ConfigGenerator] Built-in templates not found, skipping copy');
return;
}
// 递归复制模板文件(只复制不存在的文件,不覆盖已有文件)
this.copyTemplatesRecursive(templateSource, templateDest);
console.log('[ConfigGenerator] Built-in templates copied successfully');
} catch (error) {
console.error('[ConfigGenerator] Failed to copy templates:', error);
}
}
/**
* 递归复制模板文件不覆盖已存在的文件
* @param {string} src 源目录
* @param {string} dest 目标目录
*/
copyTemplatesRecursive(src, dest) {
// 确保目标目录存在
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest, { recursive: true });
}
// 读取源目录内容
const entries = fs.readdirSync(src, { withFileTypes: true });
entries.forEach(entry => {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
// 递归复制子目录
this.copyTemplatesRecursive(srcPath, destPath);
} else {
// 只复制不存在的文件(不覆盖用户修改过的文件)
if (!fs.existsSync(destPath)) {
fs.copyFileSync(srcPath, destPath);
console.log('[ConfigGenerator] Copied template:', destPath);
} else {
console.log('[ConfigGenerator] Template already exists, skipping:', destPath);
}
}
});
2025-10-16 20:18:20 +08:00
}
/**
* 获取配置信息
*/
getConfigInfo() {
return {
javaPath: this.javaPath,
templatePath: this.templatePath,
configPath: this.configPath,
dataPath: this.dataPath
};
}
}
module.exports = ConfigGenerator;