|
|
import { resolve } from 'path' |
|
|
import fs from 'fs' |
|
|
import * as parser from '@babel/parser' |
|
|
import traverse from '@babel/traverse' |
|
|
import { parse } from '@vue/compiler-sfc' |
|
|
|
|
|
// 路由映射插件 - 真正利用AST解析和Vite编译时关系 |
|
|
export function routeMappingPlugin() { |
|
|
return { |
|
|
name: 'route-mapping', |
|
|
|
|
|
// 在构建开始时执行 |
|
|
buildStart() { |
|
|
console.log('🔧 开始分析AST和Vite编译时关系...') |
|
|
this.analyzeASTAndViteRelations() |
|
|
}, |
|
|
|
|
|
// 在开发模式下也执行 |
|
|
configureServer(server) { |
|
|
console.log('🔧 开发模式下分析AST和Vite编译时关系...') |
|
|
this.analyzeASTAndViteRelations() |
|
|
}, |
|
|
|
|
|
// 利用AST和Vite编译时API分析关系 |
|
|
analyzeASTAndViteRelations() { |
|
|
try { |
|
|
// 1. 分析路由配置的AST |
|
|
const routerAST = this.analyzeRouterAST() |
|
|
|
|
|
// 2. 分析组件文件的AST |
|
|
const componentASTs = this.analyzeComponentASTs() |
|
|
|
|
|
// 3. 分析服务文件的AST |
|
|
const serviceASTs = this.analyzeServiceASTs() |
|
|
|
|
|
// 4. 建立真实的调用关系 |
|
|
const callRelations = this.buildCallRelations(routerAST, componentASTs, serviceASTs) |
|
|
|
|
|
// 5. 生成真实的路由映射 |
|
|
const routeMappings = this.generateRealRouteMappings(callRelations) |
|
|
|
|
|
// 6. 生成映射文件 |
|
|
this.generateRouteMappingFile(routeMappings) |
|
|
|
|
|
console.log('✅ AST和Vite编译时关系分析完成') |
|
|
} catch (error) { |
|
|
console.error('❌ AST和Vite编译时关系分析失败:', error) |
|
|
// 回退到简单分析 |
|
|
this.fallbackToSimpleAnalysis() |
|
|
} |
|
|
}, |
|
|
|
|
|
// 分析路由AST |
|
|
analyzeRouterAST() { |
|
|
const routerPath = resolve(__dirname, '../src/renderer/router/index.js') |
|
|
if (!fs.existsSync(routerPath)) { |
|
|
throw new Error('Router file not found') |
|
|
} |
|
|
|
|
|
const routerContent = fs.readFileSync(routerPath, 'utf-8') |
|
|
const ast = parser.parse(routerContent, { |
|
|
sourceType: 'module', |
|
|
plugins: ['jsx'] |
|
|
}) |
|
|
|
|
|
const routes = [] |
|
|
|
|
|
traverse(ast, { |
|
|
// 查找路由配置对象 |
|
|
ObjectExpression(path) { |
|
|
const properties = path.node.properties |
|
|
let route = {} |
|
|
|
|
|
properties.forEach(prop => { |
|
|
if (prop.key && prop.key.name === 'path' && prop.value && prop.value.value) { |
|
|
route.path = prop.value.value |
|
|
} |
|
|
if (prop.key && prop.key.name === 'name' && prop.value && prop.value.value) { |
|
|
route.name = prop.value.value |
|
|
} |
|
|
if (prop.key && prop.key.name === 'component' && prop.value) { |
|
|
route.component = this.extractComponentName(prop.value) |
|
|
} |
|
|
}) |
|
|
|
|
|
if (route.path) { |
|
|
route.module = this.extractModuleFromPath(route.path) |
|
|
routes.push(route) |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
return { routes, ast } |
|
|
}, |
|
|
|
|
|
// 分析组件AST |
|
|
analyzeComponentASTs() { |
|
|
const componentASTs = new Map() |
|
|
const componentFiles = this.findComponentFiles() |
|
|
|
|
|
componentFiles.forEach(componentFile => { |
|
|
try { |
|
|
const content = fs.readFileSync(componentFile.path, 'utf-8') |
|
|
|
|
|
if (componentFile.path.endsWith('.vue')) { |
|
|
// 解析Vue文件 |
|
|
const { descriptor } = parse(content) |
|
|
const scriptContent = descriptor.script?.content || '' |
|
|
|
|
|
if (scriptContent) { |
|
|
const scriptAST = parser.parse(scriptContent, { |
|
|
sourceType: 'module', |
|
|
plugins: ['jsx'] |
|
|
}) |
|
|
|
|
|
const analysis = this.analyzeVueComponentAST(scriptAST, componentFile.name) |
|
|
componentASTs.set(componentFile.name, { |
|
|
...analysis, |
|
|
file: componentFile, |
|
|
template: descriptor.template?.content || '' |
|
|
}) |
|
|
} |
|
|
} else { |
|
|
// 解析JS文件 |
|
|
const ast = parser.parse(content, { |
|
|
sourceType: 'module', |
|
|
plugins: ['jsx'] |
|
|
}) |
|
|
|
|
|
const analysis = this.analyzeJavaScriptComponentAST(ast, componentFile.name) |
|
|
componentASTs.set(componentFile.name, { |
|
|
...analysis, |
|
|
file: componentFile |
|
|
}) |
|
|
} |
|
|
} catch (error) { |
|
|
console.warn(`⚠️ 解析组件文件失败: ${componentFile.path}`, error.message) |
|
|
} |
|
|
}) |
|
|
|
|
|
return componentASTs |
|
|
}, |
|
|
|
|
|
// 分析服务AST |
|
|
analyzeServiceASTs() { |
|
|
const serviceASTs = new Map() |
|
|
const serviceFiles = this.findServiceFiles() |
|
|
|
|
|
serviceFiles.forEach(serviceFile => { |
|
|
try { |
|
|
const content = fs.readFileSync(serviceFile.path, 'utf-8') |
|
|
const ast = parser.parse(content, { |
|
|
sourceType: 'module', |
|
|
plugins: ['jsx'] |
|
|
}) |
|
|
|
|
|
const analysis = this.analyzeServiceAST(ast, serviceFile.name) |
|
|
serviceASTs.set(serviceFile.name, { |
|
|
...analysis, |
|
|
file: serviceFile |
|
|
}) |
|
|
} catch (error) { |
|
|
console.warn(`⚠️ 解析服务文件失败: ${serviceFile.path}`, error.message) |
|
|
} |
|
|
}) |
|
|
|
|
|
return serviceASTs |
|
|
}, |
|
|
|
|
|
// 分析Vue组件AST |
|
|
analyzeVueComponentAST(ast, componentName) { |
|
|
const analysis = { |
|
|
imports: [], |
|
|
exports: [], |
|
|
methods: [], |
|
|
serviceCalls: [], |
|
|
events: [] |
|
|
} |
|
|
|
|
|
traverse(ast, { |
|
|
// 查找import语句 |
|
|
ImportDeclaration(path) { |
|
|
const importSpecifiers = path.node.specifiers |
|
|
importSpecifiers.forEach(specifier => { |
|
|
if (specifier.type === 'ImportSpecifier') { |
|
|
analysis.imports.push({ |
|
|
name: specifier.imported.name, |
|
|
local: specifier.local.name, |
|
|
source: path.node.source.value |
|
|
}) |
|
|
} |
|
|
}) |
|
|
}, |
|
|
|
|
|
// 查找方法定义 |
|
|
FunctionDeclaration(path) { |
|
|
if (path.node.id) { |
|
|
analysis.methods.push(path.node.id.name) |
|
|
} |
|
|
}, |
|
|
|
|
|
// 查找箭头函数 |
|
|
ArrowFunctionExpression(path) { |
|
|
if (path.parent && path.parent.type === 'VariableDeclarator' && path.parent.id) { |
|
|
analysis.methods.push(path.parent.id.name) |
|
|
} |
|
|
}, |
|
|
|
|
|
// 查找服务调用 |
|
|
CallExpression(path) { |
|
|
if (path.node.callee && path.node.callee.type === 'MemberExpression') { |
|
|
const object = path.node.callee.object |
|
|
const property = path.node.callee.property |
|
|
|
|
|
if (object && property && object.name && property.name) { |
|
|
// 检查是否是服务调用 |
|
|
const serviceName = object.name |
|
|
const methodName = property.name |
|
|
|
|
|
if (serviceName.endsWith('Service')) { |
|
|
analysis.serviceCalls.push({ |
|
|
service: serviceName, |
|
|
method: methodName, |
|
|
arguments: path.node.arguments.map(arg => this.extractArgumentValue(arg)) |
|
|
}) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
return analysis |
|
|
}, |
|
|
|
|
|
// 分析JavaScript组件AST |
|
|
analyzeJavaScriptComponentAST(ast, componentName) { |
|
|
return this.analyzeVueComponentAST(ast, componentName) |
|
|
}, |
|
|
|
|
|
// 分析服务AST |
|
|
analyzeServiceAST(ast, serviceName) { |
|
|
const analysis = { |
|
|
exports: [], |
|
|
methods: [], |
|
|
apiCalls: [], |
|
|
imports: [] |
|
|
} |
|
|
|
|
|
traverse(ast, { |
|
|
// 查找export语句 |
|
|
ExportNamedDeclaration(path) { |
|
|
if (path.node.declaration && path.node.declaration.type === 'VariableDeclarator') { |
|
|
analysis.exports.push(path.node.declaration.id.name) |
|
|
} |
|
|
}, |
|
|
|
|
|
// 查找方法定义 |
|
|
FunctionDeclaration(path) { |
|
|
if (path.node.id) { |
|
|
analysis.methods.push(path.node.id.name) |
|
|
} |
|
|
}, |
|
|
|
|
|
// 查找API调用 |
|
|
CallExpression(path) { |
|
|
if (path.node.callee && path.node.callee.type === 'MemberExpression') { |
|
|
const object = path.node.callee.object |
|
|
const property = path.node.callee.property |
|
|
|
|
|
if (object && property) { |
|
|
// 检查是否是API调用 |
|
|
if (object.name === 'api' || object.name === 'axios' || object.name === 'http') { |
|
|
const method = property.name |
|
|
const args = path.node.arguments |
|
|
|
|
|
if (args.length > 0 && args[0].type === 'StringLiteral') { |
|
|
analysis.apiCalls.push({ |
|
|
method: method.toUpperCase(), |
|
|
path: args[0].value, |
|
|
arguments: args.slice(1).map(arg => this.extractArgumentValue(arg)) |
|
|
}) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
return analysis |
|
|
}, |
|
|
|
|
|
// 建立调用关系 |
|
|
buildCallRelations(routerAST, componentASTs, serviceASTs) { |
|
|
const relations = { |
|
|
routes: routerAST.routes, |
|
|
components: new Map(), |
|
|
services: new Map(), |
|
|
callGraph: new Map(), |
|
|
imports: new Map() |
|
|
} |
|
|
|
|
|
// 建立组件关系 |
|
|
componentASTs.forEach((analysis, componentName) => { |
|
|
relations.components.set(componentName, { |
|
|
...analysis, |
|
|
serviceDependencies: analysis.serviceCalls.map(call => call.service) |
|
|
}) |
|
|
}) |
|
|
|
|
|
// 建立服务关系 |
|
|
serviceASTs.forEach((analysis, serviceName) => { |
|
|
relations.services.set(serviceName, { |
|
|
...analysis, |
|
|
apiEndpoints: analysis.apiCalls |
|
|
}) |
|
|
}) |
|
|
|
|
|
// 建立调用图 |
|
|
componentASTs.forEach((componentAnalysis, componentName) => { |
|
|
const calls = [] |
|
|
|
|
|
componentAnalysis.serviceCalls.forEach(call => { |
|
|
calls.push({ |
|
|
type: 'service', |
|
|
target: call.service, |
|
|
method: call.method, |
|
|
component: componentName |
|
|
}) |
|
|
}) |
|
|
|
|
|
relations.callGraph.set(componentName, calls) |
|
|
}) |
|
|
|
|
|
return relations |
|
|
}, |
|
|
|
|
|
// 生成真实的路由映射 |
|
|
generateRealRouteMappings(callRelations) { |
|
|
const mappings = { |
|
|
mainRoutes: [], |
|
|
moduleApiMappings: {}, |
|
|
subRouteMappings: {}, |
|
|
callRelations: callRelations |
|
|
} |
|
|
|
|
|
// 生成主路由 |
|
|
callRelations.routes.forEach(route => { |
|
|
mappings.mainRoutes.push({ |
|
|
path: route.path, |
|
|
name: route.name, |
|
|
module: route.module, |
|
|
description: this.generateDescription(route.name, route.module), |
|
|
type: this.determineRouteType(route.path, route.module), |
|
|
component: route.component |
|
|
}) |
|
|
}) |
|
|
|
|
|
// 生成API映射 |
|
|
callRelations.services.forEach((serviceAnalysis, serviceName) => { |
|
|
const moduleName = this.extractModuleFromService(serviceName) |
|
|
if (moduleName && serviceAnalysis.apiCalls.length > 0) { |
|
|
const apiMapping = this.buildApiMappingFromRealCalls(serviceAnalysis.apiCalls, moduleName) |
|
|
mappings.moduleApiMappings[moduleName] = apiMapping |
|
|
} |
|
|
}) |
|
|
|
|
|
// 生成子路由映射 |
|
|
mappings.subRouteMappings = this.generateSubRouteMappingsFromRelations(callRelations) |
|
|
|
|
|
return mappings |
|
|
}, |
|
|
|
|
|
// 从真实调用构建API映射 |
|
|
buildApiMappingFromRealCalls(apiCalls, moduleName) { |
|
|
const operations = {} |
|
|
const paths = [] |
|
|
|
|
|
apiCalls.forEach(call => { |
|
|
const operation = this.inferOperationFromApiCall(call.path, call.method) |
|
|
if (operation) { |
|
|
operations[operation] = { |
|
|
path: call.path, |
|
|
method: call.method |
|
|
} |
|
|
paths.push(call.path) |
|
|
} |
|
|
}) |
|
|
|
|
|
const basePath = this.extractBasePath(paths) |
|
|
|
|
|
return { |
|
|
basePath: basePath, |
|
|
operations: operations |
|
|
} |
|
|
}, |
|
|
|
|
|
// 从API调用推断操作 |
|
|
inferOperationFromApiCall(path, method) { |
|
|
const pathLower = path.toLowerCase() |
|
|
|
|
|
// 根据路径模式推断操作 |
|
|
if (path.includes('/:id') || path.includes('/{id}')) { |
|
|
if (method === 'GET') return 'detail' |
|
|
if (method === 'PUT') return 'update' |
|
|
if (method === 'DELETE') return 'delete' |
|
|
} |
|
|
|
|
|
if (path.includes('/search')) return 'search' |
|
|
if (path.includes('/filter')) return 'filter' |
|
|
if (path.includes('/roles')) return 'getRoles' |
|
|
if (path.includes('/permissions')) return 'getPermissions' |
|
|
if (path.includes('/assign')) return 'assignRoles' |
|
|
if (path.includes('/remove')) return 'removeRoles' |
|
|
|
|
|
// 根据HTTP方法推断 |
|
|
if (method === 'GET' && !path.includes('/')) return 'list' |
|
|
if (method === 'POST' && !path.includes('/')) return 'create' |
|
|
if (method === 'PUT' && !path.includes('/')) return 'update' |
|
|
if (method === 'DELETE' && !path.includes('/')) return 'delete' |
|
|
|
|
|
// 默认操作名 |
|
|
return `${method.toLowerCase()}_${path.replace(/[^a-zA-Z0-9]/g, '_')}` |
|
|
}, |
|
|
|
|
|
// 从关系生成子路由映射 |
|
|
generateSubRouteMappingsFromRelations(callRelations) { |
|
|
const subRouteMappings = {} |
|
|
|
|
|
callRelations.callGraph.forEach((calls, componentName) => { |
|
|
calls.forEach(call => { |
|
|
if (call.type === 'service') { |
|
|
const operation = this.inferOperationFromServiceMethod(call.method) |
|
|
if (operation && operation !== 'list') { |
|
|
// 找到对应的主路由 |
|
|
const mainRoute = callRelations.routes.find(route => |
|
|
route.component === componentName || |
|
|
route.name.toLowerCase().includes(componentName.toLowerCase()) |
|
|
) |
|
|
|
|
|
if (mainRoute) { |
|
|
const subPath = `${mainRoute.path}/${operation}` |
|
|
subRouteMappings[subPath] = { |
|
|
mainRoute: mainRoute.path, |
|
|
operation: operation |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
return subRouteMappings |
|
|
}, |
|
|
|
|
|
// 回退到简单分析 |
|
|
fallbackToSimpleAnalysis() { |
|
|
console.log('⚠️ 使用简单分析作为回退...') |
|
|
|
|
|
const mappings = { |
|
|
mainRoutes: [], |
|
|
moduleApiMappings: {}, |
|
|
subRouteMappings: {}, |
|
|
method: 'simple-analysis' |
|
|
} |
|
|
|
|
|
// 简单的路由提取 |
|
|
const routerPath = resolve(__dirname, '../src/renderer/router/index.js') |
|
|
if (fs.existsSync(routerPath)) { |
|
|
const content = fs.readFileSync(routerPath, 'utf-8') |
|
|
mappings.mainRoutes = this.simpleRouteExtraction(content) |
|
|
} |
|
|
|
|
|
this.generateRouteMappingFile(mappings) |
|
|
console.log('✅ 简单分析完成') |
|
|
}, |
|
|
|
|
|
// 简单的路由提取 |
|
|
simpleRouteExtraction(content) { |
|
|
const routes = [] |
|
|
const routeRegex = /path:\s*['"`]([^'"`]+)['"`]/g |
|
|
const nameRegex = /name:\s*['"`]([^'"`]+)['"`]/g |
|
|
|
|
|
let match |
|
|
while ((match = routeRegex.exec(content)) !== null) { |
|
|
const path = match[1] |
|
|
const nameMatch = nameRegex.exec(content) |
|
|
const name = nameMatch ? nameMatch[1] : path.split('/').pop() |
|
|
|
|
|
routes.push({ |
|
|
path, |
|
|
name, |
|
|
module: this.extractModuleFromPath(path), |
|
|
description: this.generateDescription(name, this.extractModuleFromPath(path)), |
|
|
type: this.determineRouteType(path, this.extractModuleFromPath(path)) |
|
|
}) |
|
|
} |
|
|
|
|
|
return routes |
|
|
}, |
|
|
|
|
|
// 查找组件文件 |
|
|
findComponentFiles() { |
|
|
const componentFiles = [] |
|
|
const moduleDirs = ['user-management', 'role-management', 'system-settings'] |
|
|
|
|
|
moduleDirs.forEach(moduleName => { |
|
|
const viewsPath = resolve(__dirname, `../src/renderer/modules/${moduleName}/views`) |
|
|
const componentsPath = resolve(__dirname, `../src/renderer/modules/${moduleName}/components`) |
|
|
|
|
|
if (fs.existsSync(viewsPath)) { |
|
|
const files = fs.readdirSync(viewsPath).filter(f => f.endsWith('.vue')) |
|
|
files.forEach(file => { |
|
|
componentFiles.push({ |
|
|
name: file.replace('.vue', ''), |
|
|
path: resolve(viewsPath, file), |
|
|
module: moduleName, |
|
|
type: 'view' |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
if (fs.existsSync(componentsPath)) { |
|
|
const files = fs.readdirSync(componentsPath).filter(f => f.endsWith('.vue')) |
|
|
files.forEach(file => { |
|
|
componentFiles.push({ |
|
|
name: file.replace('.vue', ''), |
|
|
path: resolve(componentsPath, file), |
|
|
module: moduleName, |
|
|
type: 'component' |
|
|
}) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
return componentFiles |
|
|
}, |
|
|
|
|
|
// 查找服务文件 |
|
|
findServiceFiles() { |
|
|
const serviceFiles = [] |
|
|
const moduleDirs = ['user-management', 'role-management', 'system-settings'] |
|
|
|
|
|
moduleDirs.forEach(moduleName => { |
|
|
const servicesPath = resolve(__dirname, `../src/renderer/modules/${moduleName}/services`) |
|
|
if (fs.existsSync(servicesPath)) { |
|
|
const files = fs.readdirSync(servicesPath).filter(f => f.endsWith('.js')) |
|
|
files.forEach(file => { |
|
|
serviceFiles.push({ |
|
|
name: file.replace('.js', ''), |
|
|
path: resolve(servicesPath, file), |
|
|
module: moduleName |
|
|
}) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
return serviceFiles |
|
|
}, |
|
|
|
|
|
// 提取组件名称 |
|
|
extractComponentName(node) { |
|
|
if (node.type === 'Identifier') { |
|
|
return node.name |
|
|
} else if (node.type === 'StringLiteral') { |
|
|
return node.value |
|
|
} |
|
|
return null |
|
|
}, |
|
|
|
|
|
// 提取参数值 |
|
|
extractArgumentValue(node) { |
|
|
if (node.type === 'StringLiteral') { |
|
|
return node.value |
|
|
} else if (node.type === 'NumericLiteral') { |
|
|
return node.value |
|
|
} else if (node.type === 'Identifier') { |
|
|
return node.name |
|
|
} |
|
|
return null |
|
|
}, |
|
|
|
|
|
// 从服务方法推断操作 |
|
|
inferOperationFromServiceMethod(methodName) { |
|
|
const methodMap = { |
|
|
'getUsers': 'list', |
|
|
'getUser': 'detail', |
|
|
'createUser': 'create', |
|
|
'updateUser': 'update', |
|
|
'deleteUser': 'delete', |
|
|
'getRoles': 'getRoles', |
|
|
'getRole': 'detail', |
|
|
'createRole': 'create', |
|
|
'updateRole': 'update', |
|
|
'deleteRole': 'delete', |
|
|
'getPermissions': 'getPermissions' |
|
|
} |
|
|
|
|
|
return methodMap[methodName] || methodName |
|
|
}, |
|
|
|
|
|
// 从服务名提取模块名 |
|
|
extractModuleFromService(serviceName) { |
|
|
const serviceMap = { |
|
|
'userService': 'user-management', |
|
|
'roleService': 'role-management', |
|
|
'settingsService': 'system-settings' |
|
|
} |
|
|
|
|
|
return serviceMap[serviceName] || null |
|
|
}, |
|
|
|
|
|
// 提取basePath |
|
|
extractBasePath(paths) { |
|
|
if (paths.length === 0) return '' |
|
|
|
|
|
// 找到所有路径的共同前缀 |
|
|
const firstPath = paths[0] |
|
|
let commonPrefix = '' |
|
|
|
|
|
for (let i = 0; i < firstPath.length; i++) { |
|
|
const char = firstPath[i] |
|
|
if (paths.every(path => path[i] === char)) { |
|
|
commonPrefix += char |
|
|
} else { |
|
|
break |
|
|
} |
|
|
} |
|
|
|
|
|
// 如果找到了完整的前缀,返回它 |
|
|
if (commonPrefix && !commonPrefix.endsWith('/')) { |
|
|
// 找到最后一个斜杠的位置 |
|
|
const lastSlashIndex = commonPrefix.lastIndexOf('/') |
|
|
if (lastSlashIndex > 0) { |
|
|
return commonPrefix.substring(0, lastSlashIndex + 1) |
|
|
} |
|
|
} |
|
|
|
|
|
return commonPrefix |
|
|
}, |
|
|
|
|
|
// 从路径提取模块名 |
|
|
extractModuleFromPath(path) { |
|
|
if (path === '/' || path === '') return 'home' |
|
|
|
|
|
const segments = path.split('/').filter(Boolean) |
|
|
if (segments.length === 0) return 'home' |
|
|
|
|
|
// 获取第一个段作为模块名 |
|
|
const module = segments[0] |
|
|
|
|
|
// 映射模块名 |
|
|
const moduleMap = { |
|
|
'user-management': 'user-management', |
|
|
'role-management': 'role-management', |
|
|
'settings': 'system-settings', |
|
|
'user-profile': 'user-management', |
|
|
'route-sync-test': 'route-sync' |
|
|
} |
|
|
|
|
|
return moduleMap[module] || module |
|
|
}, |
|
|
|
|
|
// 生成路由描述 |
|
|
generateDescription(name, module) { |
|
|
const descriptions = { |
|
|
'home': '首页', |
|
|
'user-management': '用户管理', |
|
|
'role-management': '角色管理', |
|
|
'system-settings': '系统设置', |
|
|
'route-sync': '路由同步测试' |
|
|
} |
|
|
|
|
|
return descriptions[module] || `${name}页面` |
|
|
}, |
|
|
|
|
|
// 确定路由类型 |
|
|
determineRouteType(path, module) { |
|
|
if (path === '/' || path === '') return 'home' |
|
|
|
|
|
// 根据模块确定类型 |
|
|
const typeMap = { |
|
|
'user-management': 'list', |
|
|
'role-management': 'list', |
|
|
'system-settings': 'form', |
|
|
'route-sync': 'test' |
|
|
} |
|
|
|
|
|
return typeMap[module] || 'list' |
|
|
}, |
|
|
|
|
|
// 生成路由映射文件 |
|
|
generateRouteMappingFile(routeMappings) { |
|
|
const mappingContent = `// 自动生成的路由映射文件 |
|
|
// 此文件由 route-mapping-plugin 在构建时生成 |
|
|
// 基于AST解析和Vite编译时关系分析 |
|
|
// 请勿手动修改 |
|
|
|
|
|
export const mainRoutes = ${JSON.stringify(routeMappings.mainRoutes, null, 2)} |
|
|
|
|
|
// 模块到API映射配置(从AST解析提取) |
|
|
export const moduleApiMappings = ${JSON.stringify(routeMappings.moduleApiMappings, null, 2)} |
|
|
|
|
|
// 子路由到主路由的映射(从调用关系提取) |
|
|
export const subRouteMappings = ${JSON.stringify(routeMappings.subRouteMappings, null, 2)} |
|
|
|
|
|
// 分析方法和结果 |
|
|
export const analysisInfo = ${JSON.stringify({ |
|
|
method: routeMappings.method || 'ast-analysis', |
|
|
timestamp: new Date().toISOString(), |
|
|
hasCallRelations: !!routeMappings.callRelations, |
|
|
componentCount: routeMappings.callRelations?.components?.size || 0, |
|
|
serviceCount: routeMappings.callRelations?.services?.size || 0 |
|
|
}, null, 2)} |
|
|
|
|
|
export default { |
|
|
mainRoutes, |
|
|
moduleApiMappings, |
|
|
subRouteMappings, |
|
|
analysisInfo |
|
|
} |
|
|
` |
|
|
|
|
|
const outputPath = resolve(__dirname, '../src/renderer/modules/route-sync/generated-route-mapping.js') |
|
|
fs.writeFileSync(outputPath, mappingContent, 'utf-8') |
|
|
|
|
|
console.log(`✅ 基于AST解析的路由映射文件已生成: ${outputPath}`) |
|
|
} |
|
|
} |
|
|
}
|
|
|
|