444 lines
14 KiB
JavaScript
444 lines
14 KiB
JavaScript
|
#!/usr/bin/env node
|
|||
|
|
|||
|
/**
|
|||
|
* 代码生成统一入口脚本
|
|||
|
* 整合了model生成和api生成功能
|
|||
|
*/
|
|||
|
|
|||
|
const { execSync } = require('child_process');
|
|||
|
const fs = require('fs');
|
|||
|
const path = require('path');
|
|||
|
const { generateApi } = require('./gen_api');
|
|||
|
|
|||
|
// 读取配置文件
|
|||
|
const CONFIG_FILE = path.join(__dirname, 'config.json');
|
|||
|
let config = {};
|
|||
|
|
|||
|
try {
|
|||
|
if (fs.existsSync(CONFIG_FILE)) {
|
|||
|
const configContent = fs.readFileSync(CONFIG_FILE, 'utf8');
|
|||
|
config = JSON.parse(configContent);
|
|||
|
console.log('Configuration loaded from config.json');
|
|||
|
} else {
|
|||
|
console.log('config.json not found, using default settings');
|
|||
|
}
|
|||
|
} catch (error) {
|
|||
|
console.error('Error loading configuration:', error.message);
|
|||
|
console.log('Using default settings');
|
|||
|
}
|
|||
|
|
|||
|
// 默认数据库配置
|
|||
|
const modelConfig = config.model || {
|
|||
|
// 数据库连接信息
|
|||
|
dbUrl: 'qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc',
|
|||
|
// 输出目录
|
|||
|
outputDir: './model',
|
|||
|
// 模板目录
|
|||
|
templateDir: '../template',
|
|||
|
// 目标目录
|
|||
|
targetDir: '../../app/user/model',
|
|||
|
// 表名列表
|
|||
|
tables: [
|
|||
|
'agent',
|
|||
|
'agent_audit',
|
|||
|
'agent_real_name'
|
|||
|
],
|
|||
|
// 禁用的表名列表
|
|||
|
disabledTables: []
|
|||
|
};
|
|||
|
|
|||
|
// 默认API配置
|
|||
|
const apiConfig = config.api || {
|
|||
|
// API定义文件路径
|
|||
|
apiFile: './app/user/cmd/api/desc/main.api',
|
|||
|
// 输出目录
|
|||
|
outputDir: './app/user/cmd/api',
|
|||
|
// 模板目录
|
|||
|
templateDir: './deploy/template',
|
|||
|
// 是否使用样式
|
|||
|
useStyle: false
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* 将表名转换为驼峰命名法
|
|||
|
* @param {string} tableName 表名
|
|||
|
* @returns {string} 驼峰命名的表名
|
|||
|
*/
|
|||
|
function convertToCamelCase(tableName) {
|
|||
|
try {
|
|||
|
// 将表名按_分割,并将每个部分首字母大写
|
|||
|
const parts = tableName.split('_');
|
|||
|
let camelCase = '';
|
|||
|
for (const part of parts) {
|
|||
|
if (part.length > 0) {
|
|||
|
camelCase += part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|||
|
}
|
|||
|
}
|
|||
|
return camelCase;
|
|||
|
} catch (error) {
|
|||
|
console.error(`Error in convertToCamelCase for table: ${tableName}`);
|
|||
|
console.error(error.message);
|
|||
|
return tableName; // 出错时返回原表名
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 确保目录存在
|
|||
|
* @param {string} dirPath 目录路径
|
|||
|
*/
|
|||
|
function ensureDirectoryExists(dirPath) {
|
|||
|
if (!fs.existsSync(dirPath)) {
|
|||
|
console.log(`Creating directory: ${dirPath}`);
|
|||
|
fs.mkdirSync(dirPath, { recursive: true });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 为单个表生成模型
|
|||
|
* @param {string} table 表名
|
|||
|
* @param {object} config 配置信息
|
|||
|
*/
|
|||
|
function generateModelForTable(table, config) {
|
|||
|
try {
|
|||
|
console.log('=========================================');
|
|||
|
console.log(`Processing table: ${table}`);
|
|||
|
|
|||
|
// 生成模型
|
|||
|
console.log('Generating model...');
|
|||
|
const command = `goctl model mysql datasource -url="${config.dbUrl}" -table="${table}" -dir="${config.outputDir}" --home="${config.templateDir}" -cache=true --style=goZero`;
|
|||
|
console.log(`Running command: ${command}`);
|
|||
|
|
|||
|
execSync(command, { stdio: 'inherit' });
|
|||
|
|
|||
|
// 将表名转换为驼峰命名法
|
|||
|
const camelCaseName = convertToCamelCase(table);
|
|||
|
console.log(`Table name converted to: ${camelCaseName}`);
|
|||
|
|
|||
|
// 定义源文件和目标文件路径
|
|||
|
const sourceModelFile = path.join(config.outputDir, `${camelCaseName}Model.go`);
|
|||
|
const sourceModelGenFile = path.join(config.outputDir, `${camelCaseName}Model_gen.go`);
|
|||
|
const targetModelFile = path.join(config.targetDir, `${camelCaseName}Model.go`);
|
|||
|
const targetModelGenFile = path.join(config.targetDir, `${camelCaseName}Model_gen.go`);
|
|||
|
|
|||
|
console.log('Source files:');
|
|||
|
console.log(` - ${sourceModelFile}`);
|
|||
|
console.log(` - ${sourceModelGenFile}`);
|
|||
|
console.log('Target files:');
|
|||
|
console.log(` - ${targetModelFile}`);
|
|||
|
console.log(` - ${targetModelGenFile}`);
|
|||
|
|
|||
|
// 检查源文件是否存在并移动
|
|||
|
if (fs.existsSync(sourceModelFile)) {
|
|||
|
console.log(`Moving ${sourceModelFile} to ${targetModelFile}`);
|
|||
|
fs.copyFileSync(sourceModelFile, targetModelFile);
|
|||
|
fs.unlinkSync(sourceModelFile);
|
|||
|
} else {
|
|||
|
console.log(`WARNING: Source file not found: ${sourceModelFile}`);
|
|||
|
}
|
|||
|
|
|||
|
if (fs.existsSync(sourceModelGenFile)) {
|
|||
|
console.log(`Moving ${sourceModelGenFile} to ${targetModelGenFile}`);
|
|||
|
fs.copyFileSync(sourceModelGenFile, targetModelGenFile);
|
|||
|
fs.unlinkSync(sourceModelGenFile);
|
|||
|
} else {
|
|||
|
console.log(`WARNING: Source file not found: ${sourceModelGenFile}`);
|
|||
|
}
|
|||
|
|
|||
|
console.log(`Processing completed for table: ${table}`);
|
|||
|
} catch (error) {
|
|||
|
console.error(`ERROR processing table: ${table}`);
|
|||
|
console.error(error.message);
|
|||
|
console.error(error.stack);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 生成指定表列表的模型
|
|||
|
* @param {string[]} tables 表名列表
|
|||
|
* @param {object} config 配置信息
|
|||
|
*/
|
|||
|
function generateModels(tables, config) {
|
|||
|
try {
|
|||
|
// 确保目录存在
|
|||
|
ensureDirectoryExists(config.outputDir);
|
|||
|
ensureDirectoryExists(config.targetDir);
|
|||
|
|
|||
|
if (tables.length === 0) {
|
|||
|
console.log('No tables specified for generation.');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// 为每个表生成模型
|
|||
|
for (const table of tables) {
|
|||
|
generateModelForTable(table, config);
|
|||
|
}
|
|||
|
|
|||
|
console.log('=========================================');
|
|||
|
console.log('All models generated successfully.');
|
|||
|
} catch (error) {
|
|||
|
console.error('ERROR in model generation:');
|
|||
|
console.error(error.message);
|
|||
|
console.error(error.stack);
|
|||
|
process.exit(1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 从数据库获取所有表名
|
|||
|
* @param {string} dbUrl 数据库连接URL
|
|||
|
* @returns {Promise<string[]>} 表名列表
|
|||
|
*/
|
|||
|
async function getAllTablesFromDB(dbUrl) {
|
|||
|
try {
|
|||
|
// 解析数据库连接信息
|
|||
|
const dbName = dbUrl.split('/').pop().split('?')[0];
|
|||
|
console.log(`Fetching all tables from database: ${dbName}`);
|
|||
|
|
|||
|
// 这里需要实现从数据库获取所有表的逻辑
|
|||
|
// 由于需要依赖额外的库,这里只是示例
|
|||
|
// 实际实现可能需要使用mysql2或其他数据库客户端库
|
|||
|
|
|||
|
// 模拟返回一些表名
|
|||
|
return [
|
|||
|
'agent',
|
|||
|
'agent_audit',
|
|||
|
'agent_real_name',
|
|||
|
'agent_active_stat',
|
|||
|
'agent_closure',
|
|||
|
'agent_commission',
|
|||
|
'agent_commission_deduction',
|
|||
|
'agent_link',
|
|||
|
'agent_membership_config',
|
|||
|
'agent_membership_recharge_order',
|
|||
|
'agent_membership_user_config',
|
|||
|
'agent_order',
|
|||
|
'agent_platform_deduction',
|
|||
|
'agent_product_config',
|
|||
|
'agent_rewards',
|
|||
|
'agent_wallet',
|
|||
|
'agent_withdrawal',
|
|||
|
'feature',
|
|||
|
'global_notifications',
|
|||
|
'order',
|
|||
|
'product',
|
|||
|
'product_feature',
|
|||
|
'query',
|
|||
|
'user',
|
|||
|
'user_auth',
|
|||
|
'example',
|
|||
|
'authorization',
|
|||
|
'authorization_face'
|
|||
|
];
|
|||
|
} catch (error) {
|
|||
|
console.error('Error fetching tables from database:', error.message);
|
|||
|
return [];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 显示配置信息
|
|||
|
*/
|
|||
|
function showConfig() {
|
|||
|
console.log('=========================================');
|
|||
|
console.log('Current Configuration:');
|
|||
|
console.log('\nModel Configuration:');
|
|||
|
console.log(' Database URL:', modelConfig.dbUrl);
|
|||
|
console.log(' Output Directory:', modelConfig.outputDir);
|
|||
|
console.log(' Template Directory:', modelConfig.templateDir);
|
|||
|
console.log(' Target Directory:', modelConfig.targetDir);
|
|||
|
console.log(' Tables:');
|
|||
|
modelConfig.tables.forEach(table => console.log(` - ${table}`));
|
|||
|
|
|||
|
if (modelConfig.disabledTables && modelConfig.disabledTables.length > 0) {
|
|||
|
console.log(' Disabled Tables:');
|
|||
|
modelConfig.disabledTables.forEach(table => console.log(` - ${table}`));
|
|||
|
}
|
|||
|
|
|||
|
console.log('\nAPI Configuration:');
|
|||
|
console.log(' API File:', apiConfig.apiFile);
|
|||
|
console.log(' Output Directory:', apiConfig.outputDir);
|
|||
|
console.log(' Template Directory:', apiConfig.templateDir);
|
|||
|
console.log(' Use Style:', apiConfig.useStyle ? 'Yes' : 'No');
|
|||
|
console.log('=========================================');
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 保存配置到文件
|
|||
|
* @param {object} config 配置对象
|
|||
|
*/
|
|||
|
function saveConfig(config) {
|
|||
|
try {
|
|||
|
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 4), 'utf8');
|
|||
|
console.log('Configuration saved to config.json');
|
|||
|
} catch (error) {
|
|||
|
console.error('Error saving configuration:', error.message);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 显示帮助信息
|
|||
|
*/
|
|||
|
function showHelp() {
|
|||
|
console.log('Usage: node codegen.js <command> [options]');
|
|||
|
console.log('Commands:');
|
|||
|
console.log(' model Generate database models');
|
|||
|
console.log(' api Generate API code');
|
|||
|
console.log(' config Show current configuration');
|
|||
|
console.log(' help Show this help message');
|
|||
|
console.log('');
|
|||
|
console.log('Model Options:');
|
|||
|
console.log(' --table <name> Generate model for specific table');
|
|||
|
console.log(' --tables <names> Generate models for specific tables (comma-separated)');
|
|||
|
console.log(' --exclude <names> Exclude specific tables (comma-separated)');
|
|||
|
console.log(' --all Generate models for all tables in database');
|
|||
|
console.log(' --db-url <url> Database connection URL');
|
|||
|
console.log(' --template <dir> Template directory');
|
|||
|
console.log(' --save Save specified tables to config.json');
|
|||
|
console.log('');
|
|||
|
console.log('API Options:');
|
|||
|
console.log(' --api <file> API definition file path');
|
|||
|
console.log(' --dir <dir> Output directory');
|
|||
|
console.log(' --template <dir> Template directory');
|
|||
|
console.log(' --style Use goZero style');
|
|||
|
console.log('');
|
|||
|
console.log('Configuration:');
|
|||
|
console.log(' Settings are loaded from config.json');
|
|||
|
console.log(' Command line options override config file settings');
|
|||
|
console.log('');
|
|||
|
console.log('Examples:');
|
|||
|
console.log(' node codegen.js model --table agent');
|
|||
|
console.log(' node codegen.js model --tables agent,user,order');
|
|||
|
console.log(' node codegen.js model --exclude user,order');
|
|||
|
console.log(' node codegen.js model --all --exclude system_table');
|
|||
|
console.log(' node codegen.js model --tables agent,user --save');
|
|||
|
process.exit(0);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 主函数
|
|||
|
*/
|
|||
|
async function main() {
|
|||
|
// 解析命令行参数
|
|||
|
const args = process.argv.slice(2);
|
|||
|
|
|||
|
if (args.length === 0 || args[0] === 'help') {
|
|||
|
showHelp();
|
|||
|
}
|
|||
|
|
|||
|
const command = args[0];
|
|||
|
|
|||
|
// 显示配置信息
|
|||
|
if (command === 'config') {
|
|||
|
showConfig();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// 处理模型生成命令
|
|||
|
if (command === 'model') {
|
|||
|
const config = { ...modelConfig };
|
|||
|
let singleTable = null;
|
|||
|
let tablesToGenerate = [...config.tables];
|
|||
|
let excludeTables = [];
|
|||
|
let shouldSaveConfig = false;
|
|||
|
let generateAllTables = false;
|
|||
|
|
|||
|
// 处理其他参数
|
|||
|
for (let i = 1; i < args.length; i++) {
|
|||
|
const arg = args[i];
|
|||
|
|
|||
|
if (arg === '--table' && i + 1 < args.length) {
|
|||
|
singleTable = args[++i];
|
|||
|
tablesToGenerate = [singleTable];
|
|||
|
} else if (arg === '--tables' && i + 1 < args.length) {
|
|||
|
const tableList = args[++i].split(',').map(t => t.trim()).filter(t => t);
|
|||
|
tablesToGenerate = tableList;
|
|||
|
} else if (arg === '--exclude' && i + 1 < args.length) {
|
|||
|
excludeTables = args[++i].split(',').map(t => t.trim()).filter(t => t);
|
|||
|
} else if (arg === '--all') {
|
|||
|
generateAllTables = true;
|
|||
|
} else if (arg === '--db-url' && i + 1 < args.length) {
|
|||
|
config.dbUrl = args[++i];
|
|||
|
} else if (arg === '--template' && i + 1 < args.length) {
|
|||
|
config.templateDir = args[++i];
|
|||
|
} else if (arg === '--save') {
|
|||
|
shouldSaveConfig = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 如果指定了--all参数,获取所有表名
|
|||
|
if (generateAllTables) {
|
|||
|
tablesToGenerate = await getAllTablesFromDB(config.dbUrl);
|
|||
|
}
|
|||
|
|
|||
|
// 排除指定的表
|
|||
|
if (excludeTables.length > 0) {
|
|||
|
tablesToGenerate = tablesToGenerate.filter(table => !excludeTables.includes(table));
|
|||
|
}
|
|||
|
|
|||
|
// 保存配置
|
|||
|
if (shouldSaveConfig) {
|
|||
|
const newConfig = { ...config };
|
|||
|
newConfig.tables = tablesToGenerate;
|
|||
|
|
|||
|
// 更新配置文件
|
|||
|
if (fs.existsSync(CONFIG_FILE)) {
|
|||
|
const existingConfig = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|||
|
existingConfig.model = newConfig;
|
|||
|
saveConfig(existingConfig);
|
|||
|
} else {
|
|||
|
saveConfig({ model: newConfig, api: apiConfig });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 生成单个表的模型或所有表的模型
|
|||
|
if (singleTable) {
|
|||
|
generateModelForTable(singleTable, config);
|
|||
|
} else {
|
|||
|
generateModels(tablesToGenerate, config);
|
|||
|
}
|
|||
|
}
|
|||
|
// 处理API生成命令
|
|||
|
else if (command === 'api') {
|
|||
|
const config = { ...apiConfig };
|
|||
|
|
|||
|
// 处理其他参数
|
|||
|
for (let i = 1; i < args.length; i++) {
|
|||
|
const arg = args[i];
|
|||
|
|
|||
|
if (arg === '--api' && i + 1 < args.length) {
|
|||
|
config.apiFile = args[++i];
|
|||
|
} else if (arg === '--dir' && i + 1 < args.length) {
|
|||
|
config.outputDir = args[++i];
|
|||
|
} else if (arg === '--template' && i + 1 < args.length) {
|
|||
|
config.templateDir = args[++i];
|
|||
|
} else if (arg === '--style') {
|
|||
|
config.useStyle = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 生成API代码
|
|||
|
generateApi(config);
|
|||
|
}
|
|||
|
else {
|
|||
|
console.error(`Unknown command: ${command}`);
|
|||
|
showHelp();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 执行主函数
|
|||
|
if (require.main === module) {
|
|||
|
main().catch(err => {
|
|||
|
console.error('Error in main execution:', err);
|
|||
|
process.exit(1);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
// 导出函数,以便其他脚本可以调用
|
|||
|
module.exports = {
|
|||
|
generateModels,
|
|||
|
generateModelForTable,
|
|||
|
generateApi,
|
|||
|
showConfig,
|
|||
|
saveConfig,
|
|||
|
getAllTablesFromDB
|
|||
|
};
|