Files
wwjcloud/tools/php-file-discovery.js

1331 lines
42 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* PHP文件发现工具
* 自动发现所有PHP控制器和服务文件建立正确的映射关系
*/
const fs = require('fs');
const path = require('path');
class PHPFileDiscovery {
constructor() {
this.phpBasePath = '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/niucloud-php/niucloud';
this.javaBasePath = '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/niucloud-java/niucloud-core/src/main/java/com/niu/core';
this.discoveredFiles = {
// PHP层级
controllers: {},
services: {},
models: {},
validates: {},
middlewares: {},
routes: {},
jobs: {},
listeners: {},
commands: {},
dicts: {},
traits: {},
// Java层级用于对比
javaControllers: {},
javaEntities: {},
javaServices: {},
javaMappers: {},
javaEnums: {},
javaEvents: {},
javaListeners: {},
javaJobs: {}
};
}
/**
* 发现所有PHP控制器文件
*/
discoverControllers() {
console.log('🔍 发现PHP控制器文件...');
const controllerPaths = [
// adminapi控制器路径
'app/adminapi/controller/sys',
'app/adminapi/controller/member',
'app/adminapi/controller/pay',
'app/adminapi/controller/upload',
'app/adminapi/controller/login',
'app/adminapi/controller/agreement',
'app/adminapi/controller/wechat',
'app/adminapi/controller/weapp',
'app/adminapi/controller/diy',
'app/adminapi/controller/poster',
'app/adminapi/controller/addon',
'app/adminapi/controller/aliapp',
'app/adminapi/controller/auth',
'app/adminapi/controller/generator',
// 新增缺失的adminapi控制器路径
'app/adminapi/controller/applet',
'app/adminapi/controller/channel',
'app/adminapi/controller/dict',
'app/adminapi/controller/home',
'app/adminapi/controller/index',
'app/adminapi/controller/niucloud',
'app/adminapi/controller/notice',
'app/adminapi/controller/site',
'app/adminapi/controller/stat',
'app/adminapi/controller/user',
'app/adminapi/controller/verify',
'app/adminapi/controller/wxoplatform',
// api控制器路径
'app/api/controller/member',
'app/api/controller/pay',
'app/api/controller/upload',
'app/api/controller/login',
'app/api/controller/agreement',
'app/api/controller/wechat',
'app/api/controller/weapp',
'app/api/controller/diy',
'app/api/controller/poster',
'app/api/controller/addon',
'app/api/controller/aliapp',
'app/api/controller/auth',
'app/api/controller/generator'
];
for (const controllerPath of controllerPaths) {
const fullPath = path.join(this.phpBasePath, controllerPath);
if (fs.existsSync(fullPath)) {
const files = fs.readdirSync(fullPath).filter(file => file.endsWith('.php'));
for (const file of files) {
const className = file.replace('.php', '');
const moduleName = this.extractModuleName(controllerPath);
const layer = this.extractLayer(controllerPath);
if (!this.discoveredFiles.controllers[moduleName]) {
this.discoveredFiles.controllers[moduleName] = {};
}
this.discoveredFiles.controllers[moduleName][className] = {
filePath: path.join(fullPath, file),
className: className,
layer: layer,
moduleName: moduleName
};
console.log(` ✅ 发现控制器: ${moduleName}/${className} (${layer})`);
}
}
}
}
/**
* 发现所有PHP服务文件
*/
discoverServices() {
console.log('🔍 发现PHP服务文件...');
const servicePaths = [
// admin服务路径
'app/service/admin/sys',
'app/service/admin/member',
'app/service/admin/pay',
'app/service/admin/upload',
'app/service/admin/login',
'app/service/admin/agreement',
'app/service/admin/wechat',
'app/service/admin/weapp',
'app/service/admin/diy',
'app/service/admin/poster',
'app/service/admin/addon',
'app/service/admin/aliapp',
'app/service/admin/auth',
'app/service/admin/captcha',
'app/service/admin/generator',
// 新增缺失的admin服务路径
'app/service/admin/applet',
'app/service/admin/channel',
'app/service/admin/dict',
'app/service/admin/home',
'app/service/admin/index',
'app/service/admin/niucloud',
'app/service/admin/notice',
'app/service/admin/site',
'app/service/admin/stat',
'app/service/admin/user',
'app/service/admin/verify',
'app/service/admin/upgrade',
'app/service/admin/wxoplatform',
// api服务路径
'app/service/api/member',
'app/service/api/pay',
'app/service/api/upload',
'app/service/api/login',
'app/service/api/agreement',
'app/service/api/wechat',
'app/service/api/weapp',
'app/service/api/diy',
'app/service/api/poster',
'app/service/api/addon',
'app/service/api/aliapp',
'app/service/api/auth',
'app/service/api/captcha',
'app/service/api/generator',
// core服务路径
'app/service/core/sys',
'app/service/core/member',
'app/service/core/pay',
'app/service/core/upload',
'app/service/core/login',
'app/service/core/agreement',
'app/service/core/wechat',
'app/service/core/weapp',
'app/service/core/diy',
'app/service/core/poster',
'app/service/core/addon',
'app/service/core/aliapp',
'app/service/core/auth',
'app/service/core/captcha',
'app/service/core/generator',
// 新增缺失的core服务路径
'app/service/core/applet',
'app/service/core/channel',
'app/service/core/dict',
'app/service/core/home',
'app/service/core/index',
'app/service/core/niucloud',
'app/service/core/notice',
'app/service/core/site',
'app/service/core/stat',
'app/service/core/user',
'app/service/core/verify',
'app/service/core/wxoplatform'
];
for (const servicePath of servicePaths) {
const fullPath = path.join(this.phpBasePath, servicePath);
if (fs.existsSync(fullPath)) {
const files = fs.readdirSync(fullPath).filter(file => file.endsWith('.php'));
for (const file of files) {
const className = file.replace('.php', '');
const moduleName = this.extractModuleName(servicePath);
const layer = this.extractLayer(servicePath);
if (!this.discoveredFiles.services[moduleName]) {
this.discoveredFiles.services[moduleName] = {};
}
// 使用 className + layer 作为唯一键,避免不同层级服务被覆盖
const serviceKey = `${className}_${layer}`;
this.discoveredFiles.services[moduleName][serviceKey] = {
filePath: path.join(fullPath, file),
className: className,
layer: layer,
moduleName: moduleName
};
console.log(` ✅ 发现服务: ${moduleName}/${className} (${layer})`);
}
}
}
}
/**
* 从路径中提取模块名
*/
extractModuleName(filePath) {
const parts = filePath.split('/');
// 对于控制器路径: app/adminapi/controller/member/Member.php
// 模块名是 controller 后面的部分
const controllerIndex = parts.findIndex(part => part === 'controller');
if (controllerIndex > 0 && controllerIndex < parts.length - 1) {
return parts[controllerIndex + 1];
}
// 对于服务路径: app/service/admin/member/MemberService.php
// 模块名是 service 后面第二层跳过层级admin/api/core
const serviceIndex = parts.findIndex(part => part === 'service');
if (serviceIndex > 0 && serviceIndex < parts.length - 2) {
return parts[serviceIndex + 2];
}
return 'unknown';
}
/**
* 从路径中提取层级
*/
extractLayer(filePath) {
if (filePath.includes('/adminapi/')) {
return 'adminapi';
} else if (filePath.includes('/api/')) {
return 'api';
} else if (filePath.includes('/core/')) {
return 'core';
} else if (filePath.includes('/admin/')) {
return 'admin';
}
return 'unknown';
}
/**
* 分析PHP文件内容
*/
analyzePHPFile(filePath) {
try {
const content = fs.readFileSync(filePath, 'utf-8');
const methods = this.extractMethods(content);
return {
filePath: filePath,
methods: methods,
content: content
};
} catch (error) {
console.warn(` ⚠️ 无法读取PHP文件 ${filePath}: ${error.message}`);
return null;
}
}
/**
* 提取PHP方法
*/
extractMethods(content) {
const methods = [];
const methodRegex = /public function (\w+)\([^)]*\)\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/g;
let match;
while ((match = methodRegex.exec(content)) !== null) {
methods.push({
name: match[1],
content: match[2],
parameters: this.extractParameters(match[0])
});
}
return methods;
}
/**
* 提取方法参数
*/
extractParameters(methodSignature) {
const params = [];
const paramRegex = /\$(\w+)/g;
let match;
while ((match = paramRegex.exec(methodSignature)) !== null) {
params.push({
name: match[1],
type: 'any'
});
}
return params;
}
/**
* 生成文件映射报告
*/
generateMappingReport() {
console.log('\n📊 PHP+Java文件映射报告:');
console.log('='.repeat(60));
// 统计PHP总数
let totalPHPControllers = 0;
let totalPHPServices = 0;
let totalPHPModels = 0;
let totalPHPValidates = 0;
let totalPHPMiddlewares = 0;
let totalPHPRoutes = 0;
let totalPHPJobs = 0;
let totalPHPListeners = 0;
let totalPHPCommands = 0;
let totalPHPDicts = 0;
// 统计Java总数
let totalJavaControllers = 0;
let totalJavaEntities = 0;
let totalJavaServices = 0;
let totalJavaMappers = 0;
let totalJavaEnums = 0;
let totalJavaEvents = 0;
let totalJavaListeners = 0;
let totalJavaJobs = 0;
// 计算PHP总数
for (const controllers of Object.values(this.discoveredFiles.controllers)) {
totalPHPControllers += Object.keys(controllers).length;
}
for (const services of Object.values(this.discoveredFiles.services)) {
totalPHPServices += Object.keys(services).length;
}
for (const models of Object.values(this.discoveredFiles.models)) {
totalPHPModels += Object.keys(models).length;
}
for (const validates of Object.values(this.discoveredFiles.validates)) {
totalPHPValidates += Object.keys(validates).length;
}
for (const middlewares of Object.values(this.discoveredFiles.middlewares)) {
totalPHPMiddlewares += Object.keys(middlewares).length;
}
for (const routes of Object.values(this.discoveredFiles.routes)) {
totalPHPRoutes += Object.keys(routes).length;
}
for (const jobs of Object.values(this.discoveredFiles.jobs)) {
totalPHPJobs += Object.keys(jobs).length;
}
for (const listeners of Object.values(this.discoveredFiles.listeners)) {
totalPHPListeners += Object.keys(listeners).length;
}
for (const commands of Object.values(this.discoveredFiles.commands)) {
totalPHPCommands += Object.keys(commands).length;
}
for (const dicts of Object.values(this.discoveredFiles.dicts)) {
totalPHPDicts += Object.keys(dicts).length;
}
// 计算Java总数
for (const controllers of Object.values(this.discoveredFiles.javaControllers)) {
totalJavaControllers += Object.keys(controllers).length;
}
for (const entities of Object.values(this.discoveredFiles.javaEntities)) {
totalJavaEntities += Object.keys(entities).length;
}
for (const services of Object.values(this.discoveredFiles.javaServices)) {
totalJavaServices += Object.keys(services).length;
}
for (const mappers of Object.values(this.discoveredFiles.javaMappers)) {
totalJavaMappers += Object.keys(mappers).length;
}
for (const enums of Object.values(this.discoveredFiles.javaEnums)) {
totalJavaEnums += Object.keys(enums).length;
}
for (const events of Object.values(this.discoveredFiles.javaEvents)) {
totalJavaEvents += Object.keys(events).length;
}
for (const listeners of Object.values(this.discoveredFiles.javaListeners)) {
totalJavaListeners += Object.keys(listeners).length;
}
for (const jobs of Object.values(this.discoveredFiles.javaJobs)) {
totalJavaJobs += Object.keys(jobs).length;
}
const totalPHPFiles = totalPHPControllers + totalPHPServices + totalPHPModels + totalPHPValidates +
totalPHPMiddlewares + totalPHPRoutes + totalPHPJobs + totalPHPListeners +
totalPHPCommands + totalPHPDicts;
const totalJavaFiles = totalJavaControllers + totalJavaEntities + totalJavaServices + totalJavaMappers +
totalJavaEnums + totalJavaEvents + totalJavaListeners + totalJavaJobs;
console.log(`\n📈 PHP项目统计:`);
console.log(` 控制器: ${totalPHPControllers}`);
console.log(` 服务: ${totalPHPServices}`);
console.log(` 模型: ${totalPHPModels}`);
console.log(` 验证器: ${totalPHPValidates}`);
console.log(` 中间件: ${totalPHPMiddlewares}`);
console.log(` 路由: ${totalPHPRoutes}`);
console.log(` 任务: ${totalPHPJobs}`);
console.log(` 监听器: ${totalPHPListeners}`);
console.log(` 命令: ${totalPHPCommands}`);
console.log(` 字典: ${totalPHPDicts}`);
console.log(` PHP总计: ${totalPHPFiles} 个文件`);
console.log(`\n📈 Java项目统计:`);
console.log(` 控制器: ${totalJavaControllers}`);
console.log(` 实体: ${totalJavaEntities}`);
console.log(` 服务: ${totalJavaServices}`);
console.log(` 映射器: ${totalJavaMappers}`);
console.log(` 枚举: ${totalJavaEnums}`);
console.log(` 事件: ${totalJavaEvents}`);
console.log(` 监听器: ${totalJavaListeners}`);
console.log(` 任务: ${totalJavaJobs}`);
console.log(` Java总计: ${totalJavaFiles} 个文件`);
console.log(`\n📈 项目对比:`);
console.log(` PHP总文件数: ${totalPHPFiles}`);
console.log(` Java总文件数: ${totalJavaFiles}`);
console.log(` 差异: ${Math.abs(totalPHPFiles - totalJavaFiles)} 个文件`);
// 按模块显示详细信息
const allModules = new Set();
Object.keys(this.discoveredFiles.controllers).forEach(m => allModules.add(m));
Object.keys(this.discoveredFiles.services).forEach(m => allModules.add(m));
Object.keys(this.discoveredFiles.models).forEach(m => allModules.add(m));
Object.keys(this.discoveredFiles.validates).forEach(m => allModules.add(m));
Object.keys(this.discoveredFiles.jobs).forEach(m => allModules.add(m));
Object.keys(this.discoveredFiles.listeners).forEach(m => allModules.add(m));
Object.keys(this.discoveredFiles.commands).forEach(m => allModules.add(m));
Object.keys(this.discoveredFiles.dicts).forEach(m => allModules.add(m));
for (const moduleName of allModules) {
console.log(`\n📁 模块: ${moduleName}`);
if (this.discoveredFiles.controllers[moduleName]) {
console.log(' 控制器:');
for (const [controllerName, info] of Object.entries(this.discoveredFiles.controllers[moduleName])) {
console.log(` - ${controllerName} (${info.layer})`);
}
}
if (this.discoveredFiles.services[moduleName]) {
console.log(' 服务:');
for (const [serviceName, info] of Object.entries(this.discoveredFiles.services[moduleName])) {
console.log(` - ${serviceName} (${info.layer})`);
}
}
if (this.discoveredFiles.models[moduleName]) {
console.log(' 模型:');
for (const [modelName, info] of Object.entries(this.discoveredFiles.models[moduleName])) {
console.log(` - ${modelName}`);
}
}
if (this.discoveredFiles.validates[moduleName]) {
console.log(' 验证器:');
for (const [validateName, info] of Object.entries(this.discoveredFiles.validates[moduleName])) {
console.log(` - ${validateName}`);
}
}
if (this.discoveredFiles.jobs[moduleName]) {
console.log(' 任务:');
for (const [jobName, info] of Object.entries(this.discoveredFiles.jobs[moduleName])) {
console.log(` - ${jobName}`);
}
}
if (this.discoveredFiles.listeners[moduleName]) {
console.log(' 监听器:');
for (const [listenerName, info] of Object.entries(this.discoveredFiles.listeners[moduleName])) {
console.log(` - ${listenerName}`);
}
}
if (this.discoveredFiles.commands[moduleName]) {
console.log(' 命令:');
for (const [commandName, info] of Object.entries(this.discoveredFiles.commands[moduleName])) {
console.log(` - ${commandName}`);
}
}
if (this.discoveredFiles.dicts[moduleName]) {
console.log(' 字典:');
for (const [dictName, info] of Object.entries(this.discoveredFiles.dicts[moduleName])) {
console.log(` - ${dictName}`);
}
}
}
// 显示中间件和路由
if (Object.keys(this.discoveredFiles.middlewares).length > 0) {
console.log(`\n📁 中间件:`);
for (const [layer, middlewares] of Object.entries(this.discoveredFiles.middlewares)) {
console.log(` ${layer}:`);
for (const [middlewareName, info] of Object.entries(middlewares)) {
console.log(` - ${middlewareName}`);
}
}
}
if (Object.keys(this.discoveredFiles.routes).length > 0) {
console.log(`\n📁 路由:`);
for (const [layer, routes] of Object.entries(this.discoveredFiles.routes)) {
console.log(` ${layer}:`);
for (const [routeName, info] of Object.entries(routes)) {
console.log(` - ${routeName}`);
}
}
}
}
/**
* 保存发现结果到文件
*/
saveDiscoveryResult() {
const resultPath = path.join(__dirname, 'php-discovery-result.json');
fs.writeFileSync(resultPath, JSON.stringify(this.discoveredFiles, null, 2));
console.log(`\n💾 发现结果已保存到: ${resultPath}`);
}
/**
* 发现所有PHP模型文件
*/
discoverModels() {
console.log('🔍 发现PHP模型文件...');
const modelPath = path.join(this.phpBasePath, 'app/model');
if (fs.existsSync(modelPath)) {
const modules = fs.readdirSync(modelPath);
for (const module of modules) {
const modulePath = path.join(modelPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.php'));
if (!this.discoveredFiles.models[module]) {
this.discoveredFiles.models[module] = {};
}
for (const file of files) {
const className = file.replace('.php', '');
this.discoveredFiles.models[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现模型: ${module}/${className}`);
}
}
}
}
}
/**
* 发现所有PHP验证器文件
*/
discoverValidates() {
console.log('🔍 发现PHP验证器文件...');
// 发现 app/validate 目录下的验证器文件
const validatePath = path.join(this.phpBasePath, 'app/validate');
if (fs.existsSync(validatePath)) {
const modules = fs.readdirSync(validatePath);
for (const module of modules) {
const modulePath = path.join(validatePath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.php'));
if (!this.discoveredFiles.validates[module]) {
this.discoveredFiles.validates[module] = {};
}
for (const file of files) {
const className = file.replace('.php', '');
this.discoveredFiles.validates[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现验证器: ${module}/${className}`);
}
}
}
}
// 发现 app/lang 目录下的验证器文件
const langPath = path.join(this.phpBasePath, 'app/lang');
if (fs.existsSync(langPath)) {
const languages = fs.readdirSync(langPath);
for (const lang of languages) {
const langPath = path.join(this.phpBasePath, 'app/lang', lang);
if (fs.statSync(langPath).isDirectory()) {
const validateFile = path.join(langPath, 'validate.php');
if (fs.existsSync(validateFile)) {
if (!this.discoveredFiles.validates['lang']) {
this.discoveredFiles.validates['lang'] = {};
}
this.discoveredFiles.validates['lang'][`${lang}Validate`] = {
filePath: validateFile,
className: `${lang}Validate`,
moduleName: 'lang'
};
console.log(` ✅ 发现语言验证器: lang/${lang}Validate`);
}
}
}
}
}
/**
* 发现所有PHP中间件文件
*/
discoverMiddlewares() {
console.log('🔍 发现PHP中间件文件...');
const middlewarePaths = [
'app/adminapi/middleware',
'app/api/middleware'
];
for (const middlewarePath of middlewarePaths) {
const fullPath = path.join(this.phpBasePath, middlewarePath);
if (fs.existsSync(fullPath)) {
const files = fs.readdirSync(fullPath).filter(file => file.endsWith('.php'));
const layer = middlewarePath.includes('adminapi') ? 'adminapi' : 'api';
if (!this.discoveredFiles.middlewares[layer]) {
this.discoveredFiles.middlewares[layer] = {};
}
for (const file of files) {
const className = file.replace('.php', '');
this.discoveredFiles.middlewares[layer][className] = {
filePath: path.join(fullPath, file),
className: className,
layer: layer
};
console.log(` ✅ 发现中间件: ${layer}/${className}`);
}
}
}
}
/**
* 发现所有PHP路由文件
*/
discoverRoutes() {
console.log('🔍 发现PHP路由文件...');
const routePaths = [
'app/adminapi/route',
'app/api/route'
];
for (const routePath of routePaths) {
const fullPath = path.join(this.phpBasePath, routePath);
if (fs.existsSync(fullPath)) {
const files = fs.readdirSync(fullPath).filter(file => file.endsWith('.php'));
const layer = routePath.includes('adminapi') ? 'adminapi' : 'api';
if (!this.discoveredFiles.routes[layer]) {
this.discoveredFiles.routes[layer] = {};
}
for (const file of files) {
const className = file.replace('.php', '');
this.discoveredFiles.routes[layer][className] = {
filePath: path.join(fullPath, file),
className: className,
layer: layer
};
console.log(` ✅ 发现路由: ${layer}/${className}`);
}
}
}
}
/**
* 发现所有PHP任务文件
*/
discoverJobs() {
console.log('🔍 发现PHP任务文件...');
const jobPath = path.join(this.phpBasePath, 'app/job');
if (fs.existsSync(jobPath)) {
const modules = fs.readdirSync(jobPath);
for (const module of modules) {
const modulePath = path.join(jobPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.php'));
if (!this.discoveredFiles.jobs[module]) {
this.discoveredFiles.jobs[module] = {};
}
for (const file of files) {
const className = file.replace('.php', '');
this.discoveredFiles.jobs[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现任务: ${module}/${className}`);
}
}
}
}
}
/**
* 发现所有PHP监听器文件
*/
discoverListeners() {
console.log('🔍 发现PHP监听器文件...');
const listenerPath = path.join(this.phpBasePath, 'app/listener');
if (fs.existsSync(listenerPath)) {
const modules = fs.readdirSync(listenerPath);
for (const module of modules) {
const modulePath = path.join(listenerPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.php'));
if (!this.discoveredFiles.listeners[module]) {
this.discoveredFiles.listeners[module] = {};
}
for (const file of files) {
const className = file.replace('.php', '');
this.discoveredFiles.listeners[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现监听器: ${module}/${className}`);
}
}
}
}
}
/**
* 发现所有PHP命令文件
*/
discoverCommands() {
console.log('🔍 发现PHP命令文件...');
const commandPath = path.join(this.phpBasePath, 'app/command');
if (fs.existsSync(commandPath)) {
const modules = fs.readdirSync(commandPath);
for (const module of modules) {
const modulePath = path.join(commandPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.php'));
if (!this.discoveredFiles.commands[module]) {
this.discoveredFiles.commands[module] = {};
}
for (const file of files) {
const className = file.replace('.php', '');
this.discoveredFiles.commands[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现命令: ${module}/${className}`);
}
}
}
}
}
/**
* 发现所有PHP字典文件
*/
discoverDicts() {
console.log('🔍 发现PHP字典文件...');
// 发现 app/dict 目录下的字典文件
const dictPath = path.join(this.phpBasePath, 'app/dict');
if (fs.existsSync(dictPath)) {
const modules = fs.readdirSync(dictPath);
for (const module of modules) {
const modulePath = path.join(dictPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.php'));
if (!this.discoveredFiles.dicts[module]) {
this.discoveredFiles.dicts[module] = {};
}
for (const file of files) {
const className = file.replace('.php', '');
this.discoveredFiles.dicts[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现字典: ${module}/${className}`);
}
}
}
}
// 发现其他位置的字典文件
const otherDictPaths = [
'app/adminapi/controller/dict',
'app/model/dict',
'app/service/admin/dict'
];
for (const dictPath of otherDictPaths) {
const fullPath = path.join(this.phpBasePath, dictPath);
if (fs.existsSync(fullPath)) {
const files = fs.readdirSync(fullPath).filter(file => file.endsWith('.php'));
for (const file of files) {
const className = file.replace('.php', '');
const moduleName = 'dict'; // 统一归类到dict模块
if (!this.discoveredFiles.dicts[moduleName]) {
this.discoveredFiles.dicts[moduleName] = {};
}
this.discoveredFiles.dicts[moduleName][className] = {
filePath: path.join(fullPath, file),
className: className,
moduleName: moduleName
};
console.log(` ✅ 发现其他字典: ${moduleName}/${className}`);
}
}
}
// 发现 app/lang 目录下的字典文件
const langPath = path.join(this.phpBasePath, 'app/lang');
if (fs.existsSync(langPath)) {
const languages = fs.readdirSync(langPath);
for (const lang of languages) {
const langPath = path.join(this.phpBasePath, 'app/lang', lang);
if (fs.statSync(langPath).isDirectory()) {
const dictFile = path.join(langPath, 'dict.php');
if (fs.existsSync(dictFile)) {
if (!this.discoveredFiles.dicts['lang']) {
this.discoveredFiles.dicts['lang'] = {};
}
this.discoveredFiles.dicts['lang'][`${lang}Dict`] = {
filePath: dictFile,
className: `${lang}Dict`,
moduleName: 'lang'
};
console.log(` ✅ 发现语言字典: lang/${lang}Dict`);
}
}
}
}
}
/**
* 发现所有PHP Trait文件
*/
discoverTraits() {
console.log('🔍 发现PHP Trait文件...');
// 搜索所有PHP文件中的trait定义
const searchPaths = [
'app/service',
'app/model',
'app/controller'
];
for (const searchPath of searchPaths) {
const fullPath = path.join(this.phpBasePath, searchPath);
if (fs.existsSync(fullPath)) {
this.searchTraitsInDirectory(fullPath, searchPath);
}
}
}
/**
* 在目录中搜索Trait文件
*/
searchTraitsInDirectory(dirPath, relativePath) {
const files = fs.readdirSync(dirPath);
for (const file of files) {
const filePath = path.join(dirPath, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
this.searchTraitsInDirectory(filePath, path.join(relativePath, file));
} else if (file.endsWith('.php')) {
this.extractTraitsFromFile(filePath, relativePath);
}
}
}
/**
* 从PHP文件中提取Trait定义
*/
extractTraitsFromFile(filePath, relativePath) {
try {
const content = fs.readFileSync(filePath, 'utf-8');
// 匹配trait定义
const traitRegex = /trait\s+(\w+)\s*\{/g;
let match;
while ((match = traitRegex.exec(content)) !== null) {
const traitName = match[1];
const moduleName = this.extractModuleNameFromPath(relativePath);
if (!this.discoveredFiles.traits[moduleName]) {
this.discoveredFiles.traits[moduleName] = {};
}
this.discoveredFiles.traits[moduleName][traitName] = {
filePath: filePath,
className: traitName,
moduleName: moduleName
};
console.log(` ✅ 发现Trait: ${moduleName}/${traitName}`);
}
} catch (error) {
console.log(` ⚠️ 读取文件失败: ${filePath}`);
}
}
/**
* 从路径中提取模块名
*/
extractModuleNameFromPath(relativePath) {
const parts = relativePath.split(path.sep);
// 跳过 'app' 和 'service'/'model'/'controller' 部分
if (parts.length > 2) {
return parts[2];
}
return 'common';
}
/**
* 发现Java控制器文件
*/
discoverJavaControllers() {
console.log('🔍 发现Java控制器文件...');
const controllerPaths = [
'controller/adminapi',
'controller/api',
'controller/core'
];
for (const controllerPath of controllerPaths) {
const fullPath = path.join(this.javaBasePath, controllerPath);
if (fs.existsSync(fullPath)) {
const modules = fs.readdirSync(fullPath);
const layer = controllerPath.includes('adminapi') ? 'adminapi' :
controllerPath.includes('api') ? 'api' : 'core';
for (const module of modules) {
const modulePath = path.join(fullPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.java'));
if (!this.discoveredFiles.javaControllers[module]) {
this.discoveredFiles.javaControllers[module] = {};
}
for (const file of files) {
const className = file.replace('.java', '');
this.discoveredFiles.javaControllers[module][className] = {
filePath: path.join(modulePath, file),
className: className,
layer: layer,
moduleName: module
};
console.log(` ✅ 发现Java控制器: ${module}/${className} (${layer})`);
}
}
}
}
}
}
/**
* 发现Java实体文件
*/
discoverJavaEntities() {
console.log('🔍 发现Java实体文件...');
const entityPath = path.join(this.javaBasePath, 'entity');
if (fs.existsSync(entityPath)) {
const modules = fs.readdirSync(entityPath);
for (const module of modules) {
const modulePath = path.join(entityPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.java'));
if (!this.discoveredFiles.javaEntities[module]) {
this.discoveredFiles.javaEntities[module] = {};
}
for (const file of files) {
const className = file.replace('.java', '');
this.discoveredFiles.javaEntities[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现Java实体: ${module}/${className}`);
}
}
}
}
}
/**
* 发现Java服务文件
*/
discoverJavaServices() {
console.log('🔍 发现Java服务文件...');
const servicePaths = [
'service/admin',
'service/api',
'service/core'
];
for (const servicePath of servicePaths) {
const fullPath = path.join(this.javaBasePath, servicePath);
if (fs.existsSync(fullPath)) {
const modules = fs.readdirSync(fullPath);
const layer = servicePath.includes('admin') ? 'admin' :
servicePath.includes('api') ? 'api' : 'core';
for (const module of modules) {
const modulePath = path.join(fullPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.java'));
if (!this.discoveredFiles.javaServices[module]) {
this.discoveredFiles.javaServices[module] = {};
}
for (const file of files) {
const className = file.replace('.java', '');
this.discoveredFiles.javaServices[module][className] = {
filePath: path.join(modulePath, file),
className: className,
layer: layer,
moduleName: module
};
console.log(` ✅ 发现Java服务: ${module}/${className} (${layer})`);
}
}
}
}
}
}
/**
* 发现Java映射器文件
*/
discoverJavaMappers() {
console.log('🔍 发现Java映射器文件...');
const mapperPath = path.join(this.javaBasePath, 'mapper');
if (fs.existsSync(mapperPath)) {
const modules = fs.readdirSync(mapperPath);
for (const module of modules) {
const modulePath = path.join(mapperPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.java'));
if (!this.discoveredFiles.javaMappers[module]) {
this.discoveredFiles.javaMappers[module] = {};
}
for (const file of files) {
const className = file.replace('.java', '');
this.discoveredFiles.javaMappers[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现Java映射器: ${module}/${className}`);
}
}
}
}
}
/**
* 发现Java枚举文件
*/
discoverJavaEnums() {
console.log('🔍 发现Java枚举文件...');
const enumPath = path.join(this.javaBasePath, 'enums');
if (fs.existsSync(enumPath)) {
const modules = fs.readdirSync(enumPath);
for (const module of modules) {
const modulePath = path.join(enumPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.java'));
if (!this.discoveredFiles.javaEnums[module]) {
this.discoveredFiles.javaEnums[module] = {};
}
for (const file of files) {
const className = file.replace('.java', '');
this.discoveredFiles.javaEnums[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现Java枚举: ${module}/${className}`);
}
}
}
}
}
/**
* 发现Java事件文件
*/
discoverJavaEvents() {
console.log('🔍 发现Java事件文件...');
const eventPath = path.join(this.javaBasePath, 'event');
if (fs.existsSync(eventPath)) {
const modules = fs.readdirSync(eventPath);
for (const module of modules) {
const modulePath = path.join(eventPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.java'));
if (!this.discoveredFiles.javaEvents[module]) {
this.discoveredFiles.javaEvents[module] = {};
}
for (const file of files) {
const className = file.replace('.java', '');
this.discoveredFiles.javaEvents[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现Java事件: ${module}/${className}`);
}
}
}
}
}
/**
* 发现Java监听器文件
*/
discoverJavaListeners() {
console.log('🔍 发现Java监听器文件...');
const listenerPath = path.join(this.javaBasePath, 'listener');
if (fs.existsSync(listenerPath)) {
const modules = fs.readdirSync(listenerPath);
for (const module of modules) {
const modulePath = path.join(listenerPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.java'));
if (!this.discoveredFiles.javaListeners[module]) {
this.discoveredFiles.javaListeners[module] = {};
}
for (const file of files) {
const className = file.replace('.java', '');
this.discoveredFiles.javaListeners[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现Java监听器: ${module}/${className}`);
}
}
}
}
}
/**
* 发现Java任务文件
*/
discoverJavaJobs() {
console.log('🔍 发现Java任务文件...');
const jobPath = path.join(this.javaBasePath, 'job');
if (fs.existsSync(jobPath)) {
const modules = fs.readdirSync(jobPath);
for (const module of modules) {
const modulePath = path.join(jobPath, module);
if (fs.statSync(modulePath).isDirectory()) {
const files = fs.readdirSync(modulePath).filter(file => file.endsWith('.java'));
if (!this.discoveredFiles.javaJobs[module]) {
this.discoveredFiles.javaJobs[module] = {};
}
for (const file of files) {
const className = file.replace('.java', '');
this.discoveredFiles.javaJobs[module][className] = {
filePath: path.join(modulePath, file),
className: className,
moduleName: module
};
console.log(` ✅ 发现Java任务: ${module}/${className}`);
}
}
}
}
}
/**
* 运行发现过程
*/
async run() {
console.log('🚀 启动PHP+Java文件发现工具...');
// 发现PHP文件
console.log('\n📁 发现PHP文件...');
this.discoverControllers();
this.discoverServices();
this.discoverModels();
this.discoverValidates();
this.discoverMiddlewares();
this.discoverRoutes();
this.discoverJobs();
this.discoverListeners();
this.discoverCommands();
this.discoverDicts();
this.discoverTraits();
// 发现Java文件
console.log('\n📁 发现Java文件...');
this.discoverJavaControllers();
this.discoverJavaEntities();
this.discoverJavaServices();
this.discoverJavaMappers();
this.discoverJavaEnums();
this.discoverJavaEvents();
this.discoverJavaListeners();
this.discoverJavaJobs();
this.generateMappingReport();
this.saveDiscoveryResult();
console.log('\n✅ PHP+Java文件发现完成');
return this.discoveredFiles;
}
}
// 如果直接运行此脚本
if (require.main === module) {
const discovery = new PHPFileDiscovery();
discovery.run().catch(console.error);
}
module.exports = PHPFileDiscovery;