- 重构LanguageUtils为LanguageService,实现ILanguageService接口 - 移除自定义验证管道和装饰器,使用标准NestJS验证 - 集成框架ValidatorService进行业务验证 - 简化目录结构,移除不必要的子目录 - 支持模块化语言包加载(common、user、order等) - 统一API响应格式(code、msg、data、timestamp) - 添加ValidationExceptionFilter处理多语言验证错误 - 完善多语言示例和文档
478 lines
13 KiB
JavaScript
478 lines
13 KiB
JavaScript
/**
|
|
* 增强版业务逻辑转换器
|
|
* 集成转换规则数据库、多阶段转换管道、上下文感知转换和质量保证系统
|
|
* 为AI自动生成打下基石
|
|
*/
|
|
|
|
const ConversionRulesDatabase = require('./conversion-rules-database');
|
|
const ConversionPipeline = require('./conversion-pipeline');
|
|
const ContextAwareConverter = require('./context-aware-converter');
|
|
const QualityAssurance = require('./quality-assurance');
|
|
|
|
class EnhancedBusinessLogicConverter {
|
|
constructor() {
|
|
this.rulesDB = new ConversionRulesDatabase();
|
|
this.pipeline = new ConversionPipeline();
|
|
this.contextConverter = new ContextAwareConverter();
|
|
this.qualityAssurance = new QualityAssurance();
|
|
|
|
this.stats = {
|
|
totalConversions: 0,
|
|
successfulConversions: 0,
|
|
failedConversions: 0,
|
|
averageQuality: 0,
|
|
conversionTime: 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 执行增强版转换
|
|
*/
|
|
async convert(phpCode, filePath, className) {
|
|
const startTime = Date.now();
|
|
this.stats.totalConversions++;
|
|
|
|
try {
|
|
console.log('🚀 开始增强版业务逻辑转换...');
|
|
console.log(`📁 文件: ${filePath}`);
|
|
console.log(`🏷️ 类名: ${className}`);
|
|
|
|
// 1. 分析上下文
|
|
const context = this.contextConverter.analyzeContext(filePath, className, phpCode);
|
|
console.log(`🎭 上下文分析完成: ${context.fileType} - ${context.businessDomain}`);
|
|
|
|
// 2. 执行多阶段转换管道
|
|
const pipelineResults = await this.pipeline.convert(phpCode, context);
|
|
console.log(`🔄 转换管道完成: ${pipelineResults.metrics.totalDuration}ms`);
|
|
|
|
// 3. 应用上下文感知转换
|
|
const contextAwareCode = this.contextConverter.applyContextAwareConversion(
|
|
pipelineResults.final,
|
|
context
|
|
);
|
|
console.log(`🧠 上下文感知转换完成`);
|
|
|
|
// 4. 执行质量检查
|
|
const qualityResults = await this.qualityAssurance.performQualityCheck(
|
|
contextAwareCode,
|
|
context
|
|
);
|
|
console.log(`🛡️ 质量检查完成: ${qualityResults.overall.toUpperCase()}`);
|
|
|
|
// 5. 自动修复问题
|
|
let finalCode = contextAwareCode;
|
|
if (qualityResults.overall === 'fail' || qualityResults.warnings.length > 0) {
|
|
const fixResults = await this.qualityAssurance.autoFix(contextAwareCode, qualityResults);
|
|
finalCode = fixResults.code;
|
|
console.log(`🔧 自动修复完成: ${fixResults.summary.totalFixes}个修复`);
|
|
}
|
|
|
|
// 6. 最终质量验证
|
|
const finalQuality = await this.qualityAssurance.performQualityCheck(finalCode, context);
|
|
|
|
// 7. 更新统计信息
|
|
const endTime = Date.now();
|
|
this.updateStats(endTime - startTime, finalQuality);
|
|
|
|
// 8. 生成转换报告
|
|
const report = this.generateConversionReport({
|
|
original: phpCode,
|
|
final: finalCode,
|
|
context,
|
|
pipelineResults,
|
|
qualityResults: finalQuality,
|
|
duration: endTime - startTime
|
|
});
|
|
|
|
console.log('🎉 增强版转换完成!');
|
|
return {
|
|
success: true,
|
|
code: finalCode,
|
|
report,
|
|
context,
|
|
quality: finalQuality
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('❌ 增强版转换失败:', error.message);
|
|
this.stats.failedConversions++;
|
|
|
|
return {
|
|
success: false,
|
|
error: error.message,
|
|
stack: error.stack,
|
|
original: phpCode
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 批量转换
|
|
*/
|
|
async batchConvert(conversions) {
|
|
const results = [];
|
|
const startTime = Date.now();
|
|
|
|
console.log(`🔄 开始批量转换: ${conversions.length}个文件`);
|
|
|
|
for (let i = 0; i < conversions.length; i++) {
|
|
const { phpCode, filePath, className } = conversions[i];
|
|
|
|
console.log(`📋 转换进度: ${i + 1}/${conversions.length}`);
|
|
|
|
try {
|
|
const result = await this.convert(phpCode, filePath, className);
|
|
results.push(result);
|
|
|
|
if (result.success) {
|
|
console.log(`✅ 转换成功: ${className}`);
|
|
} else {
|
|
console.log(`❌ 转换失败: ${className} - ${result.error}`);
|
|
}
|
|
} catch (error) {
|
|
console.error(`❌ 转换异常: ${className} - ${error.message}`);
|
|
results.push({
|
|
success: false,
|
|
error: error.message,
|
|
filePath,
|
|
className
|
|
});
|
|
}
|
|
}
|
|
|
|
const endTime = Date.now();
|
|
const batchReport = this.generateBatchReport(results, endTime - startTime);
|
|
|
|
console.log(`🎯 批量转换完成: ${results.filter(r => r.success).length}/${results.length}成功`);
|
|
|
|
return {
|
|
results,
|
|
report: batchReport,
|
|
stats: this.stats
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 学习模式 - 从成功案例中学习
|
|
*/
|
|
async learnFromSuccess(conversions) {
|
|
console.log('🧠 开始学习模式...');
|
|
|
|
const successfulConversions = conversions.filter(c => c.success);
|
|
const learningData = [];
|
|
|
|
for (const conversion of successfulConversions) {
|
|
const { original, final, context, quality } = conversion;
|
|
|
|
// 提取转换模式
|
|
const patterns = this.extractConversionPatterns(original, final);
|
|
|
|
// 分析质量指标
|
|
const qualityMetrics = this.analyzeQualityMetrics(quality);
|
|
|
|
learningData.push({
|
|
context,
|
|
patterns,
|
|
quality: qualityMetrics,
|
|
original,
|
|
final
|
|
});
|
|
}
|
|
|
|
// 更新转换规则数据库
|
|
this.updateRulesFromLearning(learningData);
|
|
|
|
console.log(`📚 学习完成: ${learningData.length}个成功案例`);
|
|
|
|
return {
|
|
learningData,
|
|
updatedRules: this.rulesDB.getStats()
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 获取转换统计信息
|
|
*/
|
|
getStats() {
|
|
return {
|
|
...this.stats,
|
|
successRate: this.stats.totalConversions > 0
|
|
? (this.stats.successfulConversions / this.stats.totalConversions * 100).toFixed(2) + '%'
|
|
: '0%',
|
|
averageQuality: this.stats.averageQuality.toFixed(2),
|
|
averageTime: this.stats.conversionTime.toFixed(2) + 'ms'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 更新统计信息
|
|
*/
|
|
updateStats(duration, quality) {
|
|
if (quality.overall === 'pass') {
|
|
this.stats.successfulConversions++;
|
|
} else {
|
|
this.stats.failedConversions++;
|
|
}
|
|
|
|
// 计算平均质量分数
|
|
const qualityScore = this.calculateQualityScore(quality);
|
|
this.stats.averageQuality = (this.stats.averageQuality + qualityScore) / 2;
|
|
|
|
// 计算平均转换时间
|
|
this.stats.conversionTime = (this.stats.conversionTime + duration) / 2;
|
|
}
|
|
|
|
/**
|
|
* 计算质量分数
|
|
*/
|
|
calculateQualityScore(quality) {
|
|
let score = 100;
|
|
|
|
// 根据错误数量扣分
|
|
score -= quality.errors.length * 10;
|
|
|
|
// 根据警告数量扣分
|
|
score -= quality.warnings.length * 2;
|
|
|
|
// 根据复杂度扣分
|
|
if (quality.metrics.complexity?.cyclomatic > 10) {
|
|
score -= (quality.metrics.complexity.cyclomatic - 10) * 2;
|
|
}
|
|
|
|
return Math.max(0, score);
|
|
}
|
|
|
|
/**
|
|
* 生成转换报告
|
|
*/
|
|
generateConversionReport(data) {
|
|
return {
|
|
summary: {
|
|
success: true,
|
|
duration: data.duration,
|
|
quality: data.qualityResults.overall,
|
|
complexity: data.qualityResults.metrics.complexity,
|
|
maintainability: data.qualityResults.metrics.maintainability
|
|
},
|
|
context: {
|
|
fileType: data.context.fileType,
|
|
businessDomain: data.context.businessDomain,
|
|
strategies: data.context.strategies,
|
|
patterns: data.context.codePatterns
|
|
},
|
|
quality: {
|
|
errors: data.qualityResults.errors.length,
|
|
warnings: data.qualityResults.warnings.length,
|
|
recommendations: data.qualityResults.recommendations.length
|
|
},
|
|
pipeline: {
|
|
stages: Object.keys(data.pipelineResults.stages).length,
|
|
totalDuration: data.pipelineResults.metrics.totalDuration
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 生成批量转换报告
|
|
*/
|
|
generateBatchReport(results, totalDuration) {
|
|
const successful = results.filter(r => r.success);
|
|
const failed = results.filter(r => !r.success);
|
|
|
|
return {
|
|
summary: {
|
|
total: results.length,
|
|
successful: successful.length,
|
|
failed: failed.length,
|
|
successRate: (successful.length / results.length * 100).toFixed(2) + '%',
|
|
totalDuration
|
|
},
|
|
quality: {
|
|
averageErrors: successful.reduce((sum, r) => sum + (r.quality?.errors?.length || 0), 0) / successful.length,
|
|
averageWarnings: successful.reduce((sum, r) => sum + (r.quality?.warnings?.length || 0), 0) / successful.length
|
|
},
|
|
errors: failed.map(f => ({
|
|
file: f.filePath,
|
|
class: f.className,
|
|
error: f.error
|
|
}))
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 提取转换模式
|
|
*/
|
|
extractConversionPatterns(original, final) {
|
|
const patterns = [];
|
|
|
|
// 提取变量转换模式
|
|
const variablePatterns = this.extractVariablePatterns(original, final);
|
|
patterns.push(...variablePatterns);
|
|
|
|
// 提取方法转换模式
|
|
const methodPatterns = this.extractMethodPatterns(original, final);
|
|
patterns.push(...methodPatterns);
|
|
|
|
// 提取类型转换模式
|
|
const typePatterns = this.extractTypePatterns(original, final);
|
|
patterns.push(...typePatterns);
|
|
|
|
return patterns;
|
|
}
|
|
|
|
/**
|
|
* 提取变量转换模式
|
|
*/
|
|
extractVariablePatterns(original, final) {
|
|
const patterns = [];
|
|
|
|
// 提取$this->variable模式
|
|
const thisMatches = original.match(/\$this->(\w+)/g);
|
|
if (thisMatches) {
|
|
thisMatches.forEach(match => {
|
|
const variableMatch = match.match(/\$this->(\w+)/);
|
|
if (variableMatch) {
|
|
const variable = variableMatch[1];
|
|
if (final.includes(`this.${variable}`)) {
|
|
patterns.push({
|
|
type: 'variable',
|
|
pattern: `$this->${variable}`,
|
|
replacement: `this.${variable}`,
|
|
confidence: 1.0
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
return patterns;
|
|
}
|
|
|
|
/**
|
|
* 提取方法转换模式
|
|
*/
|
|
extractMethodPatterns(original, final) {
|
|
const patterns = [];
|
|
|
|
// 提取方法调用模式
|
|
const methodMatches = original.match(/\$this->(\w+)\(/g);
|
|
if (methodMatches) {
|
|
methodMatches.forEach(match => {
|
|
const method = match.match(/\$this->(\w+)\(/)[1];
|
|
if (final.includes(`this.${method}(`)) {
|
|
patterns.push({
|
|
type: 'method',
|
|
pattern: `$this->${method}(`,
|
|
replacement: `this.${method}(`,
|
|
confidence: 1.0
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
return patterns;
|
|
}
|
|
|
|
/**
|
|
* 提取类型转换模式
|
|
*/
|
|
extractTypePatterns(original, final) {
|
|
const patterns = [];
|
|
|
|
// 提取类型声明模式
|
|
const typeMatches = original.match(/(string|int|array|bool)\s+\$(\w+)/g);
|
|
if (typeMatches) {
|
|
typeMatches.forEach(match => {
|
|
const typeMatch = match.match(/(string|int|array|bool)\s+\$(\w+)/);
|
|
const type = typeMatch[1];
|
|
const variable = typeMatch[2];
|
|
|
|
let tsType = type;
|
|
if (type === 'int') tsType = 'number';
|
|
if (type === 'array') tsType = 'any[]';
|
|
if (type === 'bool') tsType = 'boolean';
|
|
|
|
if (final.includes(`${variable}: ${tsType}`)) {
|
|
patterns.push({
|
|
type: 'type',
|
|
pattern: `${type} $${variable}`,
|
|
replacement: `${variable}: ${tsType}`,
|
|
confidence: 1.0
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
return patterns;
|
|
}
|
|
|
|
/**
|
|
* 分析质量指标
|
|
*/
|
|
analyzeQualityMetrics(quality) {
|
|
return {
|
|
overall: quality.overall,
|
|
errorCount: quality.errors.length,
|
|
warningCount: quality.warnings.length,
|
|
complexity: quality.metrics.complexity,
|
|
maintainability: quality.metrics.maintainability,
|
|
testability: quality.metrics.testability,
|
|
performance: quality.metrics.performance
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 从学习数据更新规则
|
|
*/
|
|
updateRulesFromLearning(learningData) {
|
|
// 分析学习数据,提取新的转换规则
|
|
const newRules = this.analyzeLearningData(learningData);
|
|
|
|
// 更新转换规则数据库
|
|
newRules.forEach(rule => {
|
|
this.rulesDB.addRule(rule.category, rule);
|
|
});
|
|
|
|
console.log(`📚 更新了${newRules.length}个转换规则`);
|
|
}
|
|
|
|
/**
|
|
* 分析学习数据
|
|
*/
|
|
analyzeLearningData(learningData) {
|
|
const newRules = [];
|
|
|
|
// 分析转换模式
|
|
learningData.forEach(data => {
|
|
data.patterns.forEach(pattern => {
|
|
// 检查是否是新模式
|
|
if (this.isNewPattern(pattern)) {
|
|
newRules.push({
|
|
category: pattern.type,
|
|
pattern: new RegExp(pattern.pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
|
|
replacement: pattern.replacement,
|
|
description: `从学习数据中提取的${pattern.type}转换规则`,
|
|
confidence: pattern.confidence
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
return newRules;
|
|
}
|
|
|
|
/**
|
|
* 检查是否是新模式
|
|
*/
|
|
isNewPattern(pattern) {
|
|
// 检查规则数据库中是否已存在类似规则
|
|
const existingRules = this.rulesDB.getRules(pattern.type);
|
|
return !existingRules.some(rule =>
|
|
rule.pattern.toString() === pattern.pattern &&
|
|
rule.replacement === pattern.replacement
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = EnhancedBusinessLogicConverter;
|