feat: 完成PHP到NestJS迁移工具和代码生成

-  成功运行迁移工具,生成28个模块的完整NestJS代码
-  生成所有实体、服务、控制器、验证器等组件
-  修复npm依赖冲突,更新package-lock.json
-  添加Docker测试脚本和配置文件
-  完善迁移工具的调试日志和错误处理
- 🔧 包含增量更新工具和质量检查工具
- 📊 迁移统计:28个模块,数千个文件,耗时26.47秒

主要变更:
- wwjcloud-nest/src/core/* - 生成的业务模块代码
- tools/* - 迁移工具和辅助脚本
- wwjcloud-nest/package.json - 依赖更新
- docker/* - 容器化配置和测试脚本
This commit is contained in:
wanwujie
2025-10-20 18:43:52 +08:00
parent 5fafaa9135
commit c4e588a2fe
565 changed files with 36188 additions and 4897 deletions

View File

@@ -30,16 +30,22 @@ export class LanguageService implements ILanguageService {
* @param language 语言
* @returns 消息内容
*/
async getMessage(key: string, args?: any, module: string = 'common', type: string = 'api', language?: string): Promise<string> {
async getMessage(
key: string,
args?: any,
module: string = 'common',
type: string = 'api',
language?: string,
): Promise<string> {
try {
const currentLanguage = language || this.getCurrentLanguage();
const cacheKey = `${type}.${module}.${key}`;
// 确保模块已加载
await this.ensureModuleLoaded(module, type, currentLanguage);
const message = this.getMessageFromCache(cacheKey, currentLanguage);
if (message && message !== key) {
// 支持参数替换
if (args && typeof args === 'object') {
@@ -47,8 +53,10 @@ export class LanguageService implements ILanguageService {
}
return message;
}
this.logger.warn(`未找到消息: ${key} (模块: ${module}, 类型: ${type}, 语言: ${currentLanguage})`);
this.logger.warn(
`未找到消息: ${key} (模块: ${module}, 类型: ${type}, 语言: ${currentLanguage})`,
);
return key;
} catch (error) {
this.logger.warn(`获取消息失败: ${key}`, error);
@@ -65,7 +73,13 @@ export class LanguageService implements ILanguageService {
* @param language 语言
* @returns 消息内容
*/
async get(key: string, args?: any, module: string = 'common', type: string = 'api', language?: string): Promise<string> {
async get(
key: string,
args?: any,
module: string = 'common',
type: string = 'api',
language?: string,
): Promise<string> {
return await this.getMessage(key, args, module, type, language);
}
@@ -94,11 +108,18 @@ export class LanguageService implements ILanguageService {
* @param type 类型
* @param language 语言
*/
private async ensureModuleLoaded(module: string, type: string, language: string): Promise<void> {
private async ensureModuleLoaded(
module: string,
type: string,
language: string,
): Promise<void> {
const moduleKey = `${module}.${type}`;
const languageKey = `${language}.${moduleKey}`;
if (!this.moduleCache.has(language) || !this.moduleCache.get(language)!.has(moduleKey)) {
if (
!this.moduleCache.has(language) ||
!this.moduleCache.get(language)!.has(moduleKey)
) {
await this.loadModuleLanguagePack(module, type, language);
}
}
@@ -109,55 +130,66 @@ export class LanguageService implements ILanguageService {
* @param type 类型 (api|dict|validate)
* @param language 语言
*/
private async loadModuleLanguagePack(module: string, type: string, language: string): Promise<void> {
private async loadModuleLanguagePack(
module: string,
type: string,
language: string,
): Promise<void> {
try {
const langDir = path.join(process.cwd(), 'src', 'lang', language);
const languagePack = new Map<string, any>();
// 1. 加载通用语言包
if (module !== 'common') {
await this.loadCommonLanguagePack(langDir, type, languagePack);
}
// 2. 加载模块语言包
await this.loadModuleSpecificPack(langDir, module, type, languagePack);
// 3. 加载插件语言包
await this.loadAddonLanguagePacks(langDir, type, languagePack);
// 4. 缓存语言包
if (!this.languageCache.has(language)) {
this.languageCache.set(language, new Map());
}
const languageCache = this.languageCache.get(language)!;
for (const [key, value] of languagePack) {
languageCache.set(key, value);
}
// 5. 记录已加载的模块
if (!this.moduleCache.has(language)) {
this.moduleCache.set(language, new Set());
}
this.moduleCache.get(language)!.add(`${module}.${type}`);
this.logger.log(`模块语言包加载完成: ${module}.${type} (${language})`);
} catch (error) {
this.logger.error(`加载模块语言包失败: ${module}.${type} (${language})`, error);
this.logger.error(
`加载模块语言包失败: ${module}.${type} (${language})`,
error,
);
}
}
/**
* 加载通用语言包
*/
private async loadCommonLanguagePack(langDir: string, type: string, languagePack: Map<string, any>): Promise<void> {
private async loadCommonLanguagePack(
langDir: string,
type: string,
languagePack: Map<string, any>,
): Promise<void> {
const commonDir = path.join(langDir, 'common');
const filePath = path.join(commonDir, `${type}.json`);
try {
const content = await fs.readFile(filePath, 'utf8');
const data = JSON.parse(content);
// 合并到语言包,添加前缀
for (const [key, value] of Object.entries(data)) {
languagePack.set(`${type}.common.${key}`, value);
@@ -170,14 +202,19 @@ export class LanguageService implements ILanguageService {
/**
* 加载模块特定语言包
*/
private async loadModuleSpecificPack(langDir: string, module: string, type: string, languagePack: Map<string, any>): Promise<void> {
private async loadModuleSpecificPack(
langDir: string,
module: string,
type: string,
languagePack: Map<string, any>,
): Promise<void> {
const moduleDir = path.join(langDir, module);
const filePath = path.join(moduleDir, `${type}.json`);
try {
const content = await fs.readFile(filePath, 'utf8');
const data = JSON.parse(content);
// 合并到语言包,添加前缀
for (const [key, value] of Object.entries(data)) {
languagePack.set(`${type}.${module}.${key}`, value);
@@ -190,21 +227,25 @@ export class LanguageService implements ILanguageService {
/**
* 加载插件语言包
*/
private async loadAddonLanguagePacks(langDir: string, type: string, languagePack: Map<string, any>): Promise<void> {
private async loadAddonLanguagePacks(
langDir: string,
type: string,
languagePack: Map<string, any>,
): Promise<void> {
const addonsDir = path.join(langDir, 'addons');
try {
const addonDirs = await fs.readdir(addonsDir);
for (const addonDir of addonDirs) {
const addonPath = path.join(addonsDir, addonDir);
const stat = await fs.stat(addonPath);
if (stat.isDirectory()) {
const filePath = path.join(addonPath, `${type}.json`);
try {
const content = await fs.readFile(filePath, 'utf8');
const data = JSON.parse(content);
// 合并到语言包,添加前缀
for (const [key, value] of Object.entries(data)) {
languagePack.set(`${type}.addon.${addonDir}.${key}`, value);
@@ -222,7 +263,10 @@ export class LanguageService implements ILanguageService {
/**
* 合并语言数据
*/
private mergeLanguageData(target: Map<string, any>, source: Record<string, any>): void {
private mergeLanguageData(
target: Map<string, any>,
source: Record<string, any>,
): void {
for (const [key, value] of Object.entries(source)) {
target.set(key, value);
}
@@ -236,7 +280,7 @@ export class LanguageService implements ILanguageService {
if (languagePack && languagePack.has(key)) {
return languagePack.get(key);
}
return key; // 未找到返回key作为fallback
}
@@ -244,7 +288,10 @@ export class LanguageService implements ILanguageService {
* 替换消息参数
* 对应 Java: MessageFormat.format()
*/
private replaceMessageParams(message: string, args: Record<string, any>): string {
private replaceMessageParams(
message: string,
args: Record<string, any>,
): string {
let result = message;
for (const [key, value] of Object.entries(args)) {
const placeholder = `{${key}}`;
@@ -303,12 +350,12 @@ export class LanguageService implements ILanguageService {
// 清除该语言的所有缓存
this.languageCache.delete(language);
this.moduleCache.delete(language);
// 重新加载通用语言包
await this.loadModuleLanguagePack('common', 'api', language);
await this.loadModuleLanguagePack('common', 'dict', language);
await this.loadModuleLanguagePack('common', 'validate', language);
this.logger.log(`重新加载语言包完成: ${language}`);
} catch (error) {
this.logger.error(`重新加载语言包失败: ${language}`, error);
@@ -336,7 +383,12 @@ export class LanguageService implements ILanguageService {
* @param module 模块名
* @param language 语言
*/
async getApiMessage(key: string, args?: any, module: string = 'common', language?: string): Promise<string> {
async getApiMessage(
key: string,
args?: any,
module: string = 'common',
language?: string,
): Promise<string> {
const currentLanguage = language || this.getCurrentLanguage();
return this.getMessage(key, args, module, 'api', currentLanguage);
}
@@ -348,7 +400,12 @@ export class LanguageService implements ILanguageService {
* @param module 模块名
* @param language 语言
*/
async getDictData(key: string, args?: any, module: string = 'common', language?: string): Promise<string> {
async getDictData(
key: string,
args?: any,
module: string = 'common',
language?: string,
): Promise<string> {
const currentLanguage = language || this.getCurrentLanguage();
return this.getMessage(key, args, module, 'dict', currentLanguage);
}
@@ -360,7 +417,12 @@ export class LanguageService implements ILanguageService {
* @param module 模块名
* @param language 语言
*/
async getValidateMessage(key: string, args?: any, module: string = 'common', language?: string): Promise<string> {
async getValidateMessage(
key: string,
args?: any,
module: string = 'common',
language?: string,
): Promise<string> {
const currentLanguage = language || this.getCurrentLanguage();
return this.getMessage(key, args, module, 'validate', currentLanguage);
}
@@ -372,14 +434,25 @@ export class LanguageService implements ILanguageService {
* @param type 类型
* @param language 语言
*/
async getBatchMessages(keys: string[], module: string = 'common', type: string = 'api', language?: string): Promise<Record<string, string>> {
async getBatchMessages(
keys: string[],
module: string = 'common',
type: string = 'api',
language?: string,
): Promise<Record<string, string>> {
const results: Record<string, string> = {};
const currentLanguage = language || this.getCurrentLanguage();
for (const key of keys) {
results[key] = await this.getMessage(key, undefined, module, type, currentLanguage);
results[key] = await this.getMessage(
key,
undefined,
module,
type,
currentLanguage,
);
}
return results;
}
}