feat: 重构多语言模块,符合NestJS规范

- 重构LanguageUtils为LanguageService,实现ILanguageService接口
- 移除自定义验证管道和装饰器,使用标准NestJS验证
- 集成框架ValidatorService进行业务验证
- 简化目录结构,移除不必要的子目录
- 支持模块化语言包加载(common、user、order等)
- 统一API响应格式(code、msg、data、timestamp)
- 添加ValidationExceptionFilter处理多语言验证错误
- 完善多语言示例和文档
This commit is contained in:
wanwu
2025-10-06 10:56:59 +08:00
parent 8da4047110
commit b1e16be25d
284 changed files with 13098 additions and 32731 deletions

View File

@@ -0,0 +1,184 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
/**
* 基础生成器类
* 提供通用的 dry-run、文件操作、日志等功能
*/
class BaseGenerator {
constructor(generatorName = 'Generator') {
this.generatorName = generatorName;
// 从环境变量或参数读取配置
this.dryRun = process.env.DRY_RUN === 'true' || process.argv.includes('--dry-run');
this.verbose = process.env.VERBOSE === 'true' || process.argv.includes('--verbose');
this.stats = {
filesCreated: 0,
filesUpdated: 0,
filesSkipped: 0,
errors: 0
};
}
/**
* 安全写入文件(支持 dry-run
*/
writeFile(filePath, content, description = '') {
try {
if (this.dryRun) {
console.log(` [DRY-RUN] Would create/update: ${filePath}`);
if (this.verbose && description) {
console.log(` Description: ${description}`);
}
this.stats.filesCreated++;
return true;
}
// 确保目录存在
this.ensureDir(path.dirname(filePath));
// 写入文件
fs.writeFileSync(filePath, content, 'utf8');
const action = fs.existsSync(filePath) ? 'Updated' : 'Created';
console.log(`${action}: ${filePath}`);
if (action === 'Created') {
this.stats.filesCreated++;
} else {
this.stats.filesUpdated++;
}
return true;
} catch (error) {
console.error(` ❌ Failed to write ${filePath}:`, error.message);
this.stats.errors++;
return false;
}
}
/**
* 确保目录存在
*/
ensureDir(dirPath) {
if (this.dryRun) {
return;
}
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
}
/**
* 读取文件(安全)
*/
readFile(filePath) {
try {
if (!fs.existsSync(filePath)) {
return null;
}
return fs.readFileSync(filePath, 'utf8');
} catch (error) {
console.error(` ❌ Failed to read ${filePath}:`, error.message);
return null;
}
}
/**
* 检查文件是否存在
*/
fileExists(filePath) {
return fs.existsSync(filePath);
}
/**
* 日志输出
*/
log(message, level = 'info') {
const prefix = {
'info': ' ',
'success': ' ✅',
'warning': ' ⚠️ ',
'error': ' ❌',
'debug': ' 🔍'
};
if (level === 'debug' && !this.verbose) {
return;
}
console.log(`${prefix[level] || ' '}${message}`);
}
/**
* 输出统计信息
*/
printStats(additionalStats = {}) {
console.log('\n📊 Generation Statistics');
console.log('==================================================');
if (this.dryRun) {
console.log(' 🔍 DRY-RUN MODE - No files were actually modified');
}
console.log(` 📁 Files Created: ${this.stats.filesCreated}`);
console.log(` 🔄 Files Updated: ${this.stats.filesUpdated}`);
console.log(` ⏭️ Files Skipped: ${this.stats.filesSkipped}`);
console.log(` ❌ Errors: ${this.stats.errors}`);
// 输出额外的统计信息
for (const [key, value] of Object.entries(additionalStats)) {
console.log(` 📈 ${key}: ${value}`);
}
const total = this.stats.filesCreated + this.stats.filesUpdated;
const successRate = total > 0
? ((total / (total + this.stats.errors)) * 100).toFixed(2)
: '0.00';
console.log(` 📊 Success Rate: ${successRate}%`);
console.log('==================================================');
}
/**
* kebab-case 转换
*/
toKebabCase(str) {
return String(str)
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
.replace(/_/g, '-')
.toLowerCase();
}
/**
* PascalCase 转换
*/
toPascalCase(str) {
return String(str)
.split(/[-_]/)
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join('');
}
/**
* camelCase 转换
*/
toCamelCase(str) {
const pascal = this.toPascalCase(str);
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
}
/**
* snake_case 转换
*/
toSnakeCase(str) {
return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');
}
}
module.exports = BaseGenerator;