Files
wwjcloud/tools/php-file-discovery.js
wanwu b1e16be25d feat: 重构多语言模块,符合NestJS规范
- 重构LanguageUtils为LanguageService,实现ILanguageService接口
- 移除自定义验证管道和装饰器,使用标准NestJS验证
- 集成框架ValidatorService进行业务验证
- 简化目录结构,移除不必要的子目录
- 支持模块化语言包加载(common、user、order等)
- 统一API响应格式(code、msg、data、timestamp)
- 添加ValidationExceptionFilter处理多语言验证错误
- 完善多语言示例和文档
2025-10-06 10:56:59 +08:00

1331 lines
42 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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;