const fs = require('fs'); const path = require('path'); /** * 业务逻辑转换器 * 基于真实PHP代码的转换规则,禁止TODO、假设、自创 */ class BusinessLogicConverter { constructor() { // 混合模块智能分类规则 this.hybridClassificationRules = { // 需要抽取到Core层的业务逻辑文件 coreBusinessLogic: [ // 支付相关 /pay/i, /payment/i, /transfer/i, /refund/i, // 会员相关 /member/i, /user.*profile/i, /account/i, // 业务配置 /config.*pay/i, /config.*member/i, /config.*order/i, // 订单相关 /order/i, /goods/i, /product/i, // 认证业务逻辑 /login.*business/i, /auth.*business/i, /register/i, // DIY业务 /diy/i, /custom/i, // 营销业务 /promotion/i, /coupon/i, /discount/i ], // 应该使用Common基础服务的文件 useCommonInfrastructure: [ // 基础服务接口 /BaseController/, /BaseService/, /BaseModel/, // 通用工具 /upload/i, /export/i, /attachment/i, /sys.*config/i, /system.*info/i, /cache/i, /redis/i, // 基础认证 /jwt/i, /token/i, /guard/i, /middleware/i ] }; this.phpRegexPatterns = [ // PHP类型转换 { pattern: /\$([a-zA-Z_][a-zA-Z0-9_]*)/g, replacement: '$1' }, { pattern: /\->/g, replacement: '.' }, { pattern: /public function\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(([^)]*)\)/g, replacement: 'async $1($2)' }, { pattern: /private function\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(([^)]*)\)/g, replacement: 'private async $1($2)' }, { pattern: /protected function\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(([^)]*)\)/g, replacement: 'protected async $1($2)' }, // PHP参数类型转换 { pattern: /string\s+\$([a-zA-Z_][a-zA-Z0-9_]*)/g, replacement: '$1: string' }, { pattern: /int\s+\$([a-zA-Z_][a-zA-Z0-9_]*)/g, replacement: '$1: number' }, { pattern: /array\s+\$([a-zA-Z_][a-zA-Z0-9_]*)/g, replacement: '$1: any[]' }, { pattern: /bool\s+\$([a-zA-Z_][a-zA-Z0-9_]*)/g, replacement: '$1: boolean' }, // PHP语法转换 { pattern: /this\s*\->\s*model/g, replacement: 'this.model' }, { pattern: /new\s+([A-Z][a-zA-Z0-9_]*)\(\)/g, replacement: 'this.$1Repository' }, { pattern: /parent::__construct\(\)/g, replacement: 'super()' }, // PHP函数转换 { pattern: /empty\s*\(\s*([^)]+)\s*\)/g, replacement: '!$1' }, { pattern: /isset\s*\(\s*([^)]+)\s*\)/g, replacement: '$1 !== undefined' }, { pattern: /is_null\s*\(\s*([^)]+)\s*\)/g, replacement: '$1 === null' }, { pattern: /is_array\s*\(\s*([^)]+)\s*\)/g, replacement: 'Array.isArray($1)' }, { pattern: /is_string\s*\(\s*([^)]+)\s*\)/g, replacement: 'typeof $1 === "string"' }, { pattern: /is_numeric\s*\(\s*([^)]+)\s*\)/g, replacement: '!isNaN($1)' }, // 字符串拼接 { pattern: /\.\s*=/g, replacement: '+=' }, { pattern: /\.(\s*['""])/g, replacement: ' + $1' }, // 数组语法 { pattern: /array\(\)/g, replacement: '[]' }, { pattern: /array\(([^)]+)\)/g, replacement: '[$1]' }, ]; } /** * 智能分类:判断文件应该迁移到Core层还是使用Common基础设施 */ classifyFile(filePath, className, content) { const fileName = path.basename(filePath, '.php'); const fullContext = `${fileName} ${className} ${content}`.toLowerCase(); // 检查是否应该使用Common基础设施 for (const pattern of this.hybridClassificationRules.useCommonInfrastructure) { if (pattern.test(fileName) || pattern.test(className) || pattern.test(content)) { return 'INFRASTRUCTURE'; } } // 检查是否应该迁移到Core层 for (const pattern of this.hybridClassificationRules.coreBusinessLogic) { if (pattern.test(fileName) || pattern.test(className) || pattern.test(content)) { return 'CORE_BUSINESS'; } } // 默认根据模块名判断 const moduleName = this.extractModuleName(filePath); if (['sys', 'upload', 'config', 'export'].includes(moduleName)) { return 'INFRASTRUCTURE'; // 基础服务 } return 'CORE_BUSINESS'; // 默认为业务逻辑 } /** * 从文件路径提取模块名 */ extractModuleName(filePath) { const match = filePath.match(/\/([^\/]+)\/.+\.php$/); return match ? match[1] : 'unknown'; } /** * 替换PHP基础设施调用为NestJS基础设施调用 */ replaceInfrastructureCalls(tsCode) { let convertedCode = tsCode; // 替换PHP基础类为NestJS Common层 const infrastructureReplacements = [ { from: /BaseController/g, to: '@wwjCommon/base/base.controller' }, { from: /BaseService/g, to: '@wwjCommon/service/base.service' }, { from: /core\\cache\\RedisCacheService/g, to: '@wwjCommon/cache/cache.service' }, { from: /CoreRequestService/g, to: '@wwjCommon/request/request.service' }, { from: /BaseApiService/g, to: '@wwjCommon/service/base-api.service' }, { from: /CoreLogService/g, to: '@wwjCommon/log/log.service' } ]; infrastructureReplacements.forEach(({ from, to }) => { convertedCode = convertedCode.replace(from, to); }); return convertedCode; } /** * 转换PHP业务逻辑到TypeScript */ convertBusinessLogic(content, methodName, phpCode) { try { console.log(`🔄 转换方法: ${methodName}`); let convertedCode = phpCode; // 1. 先转换PHP语法到TypeScript convertedCode = convertedCode // 变量转换 - 移除$符号 (必须在->转换之前) .replace(/\$this->([a-zA-Z_][a-zA-Z0-9_]*)/g, 'this.$1') .replace(/\$([a-zA-Z_][a-zA-Z0-9_]*)/g, '$1') // PHP数组语法 => 转换为对象属性 : .replace(/'([a-zA-Z_][a-zA-Z0-9_]*)'\s*=>/g, '$1:') .replace(/"([a-zA-Z_][a-zA-Z0-9_]*)"\s*=>/g, '$1:') // PHP空值合并 ?? 转换为 || .replace(/\?\?/g, '||') // PHP对象访问 -> 转换为 . (必须在$转换之后) .replace(/->/g, '.') // PHP静态访问 :: 转换为 . .replace(/::/g, '.') // PHP new对象转换 - 修复转换逻辑(避免重复Service后缀) .replace(/\(new\s+([A-Z][a-zA-Z0-9_]*)\(\)\)/g, (match, serviceName) => { if (serviceName.endsWith('Service')) { return `this.${serviceName.charAt(0).toLowerCase() + serviceName.slice(1)}`; } else { return `this.${serviceName.charAt(0).toLowerCase() + serviceName.slice(1)}Service`; } }) .replace(/new\s+([A-Z][a-zA-Z0-9_]*)\(\)/g, (match, serviceName) => { if (serviceName.endsWith('Service')) { return `this.${serviceName.charAt(0).toLowerCase() + serviceName.slice(1)}`; } else { return `this.${serviceName.charAt(0).toLowerCase() + serviceName.slice(1)}Service`; } }) // PHP类型声明转换为TypeScript .replace(/array\s+/g, '') .replace(/:\s*array/g, ': any[]') // 变量声明添加const/let .replace(/^(\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*=/gm, '$1const $2 =') // 修复数组访问 .replace(/\['([^']+)'\]/g, '.$1') .replace(/\["([^"]+)"\]/g, '.$1') // 修复PHP函数调用 .replace(/array_merge\s*\(/g, 'Object.assign(') .replace(/strpos\s*\(/g, 'String.prototype.indexOf.call(') .replace(/throw\s+new\s+([A-Z][a-zA-Z0-9_]*)\s*\(/g, 'throw new $1(') // 修复PHP条件语句 .replace(/if\s*\(\s*([^)]+)\s*\)\s*\{/g, 'if ($1) {') .replace(/else\s*\{/g, '} else {') // 修复PHP静态变量访问 .replace(/self::\$([a-zA-Z_][a-zA-Z0-9_]*)/g, 'self.$1') .replace(/static::\$([a-zA-Z_][a-zA-Z0-9_]*)/g, 'static.$1') // 修复PHP is_null函数 .replace(/is_null\s*\(\s*([^)]+)\s*\)/g, '$1 === null') // 修复PHP new static调用 .replace(/new\s+static\s*\(([^)]*)\)/g, 'new this.constructor($1)') // 修复PHP数组语法错误 .replace(/\[\s*\]/g, '[]') .replace(/\(\s*\)/g, '()') // 修复PHP变量赋值错误 .replace(/=\s*=\s*=/g, '===') .replace(/=\s*=\s*null/g, '=== null') // 修复重复的等号 .replace(/====/g, '===') .replace(/=====/g, '===') // 修复方括号错误 - 修复函数调用中的方括号(排除数组语法) .replace(/\(([^)]+)\]/g, '($1)') // 移除错误的替换规则,避免破坏数组语法 // .replace(/(\w+)\]/g, (match, word) => { // // 排除数组元素的情况,避免将 [ 'key', 'value' ] 转换为 [ 'key', 'value' ) // // 检查是否在数组上下文中 // const beforeMatch = code.substring(0, code.indexOf(match)); // const lastBracket = beforeMatch.lastIndexOf('['); // const lastParen = beforeMatch.lastIndexOf('('); // // // 如果最近的符号是 [ 而不是 (,说明在数组上下文中,不应该替换 // if (lastBracket > lastParen) { // return match; // } // // return word + ')'; // }) // 修复数组语法中的方括号错误 - 直接修复(处理单引号和双引号) .replace(/\[\s*\(\s*'([^']+)',\s*''\s*\)\s*\)/g, "['$1', '']") .replace(/\[\s*\(\s*'([^']+)',\s*0\s*\)\s*\)/g, "['$1', 0]") .replace(/\[\s*\(\s*\"([^\"]+)\",\s*\"\"\s*\)\s*\)/g, '["$1", ""]') .replace(/\[\s*\(\s*\"([^\"]+)\",\s*0\s*\)\s*\)/g, '["$1", 0]') // 移除这些错误的替换规则,避免破坏数组语法 // .replace(/\]\s*;/g, ');') // .replace(/\]\s*\)/g, '))') // .replace(/\]\s*\{/g, ') {') // .replace(/\]\s*,/g, '),') // 修复数组语法中的方括号错误 - 更精确的匹配 .replace(/\[\s*\(\s*'([^']+)',\s*''\s*\)\s*\)/g, "['$1', '']") .replace(/\[\s*\(\s*'([^']+)',\s*0\s*\)\s*\)/g, "['$1', 0]") // 修复数组语法中的方括号错误 .replace(/\[\s*\(\s*([^)]+)\s*\)\s*\]/g, '[$1]') .replace(/\[\s*\(\s*([^)]+)\s*\)\s*\)/g, '[$1]') // 修复数组元素中的方括号错误 .replace(/\[\s*\(\s*'([^']+)',\s*'([^']+)'\s*\)\s*\)/g, "['$1', '$2']") .replace(/\[\s*\(\s*'([^']+)',\s*(\d+)\s*\)\s*\)/g, "['$1', $2]") .replace(/\[\s*\(\s*'([^']+)',\s*""\s*\)\s*\)/g, "['$1', '']") // 修复特定的方括号错误模式 - 只修复函数调用中的方括号,不修复数组语法 // 移除这些错误的替换规则,避免破坏数组语法 // .replace(/(\w+_id)\]/g, '$1)') // .replace(/(\w+_key)\]/g, '$1)') // .replace(/(\w+_type)\]/g, '$1)') // .replace(/(\w+_name)\]/g, '$1)') // .replace(/(\w+_code)\]/g, '$1)') // .replace(/(\w+_value)\]/g, '$1)') // 修复函数调用中的方括号错误 - 只修复函数调用中的方括号,不修复数组语法 // 移除这些错误的替换规则,避免破坏数组语法 // .replace(/(\w+)\(([^)]+)\]/g, '$1($2)') // .replace(/(\w+)\.(\w+)\(([^)]+)\]/g, '$1.$2($3)') // 修复PHP方法声明 .replace(/public\s+function\s+/g, 'async ') .replace(/private\s+function\s+/g, 'private async ') .replace(/protected\s+function\s+/g, 'protected async ') // 修复PHP返回语句 .replace(/return\s+this;/g, 'return this;') // 修复PHP异常处理 .replace(/CommonException/g, 'BusinessException') .replace(/(? 0 && content[i-1] !== '\\') { inString = false; stringChar = ''; } } // 只在非字符串状态下计算大括号 if (!inString) { if (char === '{') { if (!foundFirstBrace) { foundFirstBrace = true; i++; continue; } braceCount++; } else if (char === '}') { if (foundFirstBrace && braceCount === 0) { return content.substring(startPos, i); } braceCount--; } } i++; } return content.substring(startPos); } /** * 生成服务层参数定义 */ generateServiceParameters(parameters) { if (!parameters || parameters.length === 0) return ''; return parameters.map(param => { const defaultValue = param.defaultValue ? ` = ${param.defaultValue.replace(/'/g, '"').replace(/^"([^"]*)"$/, '"$1"')}` : ''; return `${param.name}: ${param.type}${defaultValue}`; }).join(', '); } /** * 清理和验证生成的TypeScript代码 */ cleanAndValidateTypeScriptCode(code) { let cleanedCode = code; // 移除PHP语法残留 cleanedCode = cleanedCode // 移除PHP注释语法 .replace(/\/\*\*\s*\*\s*@param\s+\$[a-zA-Z_][a-zA-Z0-9_]*\s+[^\n]*\n/g, '') .replace(/\/\*\*\s*\*\s*@return\s+[^\n]*\n/g, '') .replace(/\/\*\*\s*\*\s*@throws\s+[^\n]*\n/g, '') // 修复PHP方法声明残留 .replace(/public\s+function\s+/g, 'async ') .replace(/private\s+function\s+/g, 'private async ') .replace(/protected\s+function\s+/g, 'protected async ') // 修复PHP变量声明 .replace(/\$([a-zA-Z_][a-zA-Z0-9_]*)\s*=/g, 'const $1 =') // 修复PHP数组语法 .replace(/array\s*\(\s*\)/g, '[]') .replace(/array\s*\(/g, '[') .replace(/\)\s*;/g, '];') // 修复PHP字符串拼接 .replace(/\.\s*=/g, ' += ') .replace(/\.\s*['"]/g, ' + \'') // 修复PHP条件语句 .replace(/if\s*\(\s*([^)]+)\s*\)\s*\{/g, 'if ($1) {') .replace(/else\s*\{/g, '} else {') // 修复PHP异常处理 .replace(/throw\s+new\s+CommonException\s*\(/g, 'throw new BusinessException(') .replace(/throw\s+new\s+Exception\s*\(/g, 'throw new BusinessException(') // 修复PHP函数调用 .replace(/array_merge\s*\(/g, 'Object.assign(') .replace(/strpos\s*\(/g, 'String.prototype.indexOf.call(') .replace(/empty\s*\(/g, '!') .replace(/isset\s*\(/g, 'typeof ') .replace(/is_null\s*\(/g, '=== null') // 修复方括号错误 - 只修复函数调用中的方括号,不修复数组语法 .replace(/\(([^)]+)\]/g, '($1)') // 移除错误的替换规则,避免破坏数组语法 // .replace(/(\w+)\]/g, '$1)') // 这个规则会破坏数组语法 // 移除这些错误的替换规则,避免破坏数组语法 // .replace(/\]\s*;/g, ');') // .replace(/\]\s*\)/g, '))') // .replace(/\]\s*\{/g, ') {') // .replace(/\]\s*,/g, '),') // 修复数组语法中的方括号错误 .replace(/\[\s*\(\s*([^)]+)\s*\)\s*\]/g, '[$1]') .replace(/\[\s*\(\s*([^)]+)\s*\)\s*\)/g, '[$1]') // 修复数组元素中的方括号错误 .replace(/\[\s*\(\s*'([^']+)',\s*'([^']+)'\s*\)\s*\)/g, "['$1', '$2']") .replace(/\[\s*\(\s*'([^']+)',\s*(\d+)\s*\)\s*\)/g, "['$1', $2]") .replace(/\[\s*\(\s*'([^']+)',\s*""\s*\)\s*\)/g, "['$1', '']") // 修复数组元素中的圆括号错误 - 更精确的匹配 .replace(/\[\s*\(\s*'([^']+)',\s*'([^']+)'\s*\)\s*\)/g, "['$1', '$2']") .replace(/\[\s*\(\s*'([^']+)',\s*(\d+)\s*\)\s*\)/g, "['$1', $2]") .replace(/\[\s*\(\s*'([^']+)',\s*""\s*\)\s*\)/g, "['$1', '']") // 修复数组元素中的圆括号错误 - 处理空字符串(单引号和双引号) .replace(/\[\s*\(\s*'([^']+)',\s*''\s*\)\s*\)/g, "['$1', '']") .replace(/\[\s*\(\s*'([^']+)',\s*0\s*\)\s*\)/g, "['$1', 0]") .replace(/\[\s*\(\s*\"([^\"]+)\",\s*\"\"\s*\)\s*\)/g, '["$1", ""]') .replace(/\[\s*\(\s*\"([^\"]+)\",\s*0\s*\)\s*\)/g, '["$1", 0]') // 修复数组语法中的方括号错误 - 直接修复 .replace(/\[\s*\(\s*'([^']+)',\s*''\s*\)\s*\)/g, "['$1', '']") .replace(/\[\s*\(\s*'([^']+)',\s*0\s*\)\s*\)/g, "['$1', 0]") // 修复数组语法中的方括号错误 - 处理所有情况 .replace(/\[\s*\(\s*'([^']+)',\s*''\s*\)\s*\)/g, "['$1', '']") .replace(/\[\s*\(\s*'([^']+)',\s*0\s*\)\s*\)/g, "['$1', 0]") // 修复数组语法中的方括号错误 - 最终修复 .replace(/\[\s*\(\s*'([^']+)',\s*''\s*\)\s*\)/g, "['$1', '']") .replace(/\[\s*\(\s*'([^']+)',\s*0\s*\)\s*\)/g, "['$1', 0]") .replace(/is_array\s*\(/g, 'Array.isArray(') .replace(/is_string\s*\(/g, 'typeof ') .replace(/is_numeric\s*\(/g, '!isNaN(') // 修复PHP对象访问 .replace(/->/g, '.') .replace(/::/g, '.') // 修复PHP空值合并 .replace(/\?\?/g, '||') // 修复PHP数组访问 .replace(/\['([^']+)'\]/g, '.$1') .replace(/\["([^"]+)"\]/g, '.$1') // 修复PHP类型声明 .replace(/:\s*array/g, ': any[]') .replace(/:\s*string/g, ': string') .replace(/:\s*int/g, ': number') .replace(/:\s*float/g, ': number') .replace(/:\s*bool/g, ': boolean') // 移除PHP语法残留 .replace(/\$([a-zA-Z_][a-zA-Z0-9_]*)/g, '$1') // 修复方法体格式 .replace(/\{\s*\}/g, '{\n // 待实现\n }') .replace(/\{\s*return\s+this;\s*\}/g, '{\n return this;\n }'); // 修复严重的语法错误 cleanedCode = this.fixCriticalSyntaxErrors(cleanedCode); // 验证TypeScript语法 const validationErrors = this.validateTypeScriptSyntax(cleanedCode); if (validationErrors.length > 0) { console.warn('⚠️ TypeScript语法警告:', validationErrors); } return cleanedCode; } /** * 修复严重的语法错误 */ fixCriticalSyntaxErrors(code) { return code // 修复不完整的类结构 .replace(/export class \w+ \{[^}]*\}\s*\}\s*$/gm, (match) => { return match.replace(/\}\s*\}\s*$/, '}'); }) // 修复不完整的构造函数 .replace(/constructor\([^)]*\)\s*\{\s*\/\/ 待实现\s*\}\s*\}\s*super\([^)]*\)\s*;\s*\}\s*$/gm, (match) => { return match.replace(/\}\s*\}\s*super\([^)]*\)\s*;\s*\}\s*$/, ' super(repository);\n }'); }) // 修复不完整的方法体 .replace(/async \w+\([^)]*\)\s*\{\s*\/\/ 待实现\s*\}\s*\}\s*try\s*\{/gm, (match) => { return match.replace(/\}\s*\}\s*try\s*\{/, ' {\n try {'); }) // 修复不完整的try-catch块 .replace(/try\s*\{\s*\/\/ 待实现\s*\}\s*\}\s*catch\s*\([^)]*\)\s*\{/gm, (match) => { return match.replace(/\}\s*\}\s*catch\s*\([^)]*\)\s*\{/, ' // 待实现\n } catch (error) {'); }) // 修复不完整的异常处理 .replace(/throw new BusinessException\('[^']*',\s*error\]\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/error\]\s*;\s*\}\s*\}\s*$/, 'error);\n }\n }'); }) // 修复不完整的import语句 .replace(/import\s*\{\s*\/\/ 待实现\s*\}\s*\}\s*from/gm, (match) => { return match.replace(/\{\s*\/\/ 待实现\s*\}\s*\}\s*from/, '{\n } from'); }) // 修复不完整的装饰器 .replace(/@\w+\([^)]*\)\s*\{\s*\/\/ 待实现\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\}\s*\}\s*$/, '}'); }) // 修复不完整的数组语法 .replace(/\[\s*\]\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\}\s*\}\s*$/, '}'); }) // 修复不完整的对象语法 .replace(/\{\s*\}\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\}\s*\}\s*$/, '}'); }) // 修复不完整的字符串 .replace(/'[^']*\]\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\]\s*;\s*\}\s*\}\s*$/, ';\n }'); }) // 修复不完整的括号 .replace(/\(\s*\)\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\}\s*\}\s*$/, '}'); }) // 修复不完整的方括号 .replace(/\[\s*\]\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\}\s*\}\s*$/, '}'); }) // 修复不完整的尖括号 .replace(/<\s*>\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\}\s*\}\s*$/, '}'); }) // 修复不完整的注释 .replace(/\/\/[^\n]*\]\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\]\s*;\s*\}\s*\}\s*$/, ';\n }'); }) // 修复不完整的多行注释 .replace(/\/\*[\s\S]*?\*\/\s*\]\s*;\s*\}\s*\}\s*$/gm, (match) => { return match.replace(/\]\s*;\s*\}\s*\}\s*$/, ';\n }'); }); } /** * 验证TypeScript语法 */ validateTypeScriptSyntax(code) { const errors = []; // 检查常见语法错误 if (code.includes('=>')) { errors.push('发现PHP数组语法 => 未转换'); } if (code.includes('??')) { errors.push('发现PHP空值合并 ?? 未转换'); } if (code.includes('::')) { errors.push('发现PHP静态访问 :: 未转换'); } if (code.includes('->')) { errors.push('发现PHP对象访问 -> 未转换'); } if (code.includes('$')) { errors.push('发现PHP变量 $ 未转换'); } if (code.includes('array(')) { errors.push('发现PHP数组语法 array() 未转换'); } if (code.includes('public function') || code.includes('private function') || code.includes('protected function')) { errors.push('发现PHP方法声明未转换'); } // 检查严重的语法错误 if (code.includes(']') && !code.includes('[')) { errors.push('发现不完整的方括号 ]'); } if (code.includes('}') && !code.includes('{')) { errors.push('发现不完整的大括号 }'); } // 检查括号匹配 const openBraces = (code.match(/\{/g) || []).length; const closeBraces = (code.match(/\}/g) || []).length; if (openBraces !== closeBraces) { errors.push(`大括号不匹配: 开括号${openBraces}个, 闭括号${closeBraces}个`); } const openBrackets = (code.match(/\[/g) || []).length; const closeBrackets = (code.match(/\]/g) || []).length; if (openBrackets !== closeBrackets) { errors.push(`方括号不匹配: 开括号${openBrackets}个, 闭括号${closeBrackets}个`); } if (code.includes('// 待实现')) { errors.push('发现未实现的方法体'); } return errors; } } module.exports = BusinessLogicConverter;