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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user