nsgm-cli 2.1.22 → 2.1.24

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 (39) hide show
  1. package/client/utils/common.ts +6 -2
  2. package/client/utils/fetch.ts +1 -1
  3. package/client/utils/sso.ts +13 -3
  4. package/generation/README.md +97 -4
  5. package/generation/config/modules.json +163 -0
  6. package/generation/package.json +1 -0
  7. package/lib/cli/commands/create-config.d.ts +5 -0
  8. package/lib/cli/commands/create-config.js +166 -0
  9. package/lib/cli/index.d.ts +1 -0
  10. package/lib/cli/index.js +1 -0
  11. package/lib/cli/registry.js +2 -0
  12. package/lib/generate_create.js +9 -0
  13. package/lib/generators/dataloader-generator.d.ts +12 -0
  14. package/lib/generators/dataloader-generator.js +221 -0
  15. package/lib/generators/resolver-generator.d.ts +2 -1
  16. package/lib/generators/resolver-generator.js +117 -24
  17. package/lib/generators/schema-generator.js +1 -0
  18. package/lib/server/dataloaders/index.d.ts +38 -0
  19. package/lib/server/dataloaders/index.js +33 -0
  20. package/lib/server/dataloaders/template-dataloader.d.ts +48 -0
  21. package/lib/server/dataloaders/template-dataloader.js +131 -0
  22. package/lib/server/debug/dataloader-debug.d.ts +63 -0
  23. package/lib/server/debug/dataloader-debug.js +192 -0
  24. package/lib/server/graphql.js +9 -0
  25. package/lib/server/utils/dataloader-monitor.d.ts +87 -0
  26. package/lib/server/utils/dataloader-monitor.js +199 -0
  27. package/lib/tsconfig.build.tsbuildinfo +1 -1
  28. package/lib/utils.js +1 -1
  29. package/next-i18next.config.js +7 -5
  30. package/next.config.js +19 -3
  31. package/package.json +3 -2
  32. package/pages/_app.tsx +6 -3
  33. package/pages/api/sso/ticketCheck.ts +117 -0
  34. package/pages/index.tsx +10 -2
  35. package/pages/login.tsx +40 -10
  36. package/pages/template/manage.tsx +15 -1
  37. package/server/apis/sso.js +22 -4
  38. package/server/modules/template/resolver.js +101 -21
  39. package/server/modules/template/schema.js +1 -0
@@ -25,12 +25,16 @@ export const getLocalApiPrefix = () => {
25
25
  protocol = protocol.split(":")[0];
26
26
  }
27
27
  host = location.hostname;
28
- port = location.port || (protocol.indexOf("https") !== -1 ? "443" : "80");
28
+ port = location.port;
29
29
  }
30
30
  // 服务器端:直接使用配置中的值,无需额外处理
31
31
  }
32
32
 
33
- localApiPrefix = `${protocol}://${host}:${port}${prefix}`;
33
+ // 只在非标准端口时才添加端口号
34
+ const isStandardPort = (protocol === "https" && port === "443") || (protocol === "http" && port === "80") || !port;
35
+ const portStr = isStandardPort ? "" : `:${port}`;
36
+
37
+ localApiPrefix = `${protocol}://${host}${portStr}${prefix}`;
34
38
  return localApiPrefix;
35
39
  };
36
40
 
@@ -188,7 +188,7 @@ export const getLocalGraphql = async (query: string, variables: any = {}) => {
188
188
  };
189
189
 
190
190
  const retryResponse = await axios.post(
191
- `${getLocalApiPrefix()}/graphql`,
191
+ `/api/graphql`,
192
192
  { query, variables },
193
193
  { headers: retryHeaders, withCredentials: true }
194
194
  );
@@ -210,22 +210,32 @@ export const directLogin = (userName: string, userPassword: string, callback: an
210
210
  // 使用 encodeURIComponent 处理可能的特殊字符,然后再进行 Base64 编码
211
211
  const safeStr = handleXSS(`${userName},${userPassword}`);
212
212
  const encodedName = btoa(encodeURIComponent(safeStr));
213
- const url = `${getLocalApiPrefix()}/rest/sso/ticketCheck?ticket=XXX&name=${encodedName}`;
213
+ const apiPrefix = getLocalApiPrefix();
214
+ const url = `${apiPrefix}/rest/sso/ticketCheck?ticket=XXX&name=${encodedName}`;
215
+
216
+ console.warn("[Login] Login URL:", url);
217
+ console.warn("[Login] Username:", userName);
214
218
 
215
219
  return fetch(url)
216
- .then((response) => response.json())
220
+ .then((response) => {
221
+ console.warn("[Login] Response status:", response.status);
222
+ return response.json();
223
+ })
217
224
  .then((data) => {
225
+ console.warn("[Login] Response data:", data);
218
226
  if (data && data.returnCode === 0) {
219
227
  // 登录成功,设置cookie
220
228
  if (typeof window !== "undefined") {
229
+ console.warn("[Login] Login successful");
221
230
  storeLogin(data.cookieValue, data.cookieExpire, data.userAttr, callback);
222
231
  return { success: true };
223
232
  }
224
233
  }
234
+ console.warn("[Login] Login failed, returnCode:", data?.returnCode, "message:", data?.message);
225
235
  return { success: false, message: "用户名或密码错误" };
226
236
  })
227
237
  .catch((error) => {
228
- console.error("登录请求失败:", error);
238
+ console.warn("[Login] Login request failed:", error);
229
239
  return { success: false, message: "登录请求失败,请稍后重试" };
230
240
  });
231
241
  };
@@ -32,10 +32,11 @@
32
32
 
33
33
  ### 代码生成命令
34
34
 
35
- | 命令 | 说明 |
36
- | ---------------- | ------------ |
37
- | `npm run create` | 创建模板页面 |
38
- | `npm run delete` | 删除模板页面 |
35
+ | 命令 | 说明 |
36
+ | ----------------------- | --------------------- |
37
+ | `npm run create` | 创建模板页面 |
38
+ | `npm run delete` | 删除模板页面 |
39
+ | `npm run create-config` | 从配置文件批量创建模块 |
39
40
 
40
41
  ### 项目维护命令
41
42
 
@@ -188,6 +189,98 @@ module.exports = {
188
189
  - 不要将 `.env` 文件提交到版本控制系统
189
190
  - 定期更换登录密码
190
191
 
192
+ ## 配置文件批量创建模块
193
+
194
+ 项目支持从 JSON 配置文件批量创建模块,提高开发效率。
195
+
196
+ ### 配置文件位置
197
+
198
+ 配置文件应放置在 `config/` 目录下,例如 `config/modules.json`。
199
+
200
+ ### 配置文件格式
201
+
202
+ #### 单模块配置
203
+
204
+ ```json
205
+ {
206
+ "controller": "product",
207
+ "action": "manage",
208
+ "dictionary": ".",
209
+ "fields": [
210
+ {
211
+ "name": "name",
212
+ "type": "varchar",
213
+ "length": 255,
214
+ "required": true,
215
+ "comment": "商品名称",
216
+ "showInList": true,
217
+ "showInForm": true,
218
+ "searchable": true
219
+ }
220
+ ]
221
+ }
222
+ ```
223
+
224
+ #### 多模块配置
225
+
226
+ ```json
227
+ [
228
+ {
229
+ "controller": "category",
230
+ "action": "manage",
231
+ "dictionary": ".",
232
+ "fields": [...]
233
+ },
234
+ {
235
+ "controller": "product",
236
+ "action": "manage",
237
+ "dictionary": ".",
238
+ "fields": [...]
239
+ }
240
+ ]
241
+ ```
242
+
243
+ 项目已提供示例配置文件 `config/modules.json`,包含 `category` 和 `product` 两个模块。
244
+
245
+ ### 使用方法
246
+
247
+ ```bash
248
+ # 创建所有模块
249
+ npm run create-config config/modules.json
250
+
251
+ # 创建指定模块
252
+ npm run create-config config/modules.json --module category
253
+
254
+ # 预览模式(不实际创建)
255
+ npm run create-config config/modules.json --dry-run
256
+ ```
257
+
258
+ ### 字段命名规范
259
+
260
+ **始终使用蛇形命名(snake_case)**:
261
+
262
+ ```json
263
+ {
264
+ "name": "user_id", // ✅ 正确
265
+ "name": "category_id", // ✅ 正确
266
+ "name": "total_amount", // ✅ 正确
267
+ "name": "create_date", // ✅ 正确
268
+ "name": "update_date" // ✅ 正确
269
+ }
270
+ ```
271
+
272
+ 避免驼峰命名:
273
+
274
+ ```json
275
+ {
276
+ "name": "userId", // ❌ 不推荐
277
+ "name": "categoryId", // ❌ 不推荐
278
+ "name": "totalAmount", // ❌ 不推荐
279
+ }
280
+ ```
281
+
282
+ 更多详细信息,请参考项目中的示例配置文件 `config/modules.json`。
283
+
191
284
  ## 开发指南
192
285
 
193
286
  1. **创建新页面**:使用 `npm run create [controller] [action]` 命令
@@ -0,0 +1,163 @@
1
+ [
2
+ {
3
+ "controller": "category",
4
+ "action": "manage",
5
+ "dictionary": ".",
6
+ "fields": [
7
+ {
8
+ "name": "id",
9
+ "type": "integer",
10
+ "required": true,
11
+ "comment": "主键",
12
+ "isPrimaryKey": true,
13
+ "isAutoIncrement": true
14
+ },
15
+ {
16
+ "name": "name",
17
+ "type": "varchar",
18
+ "length": 100,
19
+ "required": true,
20
+ "comment": "分类名称",
21
+ "showInList": true,
22
+ "showInForm": true,
23
+ "searchable": true
24
+ },
25
+ {
26
+ "name": "description",
27
+ "type": "text",
28
+ "required": false,
29
+ "comment": "分类描述",
30
+ "showInList": false,
31
+ "showInForm": true
32
+ },
33
+ {
34
+ "name": "parent_id",
35
+ "type": "integer",
36
+ "required": false,
37
+ "comment": "父分类ID",
38
+ "showInList": true,
39
+ "showInForm": true
40
+ },
41
+ {
42
+ "name": "sort_order",
43
+ "type": "integer",
44
+ "required": true,
45
+ "comment": "排序",
46
+ "showInList": true,
47
+ "showInForm": true
48
+ },
49
+ {
50
+ "name": "status",
51
+ "type": "varchar",
52
+ "length": 20,
53
+ "required": true,
54
+ "comment": "状态",
55
+ "showInList": true,
56
+ "showInForm": true
57
+ },
58
+ {
59
+ "name": "create_date",
60
+ "type": "timestamp",
61
+ "required": true,
62
+ "comment": "创建时间",
63
+ "isSystemField": true
64
+ },
65
+ {
66
+ "name": "update_date",
67
+ "type": "timestamp",
68
+ "required": true,
69
+ "comment": "更新时间",
70
+ "isSystemField": true
71
+ }
72
+ ]
73
+ },
74
+ {
75
+ "controller": "product",
76
+ "action": "manage",
77
+ "dictionary": ".",
78
+ "fields": [
79
+ {
80
+ "name": "id",
81
+ "type": "integer",
82
+ "required": true,
83
+ "comment": "主键",
84
+ "isPrimaryKey": true,
85
+ "isAutoIncrement": true
86
+ },
87
+ {
88
+ "name": "name",
89
+ "type": "varchar",
90
+ "length": 255,
91
+ "required": true,
92
+ "comment": "商品名称",
93
+ "showInList": true,
94
+ "showInForm": true,
95
+ "searchable": true
96
+ },
97
+ {
98
+ "name": "description",
99
+ "type": "text",
100
+ "required": false,
101
+ "comment": "商品描述",
102
+ "showInList": false,
103
+ "showInForm": true
104
+ },
105
+ {
106
+ "name": "price",
107
+ "type": "decimal",
108
+ "required": true,
109
+ "comment": "商品价格",
110
+ "showInList": true,
111
+ "showInForm": true
112
+ },
113
+ {
114
+ "name": "category_id",
115
+ "type": "integer",
116
+ "required": false,
117
+ "comment": "分类ID",
118
+ "showInList": true,
119
+ "showInForm": true
120
+ },
121
+ {
122
+ "name": "stock",
123
+ "type": "integer",
124
+ "required": true,
125
+ "comment": "库存数量",
126
+ "showInList": true,
127
+ "showInForm": true
128
+ },
129
+ {
130
+ "name": "image_url",
131
+ "type": "varchar",
132
+ "length": 500,
133
+ "required": false,
134
+ "comment": "商品图片URL",
135
+ "showInList": true,
136
+ "showInForm": true
137
+ },
138
+ {
139
+ "name": "status",
140
+ "type": "varchar",
141
+ "length": 20,
142
+ "required": true,
143
+ "comment": "状态",
144
+ "showInList": true,
145
+ "showInForm": true
146
+ },
147
+ {
148
+ "name": "create_date",
149
+ "type": "timestamp",
150
+ "required": true,
151
+ "comment": "创建时间",
152
+ "isSystemField": true
153
+ },
154
+ {
155
+ "name": "update_date",
156
+ "type": "timestamp",
157
+ "required": true,
158
+ "comment": "更新时间",
159
+ "isSystemField": true
160
+ }
161
+ ]
162
+ }
163
+ ]
@@ -13,6 +13,7 @@
13
13
  "create": "nsgm create",
14
14
  "delete": "nsgm delete",
15
15
  "deletedb": "nsgm deletedb",
16
+ "create-config": "nsgm create-config",
16
17
  "generate-password": "node scripts/generate-password-hash.js",
17
18
  "postversion": "git push && git push --tags",
18
19
  "test": "jest",
@@ -0,0 +1,5 @@
1
+ import { Command } from "../types";
2
+ /**
3
+ * 从配置文件创建命令
4
+ */
5
+ export declare const createConfigCommand: Command;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createConfigCommand = void 0;
7
+ const utils_1 = require("../utils");
8
+ const generate_1 = require("../../generate");
9
+ const fs_1 = __importDefault(require("fs"));
10
+ /**
11
+ * 从配置文件创建命令
12
+ */
13
+ exports.createConfigCommand = {
14
+ name: "create-config",
15
+ aliases: ["-cc", "--create-config"],
16
+ description: "从配置文件创建模块",
17
+ usage: "nsgm create-config <config-file> [options]",
18
+ examples: [
19
+ "nsgm create-config config/modules.json",
20
+ "nsgm create-config config/modules.json --module product",
21
+ "nsgm create-config config/modules.json --all",
22
+ ],
23
+ options: [
24
+ {
25
+ name: "module",
26
+ description: "指定要创建的模块名称(如果不指定则创建所有)",
27
+ required: false,
28
+ type: "string",
29
+ },
30
+ {
31
+ name: "all",
32
+ description: "创建配置文件中的所有模块",
33
+ required: false,
34
+ type: "boolean",
35
+ },
36
+ {
37
+ name: "dry-run",
38
+ description: "预览模式,只显示将要创建的模块而不实际创建",
39
+ required: false,
40
+ type: "boolean",
41
+ },
42
+ ],
43
+ execute: async (options) => {
44
+ try {
45
+ // 获取配置文件路径
46
+ const args = process.argv.slice(2);
47
+ if (args.length === 0 || args[0].startsWith("-")) {
48
+ utils_1.Console.error("请指定配置文件路径");
49
+ utils_1.Console.info("使用方法:");
50
+ utils_1.Console.info(" nsgm create-config <config-file> [--module <name>]");
51
+ utils_1.Console.info(" nsgm create-config <config-file> [--all]");
52
+ utils_1.Console.info("");
53
+ utils_1.Console.info("示例:");
54
+ utils_1.Console.info(" nsgm create-config config/modules.json");
55
+ utils_1.Console.info(" nsgm create-config config/modules.json --module category");
56
+ utils_1.Console.info(" nsgm create-config config/modules.json --all");
57
+ process.exit(1);
58
+ }
59
+ const configPath = args[0];
60
+ // 检查配置文件是否存在
61
+ if (!fs_1.default.existsSync(configPath)) {
62
+ utils_1.Console.error(`配置文件不存在: ${configPath}`);
63
+ process.exit(1);
64
+ }
65
+ // 读取配置文件
66
+ const configContent = fs_1.default.readFileSync(configPath, "utf8");
67
+ const config = JSON.parse(configContent);
68
+ // 验证配置格式
69
+ if (!Array.isArray(config)) {
70
+ utils_1.Console.error("配置文件格式错误:必须是一个数组");
71
+ process.exit(1);
72
+ }
73
+ // 解析目标模块
74
+ let targetModules = [];
75
+ if (options.module && typeof options.module === "string") {
76
+ // 创建指定模块
77
+ const targetModule = config.find((m) => m.controller === options.module);
78
+ if (!targetModule) {
79
+ utils_1.Console.error(`未找到模块: ${options.module}`);
80
+ utils_1.Console.info(`可用的模块: ${config.map((m) => m.controller).join(", ")}`);
81
+ process.exit(1);
82
+ }
83
+ targetModules = [targetModule];
84
+ }
85
+ else {
86
+ // 创建所有模块
87
+ targetModules = config;
88
+ }
89
+ // 预览模式
90
+ if (options.dryRun) {
91
+ utils_1.Console.title("📋 预览模式");
92
+ utils_1.Console.newLine();
93
+ utils_1.Console.info("将要创建的模块:");
94
+ utils_1.Console.newLine();
95
+ targetModules.forEach((module, index) => {
96
+ utils_1.Console.highlight(`${index + 1}. ${module.controller}`);
97
+ utils_1.Console.info(` 操作: ${module.action || "manage"}`);
98
+ utils_1.Console.info(` 目录: ${module.dictionary || "./"}`);
99
+ utils_1.Console.info(` 字段数: ${module.fields.length}`);
100
+ utils_1.Console.info(` 字段: ${module.fields.map((f) => f.name).join(", ")}`);
101
+ utils_1.Console.newLine();
102
+ });
103
+ utils_1.Console.separator();
104
+ utils_1.Console.info(`总计: ${targetModules.length} 个模块`);
105
+ utils_1.Console.newLine();
106
+ utils_1.Console.info("移除 --dry-run 参数以实际创建模块");
107
+ return;
108
+ }
109
+ // 确认创建
110
+ utils_1.Console.title(`📦 准备创建 ${targetModules.length} 个模块`);
111
+ utils_1.Console.newLine();
112
+ targetModules.forEach((module, index) => {
113
+ utils_1.Console.info(`${index + 1}. ${module.controller}`);
114
+ });
115
+ utils_1.Console.newLine();
116
+ const confirmed = await utils_1.Prompt.confirm("确认创建这些模块?", true);
117
+ if (!confirmed) {
118
+ utils_1.Console.warning("创建已取消");
119
+ process.exit(0);
120
+ }
121
+ // 逐个创建模块
122
+ let successCount = 0;
123
+ let failureCount = 0;
124
+ const failures = [];
125
+ for (const module of targetModules) {
126
+ utils_1.Console.separator();
127
+ utils_1.Console.highlight(`📦 创建模块 ${successCount + failureCount + 1}/${targetModules.length}: ${module.controller}`);
128
+ try {
129
+ const spinner = utils_1.Console.spinner("正在创建文件...", "green");
130
+ spinner.start();
131
+ // 调用核心创建函数
132
+ (0, generate_1.createFiles)(module.controller, module.action || "manage", module.dictionary || ".", module.fields);
133
+ spinner.succeed("控制器创建完成!");
134
+ successCount++;
135
+ utils_1.Console.newLine();
136
+ }
137
+ catch (error) {
138
+ const errorMessage = error instanceof Error ? error.message : String(error);
139
+ utils_1.Console.error(`错误: ${errorMessage}`);
140
+ failures.push({ module: module.controller, error: errorMessage });
141
+ failureCount++;
142
+ utils_1.Console.newLine();
143
+ }
144
+ }
145
+ // 显示总结
146
+ utils_1.Console.separator();
147
+ utils_1.Console.title("🎉 创建完成");
148
+ utils_1.Console.newLine();
149
+ utils_1.Console.highlight(`✅ 成功: ${successCount} 个`);
150
+ utils_1.Console.highlight(`❌ 失败: ${failureCount} 个`);
151
+ if (failures.length > 0) {
152
+ utils_1.Console.newLine();
153
+ utils_1.Console.error("失败的模块:");
154
+ failures.forEach(({ module, error }) => {
155
+ utils_1.Console.error(` - ${module}: ${error}`);
156
+ });
157
+ }
158
+ utils_1.Console.newLine();
159
+ utils_1.Console.box("创建已完成,请检查生成的文件!", "success");
160
+ }
161
+ catch (error) {
162
+ utils_1.Console.error(`执行失败: ${error}`);
163
+ process.exit(1);
164
+ }
165
+ },
166
+ };
@@ -7,6 +7,7 @@ export * from "./registry";
7
7
  export * from "./app";
8
8
  export * from "./commands/build";
9
9
  export * from "./commands/create";
10
+ export * from "./commands/create-config";
10
11
  export * from "./commands/delete";
11
12
  export * from "./commands/export";
12
13
  export * from "./commands/help";
package/lib/cli/index.js CHANGED
@@ -24,6 +24,7 @@ __exportStar(require("./app"), exports);
24
24
  // 命令导出
25
25
  __exportStar(require("./commands/build"), exports);
26
26
  __exportStar(require("./commands/create"), exports);
27
+ __exportStar(require("./commands/create-config"), exports);
27
28
  __exportStar(require("./commands/delete"), exports);
28
29
  __exportStar(require("./commands/export"), exports);
29
30
  __exportStar(require("./commands/help"), exports);
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CommandRegistry = void 0;
4
4
  const build_1 = require("./commands/build");
5
5
  const create_1 = require("./commands/create");
6
+ const create_config_1 = require("./commands/create-config");
6
7
  const delete_1 = require("./commands/delete");
7
8
  const export_1 = require("./commands/export");
8
9
  const help_1 = require("./commands/help");
@@ -26,6 +27,7 @@ class CommandRegistry {
26
27
  const commands = [
27
28
  build_1.buildCommand,
28
29
  create_1.createCommand,
30
+ create_config_1.createConfigCommand,
29
31
  delete_1.deleteCommand,
30
32
  delete_1.deleteDbCommand,
31
33
  export_1.exportCommand,
@@ -48,6 +48,7 @@ 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
50
  const file_generator_1 = require("./generators/file-generator");
51
+ const dataloader_generator_1 = require("./generators/dataloader-generator");
51
52
  // 常量定义
52
53
  const TEMPLATE_FILES = {
53
54
  reduxActions: "redux/template/manage/actions.ts",
@@ -207,6 +208,7 @@ const generateDynamicFiles = (controller, action, paths, fields, dictionary) =>
207
208
  const resolverGenerator = new resolver_generator_1.ResolverGenerator(controller, action, fields);
208
209
  const serviceGenerator = new service_generator_1.ServiceGenerator(controller, action, fields);
209
210
  const pageGenerator = new page_generator_1.PageGenerator(controller, action, fields);
211
+ const dataLoaderGenerator = new dataloader_generator_1.DataLoaderGenerator(controller, action, fields);
210
212
  // 根据 dictionary 确定文件生成器的项目路径
211
213
  const projectPath = !dictionary || dictionary === "." ? "." : path_1.default.join(constants_1.destFolder, dictionary);
212
214
  const fileGenerator = new file_generator_1.FileGenerator(projectPath);
@@ -216,6 +218,11 @@ const generateDynamicFiles = (controller, action, paths, fields, dictionary) =>
216
218
  fs_1.default.writeFileSync(paths.destServerModulesResolver, resolverGenerator.generate());
217
219
  fs_1.default.writeFileSync(paths.destClientAction, serviceGenerator.generate());
218
220
  fs_1.default.writeFileSync(paths.destPagesAction, pageGenerator.generate());
221
+ // 生成 DataLoader 文件
222
+ const dataLoaderPath = (0, path_1.resolve)(`${projectPath}/server/dataloaders/${controller}-dataloader.ts`);
223
+ (0, utils_1.mkdirSync)(path_1.default.dirname(dataLoaderPath));
224
+ fs_1.default.writeFileSync(dataLoaderPath, dataLoaderGenerator.generate());
225
+ console.log(`🚀 已生成 DataLoader 文件: ${dataLoaderPath}`);
219
226
  // 生成多语言文件
220
227
  fileGenerator.generateI18nFiles(controller, action, fields);
221
228
  };
@@ -302,6 +309,8 @@ const createFiles = (controller, action, dictionary, fields) => {
302
309
  paths.destClientServiceController,
303
310
  paths.destClientStyledController,
304
311
  paths.destServerModulesController,
312
+ // 添加 DataLoader 目录
313
+ (0, path_1.resolve)(`${getDestPath(constants_1.destServerPath)}/dataloaders`),
305
314
  ];
306
315
  createDirectoryStructure(basePaths);
307
316
  console.log("Directory structure created");
@@ -0,0 +1,12 @@
1
+ import { BaseGenerator } from "./base-generator";
2
+ /**
3
+ * DataLoader生成器
4
+ * 自动生成对应的 DataLoader 文件
5
+ */
6
+ export declare class DataLoaderGenerator extends BaseGenerator {
7
+ generate(): string;
8
+ /**
9
+ * 生成外键 DataLoader
10
+ */
11
+ private generateForeignKeyLoaders;
12
+ }