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
@@ -0,0 +1,32 @@
1
+ // 这个文件需要在所有 React 组件加载之前执行
2
+ // 用于抑制 useLayoutEffect 在服务端渲染时的警告
3
+
4
+ if (typeof window === 'undefined') {
5
+ // 服务端环境
6
+ const originalError = console.error
7
+ const originalWarn = console.warn
8
+
9
+ console.error = function (...args) {
10
+ const message = args[0]
11
+ if (
12
+ typeof message === 'string' &&
13
+ (message.includes('useLayoutEffect does nothing on the server') ||
14
+ message.includes('Warning: useLayoutEffect does nothing on the server'))
15
+ ) {
16
+ return
17
+ }
18
+ originalError.apply(console, args)
19
+ }
20
+
21
+ console.warn = function (...args) {
22
+ const message = args[0]
23
+ if (
24
+ typeof message === 'string' &&
25
+ (message.includes('useLayoutEffect does nothing on the server') ||
26
+ message.includes('Warning: useLayoutEffect does nothing on the server'))
27
+ ) {
28
+ return
29
+ }
30
+ originalWarn.apply(console, args)
31
+ }
32
+ }
package/eslint.config.js CHANGED
@@ -1,7 +1,7 @@
1
- const js = require('@eslint/js');
2
- const typescript = require('@typescript-eslint/eslint-plugin');
3
- const typescriptParser = require('@typescript-eslint/parser');
4
- const prettier = require('eslint-plugin-prettier');
1
+ const js = require('@eslint/js')
2
+ const typescript = require('@typescript-eslint/eslint-plugin')
3
+ const typescriptParser = require('@typescript-eslint/parser')
4
+ const prettier = require('eslint-plugin-prettier')
5
5
 
6
6
  module.exports = [
7
7
  js.configs.recommended,
@@ -29,7 +29,7 @@ module.exports = [
29
29
  },
30
30
  plugins: {
31
31
  '@typescript-eslint': typescript,
32
- 'prettier': prettier
32
+ prettier: prettier
33
33
  },
34
34
  rules: {
35
35
  'no-console': 'off', // 允许 console 语句用于调试
@@ -46,14 +46,17 @@ module.exports = [
46
46
  'prefer-arrow-callback': 'warn',
47
47
  '@typescript-eslint/no-var-requires': 'off', // 允许 require
48
48
  '@typescript-eslint/no-explicit-any': 'warn', // 警告但不报错
49
- '@typescript-eslint/no-unused-vars': ['warn', {
50
- argsIgnorePattern: '^_',
51
- varsIgnorePattern: '^_'
52
- }],
49
+ '@typescript-eslint/no-unused-vars': [
50
+ 'warn',
51
+ {
52
+ argsIgnorePattern: '^_',
53
+ varsIgnorePattern: '^_'
54
+ }
55
+ ],
53
56
  '@typescript-eslint/no-inferrable-types': 'warn',
54
57
  '@typescript-eslint/prefer-optional-chain': 'warn',
55
58
  '@typescript-eslint/no-explicit-any': 'off',
56
- 'prettier/prettier': 'error'
59
+ 'prettier/prettier': 'off'
57
60
  }
58
61
  },
59
62
  {
@@ -82,14 +85,14 @@ module.exports = [
82
85
  },
83
86
  plugins: {
84
87
  '@typescript-eslint': typescript,
85
- 'prettier': prettier
88
+ prettier: prettier
86
89
  },
87
90
  rules: {
88
91
  'no-console': 'off',
89
92
  'no-undef': 'off',
90
93
  'no-unused-vars': 'off',
91
94
  '@typescript-eslint/no-explicit-any': 'off',
92
- 'prettier/prettier': 'error'
95
+ 'prettier/prettier': 'off'
93
96
  }
94
97
  },
95
98
  {
@@ -113,12 +116,6 @@ module.exports = [
113
116
  }
114
117
  },
115
118
  {
116
- ignores: [
117
- 'node_modules/**',
118
- 'lib/**',
119
- '.next/**',
120
- 'coverage/**',
121
- '*.config.js'
122
- ]
119
+ ignores: ['node_modules/**', 'lib/**', '.next/**', 'coverage/**', '*.config.js']
123
120
  }
124
- ];
121
+ ]
@@ -2,4 +2,4 @@
2
2
 
3
3
  export default {
4
4
  //templateManage: templateManageReducer,
5
- }
5
+ }
@@ -1,34 +1,40 @@
1
1
  import { BookOutlined, SolutionOutlined } from '@ant-design/icons'
2
2
  import React from 'react'
3
3
 
4
- let key = 1
4
+ // 统一的菜单配置函数,支持可选的多语言翻译
5
+ export const getMenuConfig = (t?: (key: string) => string) => {
6
+ let key = 1
5
7
 
6
- export default [
7
- {
8
- key: (++key).toString(),
9
- text: '', // 空目录不显示,为了使用 SolutionOutlined 而不报错
10
- url: '/',
11
- icon: <SolutionOutlined rev={undefined} />,
12
- subMenus: null
13
- },
14
- {
15
- key: (++key).toString(),
16
- text: '介绍',
17
- url: '/',
18
- icon: <BookOutlined rev={undefined} />,
19
- subMenus: null
20
- },
21
- /*{
22
- key: (++key).toString(),
23
- text: '模板',
24
- url: '/template/manage',
25
- icon: <SolutionOutlined rev={undefined} />,
26
- subMenus: [
27
- {
28
- key: key + '_1',
29
- text: '模板1',
30
- url: '/template/manage'
31
- }
32
- ]
33
- }*/
34
- ]
8
+ return [
9
+ {
10
+ key: (++key).toString(),
11
+ text: '', // 空目录不显示,为了使用 SolutionOutlined 而不报错
12
+ url: '/',
13
+ icon: <SolutionOutlined rev={undefined} />,
14
+ subMenus: null,
15
+ },
16
+ {
17
+ key: (++key).toString(),
18
+ text: t ? t('layout:layout.menu.introduction') : '介绍',
19
+ url: '/',
20
+ icon: <BookOutlined rev={undefined} />,
21
+ subMenus: null,
22
+ },
23
+ /*{
24
+ key: (++key).toString(),
25
+ text: t ? t('layout:layout.menu.template') : '',
26
+ url: '/template/manage',
27
+ icon: <SolutionOutlined rev={undefined} />,
28
+ subMenus: [
29
+ {
30
+ key: `${key}_1`,
31
+ text: t ? t('layout:layout.menu.template1') : '',
32
+ url: '/template/manage',
33
+ },
34
+ ],
35
+ }*/
36
+ ]
37
+ }
38
+
39
+ // 默认导出不传翻译函数,使用中文
40
+ export default getMenuConfig()
package/generation/env ADDED
@@ -0,0 +1,3 @@
1
+ # Login Configuration
2
+ LOGIN_USERNAME=admin
3
+ LOGIN_PASSWORD_HASH=$2b$10$CsZ7eZWpzOmDPN4IqwNMJOgqsz.zpFnAnuk4JsF8Nr4P7Hp19eMiy
@@ -1,7 +1,11 @@
1
1
  const { nextConfig } = require('nsgm-cli')
2
+ const { i18n } = require('./next-i18next.config')
2
3
 
3
4
  module.exports = (phase, defaultConfig) => {
4
- let configObj = nextConfig(phase, defaultConfig)
5
+ let configObj = nextConfig(phase, defaultConfig)
5
6
 
6
- return configObj
7
- }
7
+ // 确保国际化配置被正确应用
8
+ configObj.i18n = i18n
9
+
10
+ return configObj
11
+ }
@@ -38,6 +38,9 @@
38
38
  "eslint": "^9",
39
39
  "eslint-config-prettier": "^10",
40
40
  "eslint-plugin-prettier": "^5",
41
- "prettier": "^3"
41
+ "prettier": "^3",
42
+ "next-i18next": "^15",
43
+ "react-i18next": "^15",
44
+ "i18next": "^24"
42
45
  }
43
- }
46
+ }
@@ -5,25 +5,20 @@
5
5
  "module": "commonjs",
6
6
  "declaration": true,
7
7
  "strict": true,
8
- "lib": [
9
- "dom",
10
- "ES2022"
11
- ],
8
+ "lib": ["dom", "ES2022"],
12
9
  "esModuleInterop": true,
13
10
  "allowJs": true,
14
11
  "skipLibCheck": true,
15
12
  "forceConsistentCasingInFileNames": true,
16
13
  "noEmit": false,
17
- "moduleResolution": "node",
14
+ "moduleResolution": "bundler",
18
15
  "resolveJsonModule": true,
19
16
  "isolatedModules": true,
20
17
  "noImplicitAny": false,
21
18
  "incremental": true,
22
19
  "baseUrl": ".",
23
20
  "paths": {
24
- "@/*": [
25
- "client/*"
26
- ]
21
+ "@/*": ["client/*"]
27
22
  },
28
23
  "noUnusedLocals": true,
29
24
  "noUnusedParameters": true,
@@ -31,14 +26,6 @@
31
26
  "noImplicitReturns": true,
32
27
  "noFallthroughCasesInSwitch": true
33
28
  },
34
- "include": [
35
- "client/**/*",
36
- "pages/**/*"
37
- ],
38
- "exclude": [
39
- "node_modules",
40
- "**/__tests__/*",
41
- ".next",
42
- "lib"
43
- ]
44
- }
29
+ "include": ["client/**/*", "pages/**/*"],
30
+ "exclude": ["node_modules", "**/__tests__/*", ".next", "lib"]
31
+ }
@@ -47,10 +47,10 @@ exports.createCommand = {
47
47
  const wizardResult = await utils_1.Prompt.createControllerWizard();
48
48
  utils_1.Console.separator();
49
49
  utils_1.Console.title('📋 控制器配置确认');
50
+ utils_1.Console.info(`项目目录: ${wizardResult.dictionary}`);
50
51
  utils_1.Console.info(`控制器名称: ${wizardResult.controller}`);
51
52
  utils_1.Console.info(`功能模块: 完整CRUD + 导入导出 + 批量删除`);
52
53
  utils_1.Console.info(`描述: ${wizardResult.description}`);
53
- utils_1.Console.info(`项目目录: ${wizardResult.dictionary}`);
54
54
  utils_1.Console.info(`数据库表: ${wizardResult.includeDatabase ? '是' : '否'}`);
55
55
  if (wizardResult.includeDatabase && wizardResult.fields.length > 0) {
56
56
  const fieldNames = wizardResult.fields.map((field) => field.name).join(', ');
@@ -48,9 +48,9 @@ exports.deleteCommand = {
48
48
  const wizardResult = await utils_1.Prompt.deleteControllerWizard();
49
49
  utils_1.Console.separator();
50
50
  utils_1.Console.title('📋 删除确认');
51
+ utils_1.Console.info(`项目目录: ${wizardResult.dictionary}`);
51
52
  utils_1.Console.info(`控制器名称: ${wizardResult.controller}`);
52
53
  utils_1.Console.info(`删除范围: ${wizardResult.action === 'all' ? '所有相关文件' : '指定操作'}`);
53
- utils_1.Console.info(`项目目录: ${wizardResult.dictionary}`);
54
54
  utils_1.Console.info(`删除数据库: ${wizardResult.deleteDatabase ? '是' : '否'}`);
55
55
  utils_1.Console.separator();
56
56
  const confirmed = await utils_1.Prompt.confirm('确认删除?此操作不可恢复!', false);
@@ -13,7 +13,7 @@ exports.initCommand = {
13
13
  options: [
14
14
  {
15
15
  name: 'dictionary',
16
- description: '项目目录名称',
16
+ description: '项目目录',
17
17
  default: '.',
18
18
  type: 'string',
19
19
  },
@@ -36,7 +36,7 @@ exports.initCommand = {
36
36
  const wizardResult = await utils_1.Prompt.initWizard();
37
37
  utils_1.Console.separator();
38
38
  utils_1.Console.title('📋 项目配置确认');
39
- utils_1.Console.info(`项目名称: ${wizardResult.projectName}`);
39
+ utils_1.Console.info(`项目目录: ${wizardResult.projectName}`);
40
40
  utils_1.Console.info(`项目描述: ${wizardResult.description}`);
41
41
  utils_1.Console.info(`作者: ${wizardResult.author}`);
42
42
  utils_1.Console.info(`数据库: ${wizardResult.database ? '是' : '否'}`);
@@ -92,10 +92,10 @@ exports.initCommand = {
92
92
  utils_1.Console.box(`项目已成功创建到 ${finalOptions.dictionary} 目录\n\n` +
93
93
  `下一步:\n` +
94
94
  `1. cd ${finalOptions.dictionary}\n` +
95
- `2. cp .env.example .env\n` +
96
- `3. npm run generate-password yourPassword\n` +
97
- `4. modify .env LOGIN_PASSWORD_HASH=yourEncryptedPassword\n` +
98
- `5. npm run dev`, 'success');
95
+ `2. npm run dev\n\n` +
96
+ `默认登录账号: admin/admin123\n` +
97
+ `如需修改密码: npm run generate-password yourNewPassword\n` +
98
+ `然后修改 .env 中的 LOGIN_PASSWORD_HASH`, 'success');
99
99
  }
100
100
  catch (error) {
101
101
  spinner.fail('项目初始化失败');
@@ -68,7 +68,7 @@ export declare class Prompt {
68
68
  fields: FieldDefinition[];
69
69
  }>;
70
70
  /**
71
- * 收集字段定义
71
+ * 收集字段定义 (简化版本)
72
72
  */
73
73
  static collectFieldDefinitions(): Promise<FieldDefinition[]>;
74
74
  /**
@@ -90,14 +90,14 @@ class Prompt {
90
90
  {
91
91
  type: 'input',
92
92
  name: 'projectName',
93
- message: '项目名称:',
93
+ message: '项目目录:',
94
94
  default: 'my-nsgm-project',
95
95
  validate: (input) => {
96
96
  if (!input.trim())
97
- return '项目名称不能为空';
97
+ return '项目目录不能为空';
98
98
  // 允许路径格式,包括相对路径和绝对路径
99
99
  if (!/^[a-zA-Z0-9\-_./\\]+$/.test(input))
100
- return '项目名称只能包含字母、数字、横线、下划线和路径分隔符';
100
+ return '项目目录只能包含字母、数字、横线、下划线和路径分隔符';
101
101
  return true;
102
102
  },
103
103
  },
@@ -129,6 +129,17 @@ class Prompt {
129
129
  console_1.Console.title('📝 创建控制器向导 (包含完整CRUD + 导入导出 + 批量删除功能)');
130
130
  console_1.Console.newLine();
131
131
  const answers = await inquirer_1.default.prompt([
132
+ {
133
+ type: 'input',
134
+ name: 'dictionary',
135
+ message: '项目目录:',
136
+ default: '.',
137
+ validate: (input) => {
138
+ if (!input.trim())
139
+ return '项目目录不能为空';
140
+ return true;
141
+ },
142
+ },
132
143
  {
133
144
  type: 'input',
134
145
  name: 'controller',
@@ -147,17 +158,6 @@ class Prompt {
147
158
  message: '控制器描述:',
148
159
  default: (answers) => `${answers.controller} 控制器`,
149
160
  },
150
- {
151
- type: 'input',
152
- name: 'dictionary',
153
- message: '项目目录:',
154
- default: '.',
155
- validate: (input) => {
156
- if (!input.trim())
157
- return '项目目录不能为空';
158
- return true;
159
- },
160
- },
161
161
  {
162
162
  type: 'confirm',
163
163
  name: 'useCustomFields',
@@ -193,11 +193,10 @@ class Prompt {
193
193
  return answers;
194
194
  }
195
195
  /**
196
- * 收集字段定义
196
+ * 收集字段定义 (简化版本)
197
197
  */
198
198
  static async collectFieldDefinitions() {
199
199
  const fields = [];
200
- let addMore = true;
201
200
  // 默认添加ID字段
202
201
  fields.push({
203
202
  name: 'id',
@@ -207,97 +206,57 @@ class Prompt {
207
206
  isPrimaryKey: true,
208
207
  isAutoIncrement: true,
209
208
  });
210
- console_1.Console.info('💡 提示:系统会自动添加 create_date 和 update_date 字段');
211
- while (addMore) {
212
- const fieldAnswers = await inquirer_1.default.prompt([
213
- {
214
- type: 'input',
215
- name: 'name',
216
- message: '字段名称:',
217
- validate: (input) => {
218
- if (!input.trim())
219
- return '字段名称不能为空';
220
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(input))
221
- return '字段名称只能包含字母、数字和下划线,且以字母或下划线开头';
222
- if (fields.some((f) => f.name === input.trim()))
223
- return '字段名称已存在';
224
- if (['create_date', 'update_date'].includes(input.trim()))
225
- return '系统字段将自动添加';
226
- return true;
227
- },
228
- },
229
- {
230
- type: 'list',
231
- name: 'type',
232
- message: '字段类型:',
233
- choices: [
234
- { name: 'varchar - 字符串', value: 'varchar' },
235
- { name: 'text - 长文本', value: 'text' },
236
- { name: 'integer - 整数', value: 'integer' },
237
- { name: 'decimal - 小数', value: 'decimal' },
238
- { name: 'boolean - 布尔值', value: 'boolean' },
239
- { name: 'date - 日期', value: 'date' },
240
- { name: 'datetime - 日期时间', value: 'datetime' },
241
- { name: 'timestamp - 时间戳', value: 'timestamp' },
242
- ],
243
- },
244
- {
245
- type: 'input',
246
- name: 'length',
247
- message: '字段长度 (可选,数字类型可指定精度):',
248
- when: (answers) => ['varchar', 'decimal'].includes(answers.type),
249
- default: (answers) => (answers.type === 'varchar' ? '255' : '10,2'),
250
- },
251
- {
252
- type: 'confirm',
253
- name: 'required',
254
- message: '是否必填:',
255
- default: false,
256
- },
257
- {
258
- type: 'input',
259
- name: 'comment',
260
- message: '字段注释:',
261
- default: (answers) => answers.name,
262
- },
263
- {
264
- type: 'confirm',
265
- name: 'showInList',
266
- message: '是否在列表页显示:',
267
- default: true,
268
- },
269
- {
270
- type: 'confirm',
271
- name: 'showInForm',
272
- message: '是否在表单中显示:',
273
- default: true,
274
- },
275
- {
276
- type: 'confirm',
277
- name: 'searchable',
278
- message: '是否可搜索:',
279
- default: (answers) => answers.type === 'varchar',
280
- },
209
+ console_1.Console.info('💡 输入字段信息,输入空白字段名结束添加');
210
+ let fieldIndex = 1;
211
+ while (true) {
212
+ const fieldName = await this.input(`字段${fieldIndex} 名称 (留空结束):`);
213
+ if (!fieldName.trim())
214
+ break;
215
+ // 验证字段名
216
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(fieldName)) {
217
+ console_1.Console.error('字段名称格式无效,请重新输入');
218
+ continue;
219
+ }
220
+ if (fields.some((f) => f.name === fieldName) || ['create_date', 'update_date'].includes(fieldName)) {
221
+ console_1.Console.error('字段名称已存在或为系统保留字段,请重新输入');
222
+ continue;
223
+ }
224
+ // 简化的字段类型选择
225
+ const fieldType = await this.select('字段类型:', [
226
+ 'varchar',
227
+ 'text',
228
+ 'integer',
229
+ 'decimal',
230
+ 'boolean',
231
+ 'date',
232
+ 'datetime',
281
233
  ]);
282
- fields.push({
283
- name: fieldAnswers.name.trim(),
284
- type: fieldAnswers.type,
285
- length: fieldAnswers.length ? fieldAnswers.length.trim() : undefined,
286
- required: fieldAnswers.required,
287
- comment: fieldAnswers.comment.trim(),
288
- showInList: fieldAnswers.showInList,
289
- showInForm: fieldAnswers.showInForm,
290
- searchable: fieldAnswers.searchable,
291
- });
292
- const continueAnswer = await inquirer_1.default.prompt([
293
- {
294
- type: 'confirm',
295
- name: 'addMore',
296
- message: '是否继续添加字段:',
297
- default: false,
298
- },
299
- ]);
300
- addMore = continueAnswer.addMore;
234
+ // 只对需要长度的类型询问长度
235
+ let length;
236
+ if (fieldType === 'varchar') {
237
+ length = await this.input('字符串长度:', '255');
238
+ }
239
+ else if (fieldType === 'decimal') {
240
+ length = await this.input('小数精度 (如: 10,2):', '10,2');
241
+ }
242
+ // 简化配置:只询问是否必填和注释
243
+ const required = await this.confirm('是否必填:', true);
244
+ const comment = await this.input('字段注释:', fieldName);
245
+ const field = {
246
+ name: fieldName,
247
+ type: fieldType,
248
+ required,
249
+ comment,
250
+ showInList: true, // 默认在列表显示
251
+ showInForm: true, // 默认在表单显示
252
+ searchable: fieldType === 'varchar', // varchar类型默认可搜索
253
+ };
254
+ // 只有当length有值时才添加
255
+ if (length) {
256
+ field.length = length;
257
+ }
258
+ fields.push(field);
259
+ fieldIndex++;
301
260
  }
302
261
  // 自动添加系统字段
303
262
  fields.push({
@@ -322,6 +281,17 @@ class Prompt {
322
281
  console_1.Console.title('🗑️ 删除控制器向导');
323
282
  console_1.Console.newLine();
324
283
  const answers = await inquirer_1.default.prompt([
284
+ {
285
+ type: 'input',
286
+ name: 'dictionary',
287
+ message: '项目目录:',
288
+ default: '.',
289
+ validate: (input) => {
290
+ if (!input.trim())
291
+ return '项目目录不能为空';
292
+ return true;
293
+ },
294
+ },
325
295
  {
326
296
  type: 'input',
327
297
  name: 'controller',
@@ -344,17 +314,6 @@ class Prompt {
344
314
  ],
345
315
  default: 'all',
346
316
  },
347
- {
348
- type: 'input',
349
- name: 'dictionary',
350
- message: '项目目录:',
351
- default: '.',
352
- validate: (input) => {
353
- if (!input.trim())
354
- return '项目目录不能为空';
355
- return true;
356
- },
357
- },
358
317
  {
359
318
  type: 'confirm',
360
319
  name: 'deleteDatabase',
@@ -13,12 +13,15 @@ declare const publicPathSource = "../public";
13
13
  declare const publicPath = "./public";
14
14
  declare const scriptsPathSource = "../scripts";
15
15
  declare const scriptsPath = "./scripts";
16
+ declare const typesPathSource = "../types";
17
+ declare const typesPath = "./types";
16
18
  declare const reduxPath = "/redux";
17
19
  declare const servicePath = "/service";
18
20
  declare const styledPath = "/styled";
19
21
  declare const styledLayoutPath = "/layout";
20
22
  declare const utilsPath = "/utils";
21
23
  declare const layoutPath = "/layout";
24
+ declare const componentsPath = "/components";
22
25
  declare const modulesPath = "/modules";
23
26
  declare const apisPath = "/apis";
24
27
  declare const sqlPath = "/sql";
@@ -35,6 +38,9 @@ declare const sourceServerPathGeneration: string;
35
38
  declare const sourcePagesPath: string;
36
39
  declare const sourcePublicPath: string;
37
40
  declare const sourceScriptsPath: string;
41
+ declare const sourceTypesPath: string;
42
+ declare const projectClientPath: string;
43
+ declare const projectPublicPath: string;
38
44
  declare const destClientPath: string;
39
45
  declare const destClientReduxPath: string;
40
46
  declare const destClientServicePath: string;
@@ -50,9 +56,10 @@ declare const destServerUtilsPath: string;
50
56
  declare const destPagesPath: string;
51
57
  declare const destPublicPath: string;
52
58
  declare const destScriptsPath: string;
59
+ declare const destTypesPath: string;
53
60
  declare const destClientUtilsMenuPath: string;
54
61
  declare const destClientReduxReducersAllPath: string;
55
62
  declare const destPublicHealthCheckPath: string;
56
63
  declare const destPackagePath: string;
57
64
  declare const destServerRestPath: string;
58
- export { sourceFolder, destFolder, isLocal, generationPath, clientPathSource, clientPath, serverPathSource, serverPath, pagesPathSource, pagesPath, publicPathSource, publicPath, scriptsPathSource, scriptsPath, reduxPath, servicePath, styledPath, styledLayoutPath, utilsPath, layoutPath, modulesPath, apisPath, sqlPath, utilsMenuPath, reduxReducersPath, slbHealthCheckPath, packagePath, restPath, sourceGenerationPath, sourceClientPath, sourceClientPathGeneration, sourceServerPath, sourceServerPathGeneration, sourcePagesPath, sourcePublicPath, sourceScriptsPath, destClientPath, destClientReduxPath, destClientServicePath, destClientStyledPath, destClientStyledLayoutPath, destClientUtilsPath, destClientLayoutPath, destServerPath, destServerModulesPath, destServerApisPath, destServerSqlPath, destServerUtilsPath, destPagesPath, destPublicPath, destScriptsPath, destClientUtilsMenuPath, destClientReduxReducersAllPath, destPublicHealthCheckPath, destPackagePath, destServerRestPath, mysqlUser, mysqlPassword, mysqlHost, mysqlPort, mysqlDatabase, };
65
+ export { sourceFolder, destFolder, isLocal, generationPath, clientPathSource, clientPath, serverPathSource, serverPath, pagesPathSource, pagesPath, publicPathSource, publicPath, scriptsPathSource, scriptsPath, typesPathSource, typesPath, reduxPath, servicePath, styledPath, styledLayoutPath, utilsPath, layoutPath, componentsPath, modulesPath, apisPath, sqlPath, utilsMenuPath, reduxReducersPath, slbHealthCheckPath, packagePath, restPath, sourceGenerationPath, sourceClientPath, sourceClientPathGeneration, sourceServerPath, sourceServerPathGeneration, sourcePagesPath, sourcePublicPath, sourceScriptsPath, sourceTypesPath, projectClientPath, projectPublicPath, destClientPath, destClientReduxPath, destClientServicePath, destClientStyledPath, destClientStyledLayoutPath, destClientUtilsPath, destClientLayoutPath, destServerPath, destServerModulesPath, destServerApisPath, destServerSqlPath, destServerUtilsPath, destPagesPath, destPublicPath, destScriptsPath, destTypesPath, destClientUtilsMenuPath, destClientReduxReducersAllPath, destPublicHealthCheckPath, destPackagePath, destServerRestPath, mysqlUser, mysqlPassword, mysqlHost, mysqlPort, mysqlDatabase, };