nsgm-cli 2.1.14 → 2.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +49 -26
  2. package/client/components/ClientProviders.tsx +29 -0
  3. package/client/components/LanguageSwitcher.tsx +59 -0
  4. package/client/components/SSRSafeAntdProvider.tsx +24 -0
  5. package/client/components/SuppressHydrationWarnings.tsx +55 -0
  6. package/client/layout/index.tsx +82 -126
  7. package/client/styled/common.ts +0 -1
  8. package/client/styled/layout/index.ts +218 -104
  9. package/client/styled/template/manage.ts +88 -1
  10. package/client/utils/i18n.ts +68 -0
  11. package/client/utils/menu.tsx +42 -36
  12. package/client/utils/navigation.ts +58 -0
  13. package/client/utils/suppressWarnings.ts +32 -0
  14. package/eslint.config.js +17 -20
  15. package/generation/client/redux/reducers.ts +1 -1
  16. package/generation/client/utils/menu.tsx +36 -30
  17. package/generation/env +3 -0
  18. package/generation/next.config.js +7 -3
  19. package/generation/package.json +5 -2
  20. package/generation/tsconfig.json +6 -19
  21. package/lib/cli/commands/create.js +1 -1
  22. package/lib/cli/commands/delete.js +1 -1
  23. package/lib/cli/commands/init.js +6 -6
  24. package/lib/cli/utils/prompt.d.ts +1 -1
  25. package/lib/cli/utils/prompt.js +76 -117
  26. package/lib/constants.d.ts +8 -1
  27. package/lib/constants.js +17 -2
  28. package/lib/generate.js +1 -0
  29. package/lib/generate_create.js +14 -11
  30. package/lib/generate_delete.js +86 -9
  31. package/lib/generate_init.d.ts +6 -0
  32. package/lib/generate_init.js +125 -5
  33. package/lib/generators/file-generator.d.ts +48 -0
  34. package/lib/generators/file-generator.js +455 -0
  35. package/lib/generators/i18n-generator.d.ts +51 -0
  36. package/lib/generators/i18n-generator.js +320 -0
  37. package/lib/generators/page-generator.d.ts +6 -2
  38. package/lib/generators/page-generator.js +182 -156
  39. package/lib/generators/resolver-generator.d.ts +6 -4
  40. package/lib/generators/resolver-generator.js +114 -75
  41. package/lib/generators/service-generator.d.ts +4 -0
  42. package/lib/generators/service-generator.js +120 -6
  43. package/lib/tsconfig.build.tsbuildinfo +1 -1
  44. package/next-i18next.config.js +18 -0
  45. package/next.config.js +55 -16
  46. package/package.json +7 -2
  47. package/pages/_app.tsx +84 -35
  48. package/pages/_document.tsx +39 -2
  49. package/pages/_error.tsx +66 -0
  50. package/pages/index.tsx +46 -29
  51. package/pages/login.tsx +58 -33
  52. package/pages/template/manage.tsx +95 -109
  53. package/public/locales/en-US/common.json +48 -0
  54. package/public/locales/en-US/home.json +57 -0
  55. package/public/locales/en-US/layout.json +22 -0
  56. package/public/locales/en-US/login.json +13 -0
  57. package/public/locales/en-US/template.json +42 -0
  58. package/public/locales/ja-JP/common.json +48 -0
  59. package/public/locales/ja-JP/home.json +57 -0
  60. package/public/locales/ja-JP/layout.json +22 -0
  61. package/public/locales/ja-JP/login.json +13 -0
  62. package/public/locales/ja-JP/template.json +42 -0
  63. package/public/locales/zh-CN/common.json +48 -0
  64. package/public/locales/zh-CN/home.json +57 -0
  65. package/public/locales/zh-CN/layout.json +22 -0
  66. package/public/locales/zh-CN/login.json +13 -0
  67. package/public/locales/zh-CN/template.json +42 -0
  68. package/server/utils/validation.js +163 -0
  69. package/types/i18next.d.ts +10 -0
package/lib/constants.js CHANGED
@@ -36,8 +36,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.destPublicPath = exports.destPagesPath = exports.destServerUtilsPath = exports.destServerSqlPath = exports.destServerApisPath = exports.destServerModulesPath = exports.destServerPath = exports.destClientLayoutPath = exports.destClientUtilsPath = exports.destClientStyledLayoutPath = exports.destClientStyledPath = exports.destClientServicePath = exports.destClientReduxPath = exports.destClientPath = exports.sourceScriptsPath = exports.sourcePublicPath = exports.sourcePagesPath = exports.sourceServerPathGeneration = exports.sourceServerPath = exports.sourceClientPathGeneration = exports.sourceClientPath = exports.sourceGenerationPath = exports.restPath = exports.packagePath = exports.slbHealthCheckPath = exports.reduxReducersPath = exports.utilsMenuPath = exports.sqlPath = exports.apisPath = exports.modulesPath = exports.layoutPath = exports.utilsPath = exports.styledLayoutPath = exports.styledPath = exports.servicePath = exports.reduxPath = exports.scriptsPath = exports.scriptsPathSource = exports.publicPath = exports.publicPathSource = exports.pagesPath = exports.pagesPathSource = exports.serverPath = exports.serverPathSource = exports.clientPath = exports.clientPathSource = exports.generationPath = exports.isLocal = exports.destFolder = exports.sourceFolder = void 0;
40
- exports.mysqlDatabase = exports.mysqlPort = exports.mysqlHost = exports.mysqlPassword = exports.mysqlUser = exports.destServerRestPath = exports.destPackagePath = exports.destPublicHealthCheckPath = exports.destClientReduxReducersAllPath = exports.destClientUtilsMenuPath = exports.destScriptsPath = void 0;
39
+ exports.destServerPath = exports.destClientLayoutPath = exports.destClientUtilsPath = exports.destClientStyledLayoutPath = exports.destClientStyledPath = exports.destClientServicePath = exports.destClientReduxPath = exports.destClientPath = exports.projectPublicPath = exports.projectClientPath = exports.sourceTypesPath = exports.sourceScriptsPath = exports.sourcePublicPath = exports.sourcePagesPath = exports.sourceServerPathGeneration = exports.sourceServerPath = exports.sourceClientPathGeneration = exports.sourceClientPath = exports.sourceGenerationPath = exports.restPath = exports.packagePath = exports.slbHealthCheckPath = exports.reduxReducersPath = exports.utilsMenuPath = exports.sqlPath = exports.apisPath = exports.modulesPath = exports.componentsPath = exports.layoutPath = exports.utilsPath = exports.styledLayoutPath = exports.styledPath = exports.servicePath = exports.reduxPath = exports.typesPath = exports.typesPathSource = exports.scriptsPath = exports.scriptsPathSource = exports.publicPath = exports.publicPathSource = exports.pagesPath = exports.pagesPathSource = exports.serverPath = exports.serverPathSource = exports.clientPath = exports.clientPathSource = exports.generationPath = exports.isLocal = exports.destFolder = exports.sourceFolder = void 0;
40
+ exports.mysqlDatabase = exports.mysqlPort = exports.mysqlHost = exports.mysqlPassword = exports.mysqlUser = exports.destServerRestPath = exports.destPackagePath = exports.destPublicHealthCheckPath = exports.destClientReduxReducersAllPath = exports.destClientUtilsMenuPath = exports.destTypesPath = exports.destScriptsPath = exports.destPublicPath = exports.destPagesPath = exports.destServerUtilsPath = exports.destServerSqlPath = exports.destServerApisPath = exports.destServerModulesPath = void 0;
41
41
  const path_1 = __importStar(require("path"));
42
42
  const db_1 = __importDefault(require("./server/db"));
43
43
  const sourceFolder = __dirname;
@@ -76,6 +76,10 @@ const scriptsPathSource = '../scripts';
76
76
  exports.scriptsPathSource = scriptsPathSource;
77
77
  const scriptsPath = './scripts';
78
78
  exports.scriptsPath = scriptsPath;
79
+ const typesPathSource = '../types';
80
+ exports.typesPathSource = typesPathSource;
81
+ const typesPath = './types';
82
+ exports.typesPath = typesPath;
79
83
  const reduxPath = '/redux';
80
84
  exports.reduxPath = reduxPath;
81
85
  const servicePath = '/service';
@@ -88,6 +92,8 @@ const utilsPath = '/utils';
88
92
  exports.utilsPath = utilsPath;
89
93
  const layoutPath = '/layout';
90
94
  exports.layoutPath = layoutPath;
95
+ const componentsPath = '/components';
96
+ exports.componentsPath = componentsPath;
91
97
  const modulesPath = '/modules';
92
98
  exports.modulesPath = modulesPath;
93
99
  const apisPath = '/apis';
@@ -120,6 +126,13 @@ const sourcePublicPath = path_1.default.join(sourceFolder, publicPathSource);
120
126
  exports.sourcePublicPath = sourcePublicPath;
121
127
  const sourceScriptsPath = path_1.default.join(sourceFolder, scriptsPathSource);
122
128
  exports.sourceScriptsPath = sourceScriptsPath;
129
+ const sourceTypesPath = path_1.default.join(sourceFolder, typesPathSource);
130
+ exports.sourceTypesPath = sourceTypesPath;
131
+ // 当前项目的实际文件路径(用于复制现有文件)
132
+ const projectClientPath = path_1.default.join(destFolder, clientPath);
133
+ exports.projectClientPath = projectClientPath;
134
+ const projectPublicPath = path_1.default.join(destFolder, publicPath);
135
+ exports.projectPublicPath = projectPublicPath;
123
136
  const destClientPath = path_1.default.join(destFolder, clientPath);
124
137
  exports.destClientPath = destClientPath;
125
138
  const destClientReduxPath = (0, path_1.resolve)(destClientPath + reduxPath);
@@ -150,6 +163,8 @@ const destPublicPath = path_1.default.join(destFolder, publicPath);
150
163
  exports.destPublicPath = destPublicPath;
151
164
  const destScriptsPath = path_1.default.join(destFolder, scriptsPath);
152
165
  exports.destScriptsPath = destScriptsPath;
166
+ const destTypesPath = path_1.default.join(destFolder, typesPath);
167
+ exports.destTypesPath = destTypesPath;
153
168
  const destClientUtilsMenuPath = (0, path_1.resolve)(destClientUtilsPath + utilsMenuPath);
154
169
  exports.destClientUtilsMenuPath = destClientUtilsMenuPath;
155
170
  const destClientReduxReducersAllPath = (0, path_1.resolve)(destClientReduxPath + reduxReducersPath);
package/lib/generate.js CHANGED
@@ -73,6 +73,7 @@ const initFiles = (dictionary, upgradeFlag = false, projectConfig) => {
73
73
  (0, generate_init_1.initScriptsFiles)(normalizedDictionary, newDestFolder);
74
74
  const { destPackagePath } = (0, generate_init_1.initRootFiles)(normalizedDictionary, newDestFolder);
75
75
  (0, generate_init_1.initTestFiles)(normalizedDictionary, newDestFolder);
76
+ (0, generate_init_1.initTypesFiles)(normalizedDictionary, newDestFolder);
76
77
  // 如果提供了项目配置,应用到生成的文件中
77
78
  if (projectConfig) {
78
79
  console.log('应用项目配置...');
@@ -47,6 +47,7 @@ const schema_generator_1 = require("./generators/schema-generator");
47
47
  const resolver_generator_1 = require("./generators/resolver-generator");
48
48
  const service_generator_1 = require("./generators/service-generator");
49
49
  const page_generator_1 = require("./generators/page-generator");
50
+ const file_generator_1 = require("./generators/file-generator");
50
51
  // 常量定义
51
52
  const TEMPLATE_FILES = {
52
53
  reduxActions: 'redux/template/manage/actions.ts',
@@ -163,7 +164,7 @@ const performAdvancedReplacements = (controller, action, paths) => {
163
164
  },
164
165
  {
165
166
  from: /Reducer,?\s*\n/,
166
- to: `Reducer,\n ${controller}${(0, utils_1.firstUpperCase)(action)}: ${controller}${(0, utils_1.firstUpperCase)(action)}Reducer\n`,
167
+ to: `Reducer,\n ${controller}${(0, utils_1.firstUpperCase)(action)}: ${controller}${(0, utils_1.firstUpperCase)(action)}Reducer,\n`,
167
168
  files: [paths.destClientReduxReducersAllPath],
168
169
  },
169
170
  {
@@ -199,22 +200,24 @@ const performAdvancedReplacements = (controller, action, paths) => {
199
200
  });
200
201
  }, MYSQL_TIMEOUT);
201
202
  };
202
- /**
203
- * 生成动态文件内容 - 使用专门的生成器
204
- */
205
- const generateDynamicFiles = (controller, _action, paths, fields) => {
203
+ const generateDynamicFiles = (controller, action, paths, fields, dictionary) => {
206
204
  // 创建生成器实例
207
- const sqlGenerator = new sql_generator_1.SQLGenerator(controller, _action, fields);
208
- const schemaGenerator = new schema_generator_1.SchemaGenerator(controller, _action, fields);
209
- const resolverGenerator = new resolver_generator_1.ResolverGenerator(controller, _action, fields);
210
- const serviceGenerator = new service_generator_1.ServiceGenerator(controller, _action, fields);
211
- const pageGenerator = new page_generator_1.PageGenerator(controller, _action, fields);
205
+ const sqlGenerator = new sql_generator_1.SQLGenerator(controller, action, fields);
206
+ const schemaGenerator = new schema_generator_1.SchemaGenerator(controller, action, fields);
207
+ const resolverGenerator = new resolver_generator_1.ResolverGenerator(controller, action, fields);
208
+ const serviceGenerator = new service_generator_1.ServiceGenerator(controller, action, fields);
209
+ const pageGenerator = new page_generator_1.PageGenerator(controller, action, fields);
210
+ // 根据 dictionary 确定文件生成器的项目路径
211
+ const projectPath = !dictionary || dictionary === '.' ? '.' : path_1.default.join(constants_1.destFolder, dictionary);
212
+ const fileGenerator = new file_generator_1.FileGenerator(projectPath);
212
213
  // 生成并写入文件
213
214
  fs_1.default.writeFileSync(paths.destServerSqlController, sqlGenerator.generate());
214
215
  fs_1.default.writeFileSync(paths.destServerModulesSchema, schemaGenerator.generate());
215
216
  fs_1.default.writeFileSync(paths.destServerModulesResolver, resolverGenerator.generate());
216
217
  fs_1.default.writeFileSync(paths.destClientAction, serviceGenerator.generate());
217
218
  fs_1.default.writeFileSync(paths.destPagesAction, pageGenerator.generate());
219
+ // 生成多语言文件
220
+ fileGenerator.generateI18nFiles(controller, action, fields);
218
221
  };
219
222
  /**
220
223
  * 复制并自定义模板文件
@@ -303,7 +306,7 @@ const createFiles = (controller, action, dictionary, fields) => {
303
306
  createDirectoryStructure(basePaths);
304
307
  console.log('Directory structure created');
305
308
  // 4. 生成动态文件内容
306
- generateDynamicFiles(controller, action, paths, finalFields);
309
+ generateDynamicFiles(controller, action, paths, finalFields, dictionary);
307
310
  console.log('Dynamic files generated');
308
311
  // 5. 复制并自定义模板文件
309
312
  copyAndCustomizeTemplateFiles(paths, finalFields);
@@ -25,6 +25,10 @@ const generateDeletePaths = (controller, action, dictionary) => {
25
25
  destClientReduxReducersAllPath: path_1.default.join(basePath, 'client', 'redux', 'reducers.ts'),
26
26
  destClientUtilsMenuPath: path_1.default.join(basePath, 'client', 'utils', 'menu.tsx'),
27
27
  destServerRestPath: path_1.default.join(basePath, 'server', 'rest.js'),
28
+ // 多语言文件路径
29
+ destI18nZhCN: path_1.default.join(basePath, 'public', 'locales', 'zh-CN', `${controller}.json`),
30
+ destI18nEnUS: path_1.default.join(basePath, 'public', 'locales', 'en-US', `${controller}.json`),
31
+ destI18nJaJP: path_1.default.join(basePath, 'public', 'locales', 'ja-JP', `${controller}.json`),
28
32
  ...(action && {
29
33
  destPagesAction: path_1.default.join(basePath, 'pages', controller, `${action}.tsx`),
30
34
  destClientReduxControllerAction: path_1.default.join(basePath, 'client', 'redux', controller, action),
@@ -59,15 +63,38 @@ const deleteSpecificActionFiles = (paths) => {
59
63
  (0, utils_1.rmFileSync)(paths.destClientStyledAction);
60
64
  }
61
65
  };
66
+ const deleteI18nFiles = (paths) => {
67
+ console.log('Deleting i18n files...');
68
+ const i18nFilesToDelete = [paths.destI18nZhCN, paths.destI18nEnUS, paths.destI18nJaJP];
69
+ i18nFilesToDelete.forEach((filePath) => {
70
+ (0, utils_1.rmFileSync)(filePath);
71
+ console.log(`✅ 删除多语言文件: ${filePath}`);
72
+ });
73
+ };
62
74
  const cleanupConfigurationFiles = (controller, action, paths) => {
63
75
  if (action === 'all') {
64
76
  // 清理所有控制器相关的配置
65
- shelljs_1.default.sed('-i', new RegExp(`.*${controller}.*Reducer.*`, 'g'), '', paths.destClientReduxReducersAllPath);
77
+ // 1. 删除 import 语句
78
+ shelljs_1.default.sed('-i', new RegExp(`^.*import.*${controller}.*Reducer.*from.*$`, 'gm'), '', paths.destClientReduxReducersAllPath);
79
+ // 2. 删除 export 对象中的属性行
80
+ shelljs_1.default.sed('-i', new RegExp(`^\\s*${controller}[^:]*:\\s*${controller}.*Reducer,?\\s*$`, 'gm'), '', paths.destClientReduxReducersAllPath);
81
+ // 3. 修复可能出现的语法问题
82
+ // 移除空行
83
+ shelljs_1.default.sed('-i', /^\s*$/g, '', paths.destClientReduxReducersAllPath);
84
+ shelljs_1.default.sed('-i', /\n\n\n/g, '\n\n', paths.destClientReduxReducersAllPath);
85
+ // 4. 修复对象末尾的逗号问题
86
+ // 如果对象只剩一个属性,移除末尾逗号
87
+ shelljs_1.default.sed('-i', /,(\s*\n\s*\})/, '$1', paths.destClientReduxReducersAllPath);
88
+ // 5. 清理服务器端配置
66
89
  shelljs_1.default.sed('-i', new RegExp(`.*${controller}.*`, 'g'), '', paths.destServerRestPath);
67
90
  }
68
91
  else {
69
92
  // 清理特定动作的配置
70
- shelljs_1.default.sed('-i', new RegExp(`.*${controller}${(0, utils_1.firstUpperCase)(action)}Reducer.*`, 'g'), '', paths.destClientReduxReducersAllPath);
93
+ shelljs_1.default.sed('-i', new RegExp(`^.*import.*${controller}${(0, utils_1.firstUpperCase)(action)}Reducer.*from.*$`, 'gm'), '', paths.destClientReduxReducersAllPath);
94
+ shelljs_1.default.sed('-i', new RegExp(`^\\s*${controller}${(0, utils_1.firstUpperCase)(action)}[^:]*:\\s*${controller}${(0, utils_1.firstUpperCase)(action)}.*Reducer,?\\s*$`, 'gm'), '', paths.destClientReduxReducersAllPath);
95
+ // 修复语法问题
96
+ shelljs_1.default.sed('-i', /^\s*$/g, '', paths.destClientReduxReducersAllPath);
97
+ shelljs_1.default.sed('-i', /,(\s*\n\s*\})/, '$1', paths.destClientReduxReducersAllPath);
71
98
  }
72
99
  };
73
100
  const performDatabaseCleanup = (controller, paths) => {
@@ -84,19 +111,23 @@ const performDatabaseCleanup = (controller, paths) => {
84
111
  };
85
112
  const performAdvancedCleanup = (controller, action, paths) => {
86
113
  const cleanupRules = [
114
+ // 标准化空行
87
115
  {
88
- from: /\n\s*\n/,
116
+ from: /\n\s*\n\s*\n/g,
89
117
  to: '\n\n',
90
118
  files: [paths.destClientReduxReducersAllPath],
91
119
  },
120
+ // 修复 reducers.ts 中可能的语法问题
92
121
  {
93
- from: /Reducer,?\s*\n/,
94
- to: 'Reducer\n',
122
+ from: /(\w+Reducer),?\s*\n\s*\}/g,
123
+ to: '$1,\n}',
95
124
  files: [paths.destClientReduxReducersAllPath],
96
125
  },
97
126
  ];
98
127
  if (action === 'all') {
99
- cleanupRules.push({
128
+ cleanupRules.push(
129
+ // 服务器端 REST 文件清理
130
+ {
100
131
  from: /'(.\/apis\/template.*?)'\)\s*\n/,
101
132
  to: "'./apis/template')\n\n",
102
133
  files: [paths.destServerRestPath],
@@ -104,18 +135,62 @@ const performAdvancedCleanup = (controller, action, paths) => {
104
135
  from: /template\)\s*\n/,
105
136
  to: 'template)\n\n',
106
137
  files: [paths.destServerRestPath],
107
- }, {
108
- from: new RegExp(`,?\\s*{\\s*//\\s*${controller}_.*_start[\\s\\S]*?//\\s*${controller}_.*_end\\s*}\\s*,?`, 'gm'),
109
- to: ',',
138
+ },
139
+ // 菜单清理 - 改进版本,保持正确的缩进和逗号
140
+ {
141
+ from: new RegExp(`,?\\s*\\{\\s*//\\s*${controller}_.*_start[\\s\\S]*?//\\s*${controller}_.*_end\\s*\\}\\s*,?`, 'gm'),
142
+ to: ',', // 保留逗号,确保数组语法正确
110
143
  files: [paths.destClientUtilsMenuPath],
111
144
  });
112
145
  }
113
146
  setTimeout(() => {
114
147
  (0, utils_1.replaceInFileAll)(cleanupRules, 0, () => {
115
148
  console.log('Advanced cleanup completed');
149
+ // 执行额外的清理步骤
150
+ performFinalCleanup(paths);
151
+ // 如果是删除整个控制器,还需要清理菜单缩进
152
+ if (action === 'all') {
153
+ cleanupMenuIndentation(paths);
154
+ }
116
155
  });
117
156
  }, CLEANUP_TIMEOUT);
118
157
  };
158
+ // 新增:智能菜单清理函数
159
+ const cleanupMenuIndentation = (paths) => {
160
+ // 读取菜单文件内容
161
+ const menuFile = paths.destClientUtilsMenuPath;
162
+ // 使用更智能的方式处理菜单清理,保持正确的缩进
163
+ setTimeout(() => {
164
+ // 清理可能出现的缩进问题,确保注释代码块有正确的缩进
165
+ shelljs_1.default.sed('-i', /^[ ]{0,2}\/\*\{/gm, ' /*{', menuFile);
166
+ shelljs_1.default.sed('-i', /^[ ]{0,4}key:/gm, ' key:', menuFile);
167
+ shelljs_1.default.sed('-i', /^[ ]{0,4}text:/gm, ' text:', menuFile);
168
+ shelljs_1.default.sed('-i', /^[ ]{0,4}url:/gm, ' url:', menuFile);
169
+ shelljs_1.default.sed('-i', /^[ ]{0,4}icon:/gm, ' icon:', menuFile);
170
+ shelljs_1.default.sed('-i', /^[ ]{0,4}subMenus:/gm, ' subMenus:', menuFile);
171
+ shelljs_1.default.sed('-i', /^[ ]{0,2}\}\*\//gm, ' }*/', menuFile);
172
+ // 修复可能出现的连续逗号问题
173
+ shelljs_1.default.sed('-i', /,,+/g, ',', menuFile);
174
+ // 修复数组末尾多余的逗号(在注释前)
175
+ shelljs_1.default.sed('-i', /,(\s*\/\*)/g, '$1', menuFile);
176
+ // 确保数组项之间有正确的逗号
177
+ shelljs_1.default.sed('-i', /(\})(\s*\/\*)/g, '$1,$2', menuFile);
178
+ console.log('Menu indentation cleanup completed');
179
+ }, 1500);
180
+ };
181
+ // 新增:最终清理函数
182
+ const performFinalCleanup = (paths) => {
183
+ // 修复 reducers.ts 的最终格式
184
+ setTimeout(() => {
185
+ // 确保最后一个属性有逗号(如果不是空对象)
186
+ shelljs_1.default.sed('-i', /(\w+Reducer)(\s*\n\s*\})/, '$1,$2', paths.destClientReduxReducersAllPath);
187
+ // 移除空对象中的逗号
188
+ shelljs_1.default.sed('-i', /\{\s*,\s*\}/, '{}', paths.destClientReduxReducersAllPath);
189
+ // 标准化缩进
190
+ shelljs_1.default.sed('-i', /^[ ]{2}/gm, ' ', paths.destClientReduxReducersAllPath);
191
+ console.log('Final cleanup completed');
192
+ }, 500);
193
+ };
119
194
  /**
120
195
  * 删除控制器相关的文件
121
196
  * @param controller 控制器名称
@@ -132,6 +207,8 @@ const deleteFiles = (controller, action, deleteDBFlag = false, dictionary) => {
132
207
  if (action === 'all') {
133
208
  console.log('Deleting all controller files...');
134
209
  deleteAllControllerFiles(paths);
210
+ // 删除多语言文件
211
+ deleteI18nFiles(paths);
135
212
  }
136
213
  else {
137
214
  console.log(`Deleting specific action files for ${action}...`);
@@ -41,6 +41,12 @@ export declare const initScriptsFiles: (dictionary: string, newDestFolder: strin
41
41
  * @param newDestFolder 新的目标文件夹路径
42
42
  */
43
43
  export declare const initRootFiles: (dictionary: string, newDestFolder: string) => InitResult;
44
+ /**
45
+ * 初始化类型定义文件
46
+ * @param dictionary 目标目录名称
47
+ * @param newDestFolder 新的目标文件夹路径
48
+ */
49
+ export declare const initTypesFiles: (dictionary: string, newDestFolder: string) => void;
44
50
  /**
45
51
  * 初始化测试文件和目录
46
52
  * @param dictionary 目标目录名称
@@ -33,10 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.initTestFiles = exports.initRootFiles = exports.initScriptsFiles = exports.initPublicFiles = exports.initServerFiles = exports.initPagesFiles = exports.initClientFiles = void 0;
36
+ exports.initTestFiles = exports.initTypesFiles = exports.initRootFiles = exports.initScriptsFiles = exports.initPublicFiles = exports.initServerFiles = exports.initPagesFiles = exports.initClientFiles = void 0;
37
37
  const path_1 = __importStar(require("path"));
38
38
  const constants_1 = require("./constants");
39
39
  const utils_1 = require("./utils");
40
+ const fs_1 = require("fs");
40
41
  // 常量定义
41
42
  const CLIENT_FILES = {
42
43
  reduxStore: '/store.ts',
@@ -46,7 +47,14 @@ const CLIENT_FILES = {
46
47
  utilsFetch: '/fetch.ts',
47
48
  utilsCookie: '/cookie.ts',
48
49
  utilsSso: '/sso.ts',
50
+ utilsI18n: '/i18n.ts',
51
+ utilsNavigation: '/navigation.ts',
52
+ utilsSuppressWarnings: '/suppressWarnings.ts',
49
53
  layoutIndex: '/index.tsx',
54
+ languageSwitcher: '/LanguageSwitcher.tsx',
55
+ clientProviders: '/ClientProviders.tsx',
56
+ ssrSafeAntdProvider: '/SSRSafeAntdProvider.tsx',
57
+ suppressHydrationWarnings: '/SuppressHydrationWarnings.tsx',
50
58
  };
51
59
  const PAGES_FILES = {
52
60
  index: '/index.tsx',
@@ -58,10 +66,13 @@ const SERVER_FILES = {
58
66
  apisSso: '/sso.js',
59
67
  utilsCommon: '/common.js',
60
68
  utilsDBPoolManager: '/db-pool-manager.js',
69
+ utilsValidation: '/validation.js',
61
70
  };
62
71
  const PUBLIC_FILES = {
63
72
  images: '/images',
64
- zhizuotuImage: '/zhizuotu_1.png',
73
+ fonts: '/fonts',
74
+ favicon: '/favicon.ico',
75
+ locales: '/locales',
65
76
  };
66
77
  const SCRIPTS_FILES = {
67
78
  startup: '/startup.sh',
@@ -70,6 +81,7 @@ const SCRIPTS_FILES = {
70
81
  };
71
82
  const ROOT_FILES = {
72
83
  nextConfig: '/next.config.js',
84
+ nextI18nConfig: '/next-i18next.config.js',
73
85
  mysqlConfig: '/mysql.config.js',
74
86
  projectConfig: '/project.config.js',
75
87
  tsconfig: '/tsconfig.json',
@@ -84,6 +96,8 @@ const ROOT_FILES = {
84
96
  app: '/app.js',
85
97
  envExampleSource: '/env.example',
86
98
  envExample: '/.env.example',
99
+ envSource: '/env',
100
+ env: '/.env',
87
101
  jestConfig: '/jest.config.js',
88
102
  jestSetup: '/jest.setup.js',
89
103
  jestSetupGlobals: '/jest.setup-globals.js',
@@ -124,6 +138,7 @@ const initClientFiles = (dictionary, newDestFolder, upgradeFlag) => {
124
138
  destPaths.styledLayout,
125
139
  destPaths.utils,
126
140
  destPaths.layout,
141
+ (0, path_1.resolve)(baseDestPath + constants_1.componentsPath),
127
142
  ];
128
143
  createDirectoryStructure(directoriesToCreate);
129
144
  // 3. 定义文件映射
@@ -168,6 +183,41 @@ const initClientFiles = (dictionary, newDestFolder, upgradeFlag) => {
168
183
  dest: (0, path_1.resolve)(destPaths.layout + CLIENT_FILES.layoutIndex),
169
184
  upgradeFlag,
170
185
  },
186
+ {
187
+ source: (0, path_1.resolve)(constants_1.projectClientPath + constants_1.utilsPath + CLIENT_FILES.utilsI18n),
188
+ dest: (0, path_1.resolve)(destPaths.utils + CLIENT_FILES.utilsI18n),
189
+ upgradeFlag,
190
+ },
191
+ {
192
+ source: (0, path_1.resolve)(constants_1.projectClientPath + constants_1.utilsPath + CLIENT_FILES.utilsNavigation),
193
+ dest: (0, path_1.resolve)(destPaths.utils + CLIENT_FILES.utilsNavigation),
194
+ upgradeFlag,
195
+ },
196
+ {
197
+ source: (0, path_1.resolve)(constants_1.projectClientPath + constants_1.componentsPath + CLIENT_FILES.languageSwitcher),
198
+ dest: (0, path_1.resolve)(baseDestPath + constants_1.componentsPath + CLIENT_FILES.languageSwitcher),
199
+ upgradeFlag,
200
+ },
201
+ {
202
+ source: (0, path_1.resolve)(constants_1.sourceClientPath + constants_1.componentsPath + CLIENT_FILES.clientProviders),
203
+ dest: (0, path_1.resolve)(baseDestPath + constants_1.componentsPath + CLIENT_FILES.clientProviders),
204
+ upgradeFlag,
205
+ },
206
+ {
207
+ source: (0, path_1.resolve)(constants_1.sourceClientPath + constants_1.componentsPath + CLIENT_FILES.ssrSafeAntdProvider),
208
+ dest: (0, path_1.resolve)(baseDestPath + constants_1.componentsPath + CLIENT_FILES.ssrSafeAntdProvider),
209
+ upgradeFlag,
210
+ },
211
+ {
212
+ source: (0, path_1.resolve)(constants_1.sourceClientPath + constants_1.componentsPath + CLIENT_FILES.suppressHydrationWarnings),
213
+ dest: (0, path_1.resolve)(baseDestPath + constants_1.componentsPath + CLIENT_FILES.suppressHydrationWarnings),
214
+ upgradeFlag,
215
+ },
216
+ {
217
+ source: (0, path_1.resolve)(constants_1.sourceClientPath + constants_1.utilsPath + CLIENT_FILES.utilsSuppressWarnings),
218
+ dest: (0, path_1.resolve)(baseDestPath + constants_1.utilsPath + CLIENT_FILES.utilsSuppressWarnings),
219
+ upgradeFlag,
220
+ },
171
221
  // 这些文件不使用 upgradeFlag
172
222
  {
173
223
  source: (0, path_1.resolve)(constants_1.sourceClientPathGeneration + constants_1.reduxPath + constants_1.reduxReducersPath),
@@ -274,6 +324,11 @@ const initServerFiles = (dictionary, newDestFolder, upgradeFlag) => {
274
324
  dest: (0, path_1.resolve)(destPaths.utils + SERVER_FILES.utilsDBPoolManager),
275
325
  upgradeFlag,
276
326
  },
327
+ {
328
+ source: (0, path_1.resolve)(constants_1.sourceServerPath + constants_1.utilsPath + SERVER_FILES.utilsValidation),
329
+ dest: (0, path_1.resolve)(destPaths.utils + SERVER_FILES.utilsValidation),
330
+ upgradeFlag,
331
+ },
277
332
  // REST 文件不使用 upgradeFlag
278
333
  {
279
334
  source: (0, path_1.resolve)(constants_1.sourceServerPathGeneration + constants_1.restPath),
@@ -307,9 +362,11 @@ const initPublicFiles = (dictionary, newDestFolder, upgradeFlag) => {
307
362
  const destPaths = {
308
363
  public: baseDestPath,
309
364
  images: (0, path_1.resolve)(baseDestPath + PUBLIC_FILES.images),
365
+ fonts: (0, path_1.resolve)(baseDestPath + PUBLIC_FILES.fonts),
366
+ locales: (0, path_1.resolve)(baseDestPath + PUBLIC_FILES.locales),
310
367
  };
311
368
  // 2. 创建目录结构
312
- const directoriesToCreate = [destPaths.public, destPaths.images];
369
+ const directoriesToCreate = [destPaths.public, destPaths.images, destPaths.fonts, destPaths.locales];
313
370
  createDirectoryStructure(directoriesToCreate);
314
371
  // 3. 定义文件映射
315
372
  const fileMappings = [
@@ -319,13 +376,42 @@ const initPublicFiles = (dictionary, newDestFolder, upgradeFlag) => {
319
376
  upgradeFlag,
320
377
  },
321
378
  {
322
- source: (0, path_1.resolve)(constants_1.sourcePublicPath + PUBLIC_FILES.images + PUBLIC_FILES.zhizuotuImage),
323
- dest: (0, path_1.resolve)(destPaths.images + PUBLIC_FILES.zhizuotuImage),
379
+ source: (0, path_1.resolve)(constants_1.sourcePublicPath + PUBLIC_FILES.favicon),
380
+ dest: (0, path_1.resolve)(destPaths.public + PUBLIC_FILES.favicon),
324
381
  upgradeFlag,
325
382
  },
326
383
  ];
327
384
  // 4. 复制文件
328
385
  copyMultipleFiles(fileMappings);
386
+ // 5. 复制 fonts 目录下的所有文件
387
+ const sourceFontsDir = (0, path_1.resolve)(constants_1.sourcePublicPath + PUBLIC_FILES.fonts);
388
+ if ((0, fs_1.existsSync)(sourceFontsDir)) {
389
+ const fontFiles = (0, fs_1.readdirSync)(sourceFontsDir);
390
+ fontFiles.forEach((file) => {
391
+ const sourceFile = (0, path_1.resolve)(sourceFontsDir, file);
392
+ const destFile = (0, path_1.resolve)(destPaths.fonts, file);
393
+ (0, utils_1.copyFileSync)(sourceFile, destFile, upgradeFlag);
394
+ });
395
+ }
396
+ // 6. 复制 locales 目录下的所有文件(递归复制)
397
+ const sourceLocalesDir = (0, path_1.resolve)(constants_1.projectPublicPath + PUBLIC_FILES.locales);
398
+ if ((0, fs_1.existsSync)(sourceLocalesDir)) {
399
+ const copyLocalesRecursive = (sourceDir, destDir) => {
400
+ const items = (0, fs_1.readdirSync)(sourceDir, { withFileTypes: true });
401
+ items.forEach((item) => {
402
+ const sourcePath = (0, path_1.resolve)(sourceDir, item.name);
403
+ const destPath = (0, path_1.resolve)(destDir, item.name);
404
+ if (item.isDirectory()) {
405
+ (0, utils_1.mkdirSync)(destPath);
406
+ copyLocalesRecursive(sourcePath, destPath);
407
+ }
408
+ else {
409
+ (0, utils_1.copyFileSync)(sourcePath, destPath, upgradeFlag);
410
+ }
411
+ });
412
+ };
413
+ copyLocalesRecursive(sourceLocalesDir, destPaths.locales);
414
+ }
329
415
  console.log('Public files initialization completed');
330
416
  return {
331
417
  destPublicHealthCheckPath: (0, path_1.resolve)(destPaths.public + constants_1.slbHealthCheckPath),
@@ -390,6 +476,10 @@ const initRootFiles = (dictionary, newDestFolder) => {
390
476
  source: (0, path_1.resolve)(constants_1.sourceGenerationPath + ROOT_FILES.nextConfig),
391
477
  dest: (0, path_1.resolve)(baseDestPath + ROOT_FILES.nextConfig),
392
478
  },
479
+ {
480
+ source: (0, path_1.resolve)(constants_1.destFolder + ROOT_FILES.nextI18nConfig),
481
+ dest: (0, path_1.resolve)(baseDestPath + ROOT_FILES.nextI18nConfig),
482
+ },
393
483
  {
394
484
  source: (0, path_1.resolve)(constants_1.sourceGenerationPath + ROOT_FILES.mysqlConfig),
395
485
  dest: (0, path_1.resolve)(baseDestPath + ROOT_FILES.mysqlConfig),
@@ -434,6 +524,10 @@ const initRootFiles = (dictionary, newDestFolder) => {
434
524
  source: (0, path_1.resolve)(constants_1.sourceGenerationPath + ROOT_FILES.envExampleSource),
435
525
  dest: (0, path_1.resolve)(baseDestPath + ROOT_FILES.envExample),
436
526
  },
527
+ {
528
+ source: (0, path_1.resolve)(constants_1.sourceGenerationPath + ROOT_FILES.envSource),
529
+ dest: (0, path_1.resolve)(baseDestPath + ROOT_FILES.env),
530
+ },
437
531
  {
438
532
  source: (0, path_1.resolve)(constants_1.sourceGenerationPath + ROOT_FILES.jestConfig),
439
533
  dest: (0, path_1.resolve)(baseDestPath + ROOT_FILES.jestConfig),
@@ -460,6 +554,32 @@ const initRootFiles = (dictionary, newDestFolder) => {
460
554
  }
461
555
  };
462
556
  exports.initRootFiles = initRootFiles;
557
+ /**
558
+ * 初始化类型定义文件
559
+ * @param dictionary 目标目录名称
560
+ * @param newDestFolder 新的目标文件夹路径
561
+ */
562
+ const initTypesFiles = (dictionary, newDestFolder) => {
563
+ console.log('Initializing types files...');
564
+ try {
565
+ // 1. 确定目标路径
566
+ const baseDestPath = dictionary === '' ? constants_1.destTypesPath : path_1.default.join(newDestFolder, constants_1.typesPath);
567
+ // 2. 创建目录
568
+ createDirectoryStructure([baseDestPath]);
569
+ // 3. 复制 i18next.d.ts 文件
570
+ const sourceI18nextFile = (0, path_1.resolve)(constants_1.destFolder, 'types', 'i18next.d.ts');
571
+ const destI18nextFile = (0, path_1.resolve)(baseDestPath, 'i18next.d.ts');
572
+ if ((0, fs_1.existsSync)(sourceI18nextFile)) {
573
+ (0, utils_1.copyFileSync)(sourceI18nextFile, destI18nextFile);
574
+ }
575
+ console.log('Types files initialization completed');
576
+ }
577
+ catch (error) {
578
+ console.error('Failed to initialize types files:', error);
579
+ throw error;
580
+ }
581
+ };
582
+ exports.initTypesFiles = initTypesFiles;
463
583
  /**
464
584
  * 初始化测试文件和目录
465
585
  * @param dictionary 目标目录名称
@@ -0,0 +1,48 @@
1
+ /**
2
+ * 文件生成器
3
+ * 负责将生成的内容写入到文件系统
4
+ */
5
+ export declare class FileGenerator {
6
+ private projectPath;
7
+ constructor(projectPath?: string);
8
+ /**
9
+ * 生成多语言文件
10
+ */
11
+ generateI18nFiles(controller: string, action: string, fields: any[]): void;
12
+ /**
13
+ * 生成页面组件文件
14
+ */
15
+ generatePageFile(controller: string, action: string, _fields: any[], content: string): void;
16
+ /**
17
+ * 生成样式文件
18
+ */
19
+ generateStyleFile(controller: string, action: string): void;
20
+ /**
21
+ * 生成Redux相关文件
22
+ */
23
+ generateReduxFiles(controller: string, action: string, _fields: any[]): void;
24
+ /**
25
+ * 生成服务文件
26
+ */
27
+ generateServiceFile(controller: string, action: string): void;
28
+ /**
29
+ * 确保目录存在
30
+ */
31
+ private ensureDirectoryExists;
32
+ /**
33
+ * 生成样式组件内容
34
+ */
35
+ private generateStyledComponentsContent;
36
+ /**
37
+ * 生成Actions内容
38
+ */
39
+ private generateActionsContent;
40
+ /**
41
+ * 生成Reducer内容
42
+ */
43
+ private generateReducerContent;
44
+ /**
45
+ * 生成Service内容
46
+ */
47
+ private generateServiceContent;
48
+ }