|
|
|
@ -10,25 +10,9 @@ const traverse = require('@babel/traverse').default
@@ -10,25 +10,9 @@ const traverse = require('@babel/traverse').default
|
|
|
|
|
*/ |
|
|
|
|
class CallChainTracer { |
|
|
|
|
constructor() { |
|
|
|
|
this.debugMode = process.env.ROUTE_MAPPING_DEBUG === 'true' || process.argv.includes('--debug') |
|
|
|
|
this.processedFiles = new Set() // 跟踪已处理的文件,避免重复处理
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 调试日志输出 |
|
|
|
|
* @param {string} message - 日志消息 |
|
|
|
|
* @param {any} data - 附加数据 |
|
|
|
|
*/ |
|
|
|
|
debugLog(message, data = null) { |
|
|
|
|
if (this.debugMode) { |
|
|
|
|
const timestamp = new Date().toISOString() |
|
|
|
|
if (data) { |
|
|
|
|
console.log(`[${timestamp}] [CallChainTracer] ${message}`, data) |
|
|
|
|
} else { |
|
|
|
|
console.log(`[${timestamp}] [CallChainTracer] ${message}`) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 清理已处理文件的记录 |
|
|
|
@ -36,7 +20,6 @@ class CallChainTracer {
@@ -36,7 +20,6 @@ class CallChainTracer {
|
|
|
|
|
*/ |
|
|
|
|
clearProcessedFiles() { |
|
|
|
|
this.processedFiles.clear() |
|
|
|
|
this.debugLog('已清理已处理文件记录') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -45,41 +28,35 @@ class CallChainTracer {
@@ -45,41 +28,35 @@ class CallChainTracer {
|
|
|
|
|
* @returns {Array} 增强的API映射数组 |
|
|
|
|
*/ |
|
|
|
|
traceMethodTriggersToVisualComponents(apiMappings) { |
|
|
|
|
const enhancedApiMappings = apiMappings.map(module => { |
|
|
|
|
const enhancedApiMappings = module.apiMappings.map(api => { |
|
|
|
|
if (!api.triggerSources || api.triggerSources.length === 0) { |
|
|
|
|
return api |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 只处理triggerType为method的触发源
|
|
|
|
|
const enhancedTriggerSources = api.triggerSources.map(trigger => { |
|
|
|
|
if (trigger.triggerType === 'method') { |
|
|
|
|
const result = this.traceMethodToVisualComponent( |
|
|
|
|
trigger, |
|
|
|
|
module.module, |
|
|
|
|
module.serviceName, |
|
|
|
|
api.apiMethodName |
|
|
|
|
) |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
return trigger |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
...api, |
|
|
|
|
triggerSources: enhancedTriggerSources |
|
|
|
|
const enhancedApiMappings = apiMappings.map(api => { |
|
|
|
|
if (!api.triggerSources || api.triggerSources.length === 0) { |
|
|
|
|
return api |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 只处理triggerType为method的触发源
|
|
|
|
|
const enhancedTriggerSources = api.triggerSources.map(trigger => { |
|
|
|
|
if (trigger.triggerType === 'method') { |
|
|
|
|
const result = this.traceMethodToVisualComponent( |
|
|
|
|
trigger, |
|
|
|
|
api.module, |
|
|
|
|
api.serviceName, |
|
|
|
|
api.apiMethodName |
|
|
|
|
) |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
return trigger |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
...module, |
|
|
|
|
apiMappings: enhancedApiMappings |
|
|
|
|
...api, |
|
|
|
|
triggerSources: enhancedTriggerSources |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
return enhancedApiMappings |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 追溯单个method到可视控件 |
|
|
|
|
* @param {Object} trigger - 触发源对象 |
|
|
|
@ -611,19 +588,15 @@ class CallChainTracer {
@@ -611,19 +588,15 @@ class CallChainTracer {
|
|
|
|
|
// 检查文件是否已经被处理过,避免重复处理
|
|
|
|
|
const fileKey = `${filePath}-${nameValue}` |
|
|
|
|
if (this.processedFiles.has(fileKey)) { |
|
|
|
|
this.debugLog(`文件 ${filePath} 的 ${nameValue} 已被处理过,跳过`) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const content = readFileSync(filePath, 'utf-8') |
|
|
|
|
|
|
|
|
|
this.debugLog(`开始修改Vue文件: ${filePath}`) |
|
|
|
|
this.debugLog(`目标节点: ${node.tag}, name: ${nameValue}, type: ${triggerType}`) |
|
|
|
|
|
|
|
|
|
// 获取节点的位置信息
|
|
|
|
|
const loc = node.loc |
|
|
|
|
if (!loc) { |
|
|
|
|
this.debugLog(`节点没有位置信息,无法修改Vue元素`) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -632,7 +605,6 @@ class CallChainTracer {
@@ -632,7 +605,6 @@ class CallChainTracer {
|
|
|
|
|
const endLine = loc.end.line |
|
|
|
|
const endColumn = loc.end.column |
|
|
|
|
|
|
|
|
|
this.debugLog(`节点位置: 第${startLine}行第${startColumn}列 到 第${endLine}行第${endColumn}列`) |
|
|
|
|
|
|
|
|
|
const lines = content.split('\n') |
|
|
|
|
|
|
|
|
@ -640,7 +612,6 @@ class CallChainTracer {
@@ -640,7 +612,6 @@ class CallChainTracer {
|
|
|
|
|
const targetLine = lines[startLine - 1] |
|
|
|
|
if (targetLine.includes(`name="`) || targetLine.includes(`name='`) ||
|
|
|
|
|
targetLine.includes(`:visible="false"`) || targetLine.includes(`:visible='false'`)) { |
|
|
|
|
this.debugLog(`元素已包含name或:visible属性,跳过修改`) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -659,12 +630,9 @@ class CallChainTracer {
@@ -659,12 +630,9 @@ class CallChainTracer {
|
|
|
|
|
// 标记文件为已处理
|
|
|
|
|
this.processedFiles.add(fileKey) |
|
|
|
|
|
|
|
|
|
this.debugLog(`已成功修改Vue文件: ${filePath}`) |
|
|
|
|
this.debugLog(`添加的属性: name="${nameValue}"${triggerType === 'button' ? ', :visible="false"' : ', :disabled="true"'}`) |
|
|
|
|
|
|
|
|
|
} catch (error) { |
|
|
|
|
this.debugLog(`修改Vue元素时出错:`, error.message) |
|
|
|
|
this.debugLog(`错误堆栈:`, error.stack) |
|
|
|
|
// 静默处理错误
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -679,12 +647,10 @@ class CallChainTracer {
@@ -679,12 +647,10 @@ class CallChainTracer {
|
|
|
|
|
*/ |
|
|
|
|
modifySingleLineElement(lines, lineIndex, startCol, endCol, nameValue, triggerType) { |
|
|
|
|
const line = lines[lineIndex] |
|
|
|
|
this.debugLog(`修改单行元素: ${line}`) |
|
|
|
|
|
|
|
|
|
// 检查是否已经存在name属性或:visible属性,避免重复修改
|
|
|
|
|
if (line.includes(`name="`) || line.includes(`name='`) ||
|
|
|
|
|
line.includes(`:visible="false"`) || line.includes(`:visible='false'`)) { |
|
|
|
|
this.debugLog(`单行元素已包含name或:visible属性,跳过修改`) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -706,7 +672,6 @@ class CallChainTracer {
@@ -706,7 +672,6 @@ class CallChainTracer {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
lines[lineIndex] = `${beforeTag}${newAttributes}${afterTag}` |
|
|
|
|
this.debugLog(`单行元素修改完成: ${lines[lineIndex]}`) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -722,7 +687,6 @@ class CallChainTracer {
@@ -722,7 +687,6 @@ class CallChainTracer {
|
|
|
|
|
*/ |
|
|
|
|
modifyMultiLineElement(lines, startLineIndex, startCol, endLineIndex, endCol, nameValue, triggerType) { |
|
|
|
|
const startLine = lines[startLineIndex] |
|
|
|
|
this.debugLog(`修改多行元素开始行: ${startLine}`) |
|
|
|
|
|
|
|
|
|
// 检查整个多行元素是否已经存在name属性或:visible属性,避免重复修改
|
|
|
|
|
let hasExistingAttributes = false |
|
|
|
@ -736,7 +700,6 @@ class CallChainTracer {
@@ -736,7 +700,6 @@ class CallChainTracer {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (hasExistingAttributes) { |
|
|
|
|
this.debugLog(`多行元素已包含name或:visible属性,跳过修改`) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -748,14 +711,12 @@ class CallChainTracer {
@@ -748,14 +711,12 @@ class CallChainTracer {
|
|
|
|
|
|
|
|
|
|
// 如果当前行没有找到结束标签,查找后续行
|
|
|
|
|
if (tagStart !== -1 && tagEnd === -1) { |
|
|
|
|
this.debugLog(`当前行没有找到结束标签,查找后续行`) |
|
|
|
|
for (let i = startLineIndex; i <= endLineIndex && i < lines.length; i++) { |
|
|
|
|
const line = lines[i] |
|
|
|
|
const endPos = line.indexOf('>') |
|
|
|
|
if (endPos !== -1) { |
|
|
|
|
tagEnd = endPos |
|
|
|
|
tagEndLineIndex = i |
|
|
|
|
this.debugLog(`在第${i + 1}行找到结束标签,位置: ${endPos}`) |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -776,12 +737,9 @@ class CallChainTracer {
@@ -776,12 +737,9 @@ class CallChainTracer {
|
|
|
|
|
const afterEndTag = endLine.substring(tagEnd) |
|
|
|
|
|
|
|
|
|
lines[tagEndLineIndex] = `${beforeEndTag}${newAttributes}${afterEndTag}` |
|
|
|
|
this.debugLog(`多行元素修改完成: ${lines[tagEndLineIndex]}`) |
|
|
|
|
} else { |
|
|
|
|
this.debugLog(`未找到有效的标签位置: tagStart=${tagStart}, tagEnd=${tagEnd}`) |
|
|
|
|
// 如果找不到结束标签,尝试在开始标签后直接添加
|
|
|
|
|
if (tagStart !== -1) { |
|
|
|
|
this.debugLog(`尝试在开始标签后直接添加属性`) |
|
|
|
|
const beforeTag = startLine.substring(0, tagStart + 1) // 包含 < 字符
|
|
|
|
|
const afterTag = startLine.substring(tagStart + 1) |
|
|
|
|
|
|
|
|
@ -793,7 +751,6 @@ class CallChainTracer {
@@ -793,7 +751,6 @@ class CallChainTracer {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
lines[startLineIndex] = `${beforeTag}${newAttributes} ${afterTag}` |
|
|
|
|
this.debugLog(`多行元素修改完成(备用方案): ${lines[startLineIndex]}`) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|