nsgm-cli 2.1.12 → 2.1.14
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.
- package/README.md +369 -163
- package/client/components/Button.tsx +3 -5
- package/client/components/__tests__/Button.test.tsx +10 -10
- package/client/layout/index.tsx +149 -137
- package/client/redux/reducers.ts +1 -1
- package/client/redux/store.ts +2 -1
- package/client/redux/template/manage/actions.ts +77 -88
- package/client/redux/template/manage/reducers.ts +25 -37
- package/client/redux/template/manage/types.ts +1 -1
- package/client/service/template/manage.ts +20 -21
- package/client/styled/common.ts +12 -13
- package/client/styled/layout/index.ts +19 -19
- package/client/styled/template/manage.ts +14 -13
- package/client/utils/common.ts +23 -21
- package/client/utils/cookie.ts +18 -19
- package/client/utils/fetch.ts +64 -100
- package/client/utils/menu.tsx +16 -3
- package/client/utils/sso.ts +74 -84
- package/eslint.config.js +38 -1
- package/generation/README.md +25 -18
- package/generation/__tests__/example.test.js +41 -0
- package/generation/client/utils/menu.tsx +9 -2
- package/generation/env.example +3 -0
- package/generation/eslint.config.js +112 -0
- package/generation/gitignore +6 -1
- package/generation/jest.config.js +40 -0
- package/generation/package.json +25 -4
- package/jest.config.js +23 -6
- package/lib/args.js +9 -1
- package/lib/cli/app.d.ts +28 -0
- package/lib/cli/app.js +99 -0
- package/lib/cli/commands/build.d.ts +2 -0
- package/lib/cli/commands/build.js +29 -0
- package/lib/cli/commands/create.d.ts +2 -0
- package/lib/cli/commands/create.js +113 -0
- package/lib/cli/commands/delete.d.ts +3 -0
- package/lib/cli/commands/delete.js +151 -0
- package/lib/cli/commands/export.d.ts +2 -0
- package/lib/cli/commands/export.js +42 -0
- package/lib/cli/commands/help.d.ts +2 -0
- package/lib/cli/commands/help.js +42 -0
- package/lib/cli/commands/init.d.ts +2 -0
- package/lib/cli/commands/init.js +115 -0
- package/lib/cli/commands/server.d.ts +3 -0
- package/lib/cli/commands/server.js +26 -0
- package/lib/cli/commands/upgrade.d.ts +2 -0
- package/lib/cli/commands/upgrade.js +38 -0
- package/lib/cli/commands/version.d.ts +2 -0
- package/lib/cli/commands/version.js +24 -0
- package/lib/cli/index.d.ts +16 -0
- package/lib/cli/index.js +33 -0
- package/lib/cli/parser.d.ts +22 -0
- package/lib/cli/parser.js +115 -0
- package/lib/cli/registry.d.ts +33 -0
- package/lib/cli/registry.js +81 -0
- package/lib/cli/types/project.d.ts +10 -0
- package/lib/cli/types/project.js +2 -0
- package/lib/cli/types.d.ts +31 -0
- package/lib/cli/types.js +20 -0
- package/lib/cli/utils/console.d.ts +62 -0
- package/lib/cli/utils/console.js +148 -0
- package/lib/cli/utils/index.d.ts +2 -0
- package/lib/cli/utils/index.js +7 -0
- package/lib/cli/utils/prompt.d.ts +83 -0
- package/lib/cli/utils/prompt.js +368 -0
- package/lib/constants.d.ts +58 -0
- package/lib/constants.js +162 -0
- package/lib/generate.d.ts +25 -3
- package/lib/generate.js +97 -621
- package/lib/generate_create.d.ts +9 -0
- package/lib/generate_create.js +326 -0
- package/lib/generate_delete.d.ts +8 -0
- package/lib/generate_delete.js +156 -0
- package/lib/generate_init.d.ts +50 -0
- package/lib/generate_init.js +492 -0
- package/lib/generators/base-generator.d.ts +47 -0
- package/lib/generators/base-generator.js +92 -0
- package/lib/generators/generator-factory.d.ts +20 -0
- package/lib/generators/generator-factory.js +25 -0
- package/lib/generators/page-generator.d.ts +41 -0
- package/lib/generators/page-generator.js +552 -0
- package/lib/generators/resolver-generator.d.ts +12 -0
- package/lib/generators/resolver-generator.js +303 -0
- package/lib/generators/schema-generator.d.ts +7 -0
- package/lib/generators/schema-generator.js +57 -0
- package/lib/generators/service-generator.d.ts +7 -0
- package/lib/generators/service-generator.js +119 -0
- package/lib/generators/sql-generator.d.ts +8 -0
- package/lib/generators/sql-generator.js +52 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +14 -193
- package/lib/server/csrf.js +9 -16
- package/lib/server/db.js +6 -7
- package/lib/server/graphql.js +5 -6
- package/lib/server/plugins/date.js +1 -1
- package/lib/server/utils/graphql-cache.js +3 -3
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/lib/utils/project-config.d.ts +5 -0
- package/lib/utils/project-config.js +145 -0
- package/lib/utils.js +1 -1
- package/next.config.js +12 -8
- package/package.json +10 -7
- package/pages/_app.tsx +23 -28
- package/pages/_document.tsx +39 -19
- package/pages/index.tsx +84 -39
- package/pages/login.tsx +21 -21
- package/pages/template/manage.tsx +114 -89
- package/public/fonts/font-awesome.min.css +4 -0
- package/public/fonts/fontawesome-webfont.woff +0 -0
- package/public/fonts/fontawesome-webfont.woff2 +0 -0
- package/public/slbhealthcheck.html +1 -1
- package/server/apis/template.js +0 -2
- package/generation/eslintrc.js +0 -16
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResolverGenerator = void 0;
|
|
4
|
+
const base_generator_1 = require("./base-generator");
|
|
5
|
+
/**
|
|
6
|
+
* Resolver生成器
|
|
7
|
+
*/
|
|
8
|
+
class ResolverGenerator extends base_generator_1.BaseGenerator {
|
|
9
|
+
generate() {
|
|
10
|
+
const selectFields = this.fields.map((f) => f.name).join(', ');
|
|
11
|
+
const insertFields = this.getFormFields();
|
|
12
|
+
const searchableFields = this.getSearchableFields();
|
|
13
|
+
const insertFieldNames = insertFields.map((f) => f.name).join(', ');
|
|
14
|
+
const insertPlaceholders = insertFields.map(() => '?').join(', ');
|
|
15
|
+
const insertValues = insertFields.map((f) => `data.${f.name}`).join(', ');
|
|
16
|
+
const searchConditions = this.generateSearchConditions(searchableFields);
|
|
17
|
+
const validateFunctions = this.generateValidateFunctions(insertFields);
|
|
18
|
+
const updateFields = insertFields.map((f) => `${f.name} = ?`).join(', ');
|
|
19
|
+
const updateValues = insertFields.map((f) => `data.${f.name}`).join(', ');
|
|
20
|
+
return `const { executeQuery, executePaginatedQuery } = require('../../utils/common')
|
|
21
|
+
|
|
22
|
+
// 输入验证函数
|
|
23
|
+
const validatePagination = (page, pageSize) => {
|
|
24
|
+
if (page < 0 || pageSize <= 0 || pageSize > 100) {
|
|
25
|
+
throw new Error('分页参数无效');
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const validateId = (id) => {
|
|
30
|
+
if (!id || !Number.isInteger(Number(id)) || Number(id) <= 0) {
|
|
31
|
+
throw new Error('ID参数无效');
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
${validateFunctions}
|
|
36
|
+
|
|
37
|
+
module.exports = {
|
|
38
|
+
// 获取${this.controller}列表(分页)
|
|
39
|
+
${this.controller}: async ({ page = 0, pageSize = 10 }) => {
|
|
40
|
+
try {
|
|
41
|
+
const pageNum = parseInt(page, 10) || 0;
|
|
42
|
+
const pageSizeNum = parseInt(pageSize, 10) || 10;
|
|
43
|
+
|
|
44
|
+
validatePagination(pageNum, pageSizeNum);
|
|
45
|
+
|
|
46
|
+
const sql = 'SELECT ${selectFields} FROM ${this.controller} LIMIT ? OFFSET ?';
|
|
47
|
+
const countSql = 'SELECT COUNT(*) as counts FROM ${this.controller}';
|
|
48
|
+
const values = [pageSizeNum, pageNum * pageSizeNum];
|
|
49
|
+
|
|
50
|
+
console.log('执行分页查询:', { sql, values, countSql });
|
|
51
|
+
|
|
52
|
+
return await executePaginatedQuery(sql, countSql, values);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('获取${this.controller}列表失败:', error.message);
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// 根据ID获取${this.controller}
|
|
60
|
+
${this.controller}Get: async ({ id }) => {
|
|
61
|
+
try {
|
|
62
|
+
validateId(id);
|
|
63
|
+
|
|
64
|
+
const sql = 'SELECT ${selectFields} FROM ${this.controller} WHERE id = ?';
|
|
65
|
+
const values = [id];
|
|
66
|
+
|
|
67
|
+
console.log('根据ID查询${this.controller}:', { sql, values });
|
|
68
|
+
|
|
69
|
+
const results = await executeQuery(sql, values);
|
|
70
|
+
|
|
71
|
+
if (results.length === 0) {
|
|
72
|
+
throw new Error(\`ID为 \${id} 的${this.controller}不存在\`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return results[0];
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error('获取${this.controller}失败:', error.message);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
// 搜索${this.controller}(分页)
|
|
83
|
+
${this.controller}Search: async ({ page = 0, pageSize = 10, data = {} }) => {
|
|
84
|
+
try {
|
|
85
|
+
validatePagination(page, pageSize);
|
|
86
|
+
|
|
87
|
+
const values = [];
|
|
88
|
+
const countValues = [];
|
|
89
|
+
|
|
90
|
+
let whereSql = '';
|
|
91
|
+
${searchConditions}
|
|
92
|
+
|
|
93
|
+
const sql = \`SELECT ${selectFields} FROM ${this.controller} WHERE 1=1\${whereSql} LIMIT ? OFFSET ?\`;
|
|
94
|
+
const countSql = \`SELECT COUNT(*) as counts FROM ${this.controller} WHERE 1=1\${whereSql}\`;
|
|
95
|
+
|
|
96
|
+
values.push(pageSize, page * pageSize);
|
|
97
|
+
|
|
98
|
+
console.log('搜索${this.controller}:', { sql, values, countSql, countValues });
|
|
99
|
+
|
|
100
|
+
return await executePaginatedQuery(sql, countSql, values, countValues);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error('搜索${this.controller}失败:', error.message);
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
// 添加${this.controller}
|
|
108
|
+
${this.controller}Add: async ({ data }) => {
|
|
109
|
+
try {
|
|
110
|
+
${this.generateValidationCalls(insertFields)}
|
|
111
|
+
|
|
112
|
+
const sql = 'INSERT INTO ${this.controller} (${insertFieldNames}) VALUES (${insertPlaceholders})';
|
|
113
|
+
const values = [${insertValues}];
|
|
114
|
+
|
|
115
|
+
console.log('添加${this.controller}:', { sql, values });
|
|
116
|
+
|
|
117
|
+
const results = await executeQuery(sql, values);
|
|
118
|
+
return results.insertId;
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error('添加${this.controller}失败:', error.message);
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
// 批量添加${this.controller}
|
|
126
|
+
${this.controller}BatchAdd: async ({ datas }) => {
|
|
127
|
+
try {
|
|
128
|
+
if (!Array.isArray(datas) || datas.length === 0) {
|
|
129
|
+
throw new Error('批量添加数据不能为空');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 验证所有数据
|
|
133
|
+
datas.forEach(data => {
|
|
134
|
+
${this.generateBatchValidationCalls(insertFields)}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const placeholders = datas.map(() => '(${insertPlaceholders})').join(',');
|
|
138
|
+
const sql = \`INSERT INTO ${this.controller} (${insertFieldNames}) VALUES \${placeholders}\`;
|
|
139
|
+
const values = datas.flatMap(data => [${insertValues}]);
|
|
140
|
+
|
|
141
|
+
console.log('批量添加${this.controller}:', { sql, values });
|
|
142
|
+
|
|
143
|
+
const results = await executeQuery(sql, values);
|
|
144
|
+
return results.insertId;
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error('批量添加${this.controller}失败:', error.message);
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
// 更新${this.controller}
|
|
152
|
+
${this.controller}Update: async ({ id, data }) => {
|
|
153
|
+
try {
|
|
154
|
+
validateId(id);
|
|
155
|
+
|
|
156
|
+
if (!data) {
|
|
157
|
+
throw new Error('更新数据不能为空');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
${this.generateUpdateValidationCalls(insertFields)}
|
|
161
|
+
|
|
162
|
+
const sql = 'UPDATE ${this.controller} SET ${updateFields} WHERE id = ?';
|
|
163
|
+
const values = [${updateValues}, id];
|
|
164
|
+
|
|
165
|
+
console.log('更新${this.controller}:', { sql, values });
|
|
166
|
+
|
|
167
|
+
const results = await executeQuery(sql, values);
|
|
168
|
+
|
|
169
|
+
if (results.affectedRows === 0) {
|
|
170
|
+
throw new Error(\`ID为 \${id} 的${this.controller}不存在\`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return true;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error('更新${this.controller}失败:', error.message);
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
// 删除${this.controller}
|
|
181
|
+
${this.controller}Delete: async ({ id }) => {
|
|
182
|
+
try {
|
|
183
|
+
validateId(id);
|
|
184
|
+
|
|
185
|
+
const sql = 'DELETE FROM ${this.controller} WHERE id = ?';
|
|
186
|
+
const values = [id];
|
|
187
|
+
|
|
188
|
+
console.log('删除${this.controller}:', { sql, values });
|
|
189
|
+
|
|
190
|
+
const results = await executeQuery(sql, values);
|
|
191
|
+
|
|
192
|
+
if (results.affectedRows === 0) {
|
|
193
|
+
throw new Error(\`ID为 \${id} 的${this.controller}不存在\`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return true;
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error('删除${this.controller}失败:', error.message);
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
// 批量删除${this.controller}
|
|
204
|
+
${this.controller}BatchDelete: async ({ ids }) => {
|
|
205
|
+
try {
|
|
206
|
+
if (!Array.isArray(ids) || ids.length === 0) {
|
|
207
|
+
throw new Error('批量删除的ID列表不能为空');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
ids.forEach(id => validateId(id));
|
|
211
|
+
|
|
212
|
+
const placeholders = ids.map(() => '?').join(',');
|
|
213
|
+
const sql = \`DELETE FROM ${this.controller} WHERE id IN (\${placeholders})\`;
|
|
214
|
+
|
|
215
|
+
console.log('批量删除${this.controller}:', { sql, values: ids });
|
|
216
|
+
|
|
217
|
+
const results = await executeQuery(sql, ids);
|
|
218
|
+
|
|
219
|
+
if (results.affectedRows === 0) {
|
|
220
|
+
throw new Error('没有找到要删除的${this.controller}');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return true;
|
|
224
|
+
} catch (error) {
|
|
225
|
+
console.error('批量删除${this.controller}失败:', error.message);
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}`;
|
|
230
|
+
}
|
|
231
|
+
generateSearchConditions(searchableFields) {
|
|
232
|
+
if (searchableFields.length === 0)
|
|
233
|
+
return '';
|
|
234
|
+
const conditions = searchableFields.map((field) => {
|
|
235
|
+
if (field.type === 'varchar' || field.type === 'text') {
|
|
236
|
+
return ` if (data.${field.name} && data.${field.name}.trim() !== '') {
|
|
237
|
+
whereSql += ' AND ${field.name} LIKE ?';
|
|
238
|
+
const ${field.name}Pattern = \`%\${data.${field.name}.trim()}%\`;
|
|
239
|
+
values.push(${field.name}Pattern);
|
|
240
|
+
countValues.push(${field.name}Pattern);
|
|
241
|
+
}`;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
return ` if (data.${field.name} !== undefined && data.${field.name} !== null) {
|
|
245
|
+
whereSql += ' AND ${field.name} = ?';
|
|
246
|
+
values.push(data.${field.name});
|
|
247
|
+
countValues.push(data.${field.name});
|
|
248
|
+
}`;
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
return conditions.join('\n\n');
|
|
252
|
+
}
|
|
253
|
+
generateValidateFunctions(insertFields) {
|
|
254
|
+
return insertFields
|
|
255
|
+
.filter((f) => f.required)
|
|
256
|
+
.map((field) => {
|
|
257
|
+
const capitalizedName = field.name.charAt(0).toUpperCase() + field.name.slice(1);
|
|
258
|
+
if (field.type === 'varchar' || field.type === 'text') {
|
|
259
|
+
return `const validate${capitalizedName} = (${field.name}) => {
|
|
260
|
+
if (!${field.name} || typeof ${field.name} !== 'string' || ${field.name}.trim().length === 0) {
|
|
261
|
+
throw new Error('${field.comment || field.name}参数无效');
|
|
262
|
+
}
|
|
263
|
+
};`;
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
return `const validate${capitalizedName} = (${field.name}) => {
|
|
267
|
+
if (${field.name} === undefined || ${field.name} === null) {
|
|
268
|
+
throw new Error('${field.comment || field.name}参数无效');
|
|
269
|
+
}
|
|
270
|
+
};`;
|
|
271
|
+
}
|
|
272
|
+
})
|
|
273
|
+
.join('\n\n');
|
|
274
|
+
}
|
|
275
|
+
generateValidationCalls(insertFields) {
|
|
276
|
+
return insertFields
|
|
277
|
+
.filter((f) => f.required)
|
|
278
|
+
.map((f) => {
|
|
279
|
+
const capitalizedName = f.name.charAt(0).toUpperCase() + f.name.slice(1);
|
|
280
|
+
return ` validate${capitalizedName}(data.${f.name});`;
|
|
281
|
+
})
|
|
282
|
+
.join('\n');
|
|
283
|
+
}
|
|
284
|
+
generateBatchValidationCalls(insertFields) {
|
|
285
|
+
return insertFields
|
|
286
|
+
.filter((f) => f.required)
|
|
287
|
+
.map((f) => {
|
|
288
|
+
const capitalizedName = f.name.charAt(0).toUpperCase() + f.name.slice(1);
|
|
289
|
+
return ` validate${capitalizedName}(data.${f.name});`;
|
|
290
|
+
})
|
|
291
|
+
.join('\n');
|
|
292
|
+
}
|
|
293
|
+
generateUpdateValidationCalls(insertFields) {
|
|
294
|
+
return insertFields
|
|
295
|
+
.filter((f) => f.required)
|
|
296
|
+
.map((f) => {
|
|
297
|
+
const capitalizedName = f.name.charAt(0).toUpperCase() + f.name.slice(1);
|
|
298
|
+
return ` if (data.${f.name} !== undefined) validate${capitalizedName}(data.${f.name});`;
|
|
299
|
+
})
|
|
300
|
+
.join('\n');
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
exports.ResolverGenerator = ResolverGenerator;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SchemaGenerator = void 0;
|
|
4
|
+
const base_generator_1 = require("./base-generator");
|
|
5
|
+
/**
|
|
6
|
+
* GraphQL Schema生成器
|
|
7
|
+
*/
|
|
8
|
+
class SchemaGenerator extends base_generator_1.BaseGenerator {
|
|
9
|
+
generate() {
|
|
10
|
+
const capitalizedTypeName = this.getCapitalizedController();
|
|
11
|
+
const pluralTypeName = `${capitalizedTypeName}s`;
|
|
12
|
+
const typeFields = this.getNonSystemFields()
|
|
13
|
+
.map((field) => ` ${field.name}: ${this.getGraphQLType(field.type)}`)
|
|
14
|
+
.join('\n');
|
|
15
|
+
const inputFields = this.getFormFields()
|
|
16
|
+
.map((field) => ` ${field.name}: ${this.getGraphQLType(field.type)}`)
|
|
17
|
+
.join('\n');
|
|
18
|
+
const searchableFields = this.getSearchableFields();
|
|
19
|
+
const searchFields = searchableFields.length > 0
|
|
20
|
+
? searchableFields.map((field) => ` ${field.name}: ${this.getGraphQLType(field.type)}`).join('\n')
|
|
21
|
+
: ' name: String';
|
|
22
|
+
return `module.exports = {
|
|
23
|
+
query: \`
|
|
24
|
+
${this.controller}(page: Int, pageSize: Int): ${pluralTypeName}
|
|
25
|
+
${this.controller}Get(id: Int): ${capitalizedTypeName}
|
|
26
|
+
${this.controller}Search(page: Int, pageSize: Int, data: ${capitalizedTypeName}SearchInput): ${pluralTypeName}
|
|
27
|
+
\`,
|
|
28
|
+
mutation: \`
|
|
29
|
+
${this.controller}Add(data: ${capitalizedTypeName}AddInput): Int
|
|
30
|
+
${this.controller}BatchAdd(datas: [${capitalizedTypeName}AddInput]): Int
|
|
31
|
+
${this.controller}Update(id: Int, data: ${capitalizedTypeName}AddInput): Boolean
|
|
32
|
+
${this.controller}Delete(id: Int): Boolean
|
|
33
|
+
${this.controller}BatchDelete(ids: [Int]): Boolean
|
|
34
|
+
\`,
|
|
35
|
+
subscription: \`\`,
|
|
36
|
+
type: \`
|
|
37
|
+
type ${capitalizedTypeName} {
|
|
38
|
+
${typeFields}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type ${pluralTypeName} {
|
|
42
|
+
totalCounts: Int
|
|
43
|
+
items: [${capitalizedTypeName}]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
input ${capitalizedTypeName}AddInput {
|
|
47
|
+
${inputFields}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
input ${capitalizedTypeName}SearchInput {
|
|
51
|
+
${searchFields}
|
|
52
|
+
}
|
|
53
|
+
\`
|
|
54
|
+
}`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.SchemaGenerator = SchemaGenerator;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServiceGenerator = void 0;
|
|
4
|
+
const base_generator_1 = require("./base-generator");
|
|
5
|
+
/**
|
|
6
|
+
* 客户端服务生成器
|
|
7
|
+
*/
|
|
8
|
+
class ServiceGenerator extends base_generator_1.BaseGenerator {
|
|
9
|
+
generate() {
|
|
10
|
+
const capitalizedTypeName = this.getCapitalizedController();
|
|
11
|
+
// 排除系统字段 create_date 和 update_date
|
|
12
|
+
const selectFields = this.fields
|
|
13
|
+
.filter((f) => !['create_date', 'update_date'].includes(f.name))
|
|
14
|
+
.map((f) => f.name)
|
|
15
|
+
.join(' ');
|
|
16
|
+
const inputFields = this.getFormFields();
|
|
17
|
+
const searchFields = this.getSearchableFields();
|
|
18
|
+
const dataObject = inputFields.map((field) => ` ${field.name}`).join(',\n');
|
|
19
|
+
const searchDataObject = searchFields.map((field) => ` ${field.name}`).join(',\n');
|
|
20
|
+
return `import { getLocalGraphql } from '@/utils/fetch'
|
|
21
|
+
import _ from 'lodash'
|
|
22
|
+
|
|
23
|
+
export const get${capitalizedTypeName}Service = (page = 0, pageSize = 10) => {
|
|
24
|
+
const get${capitalizedTypeName}Query = \`query ($page: Int, $pageSize: Int) { ${this.controller}(page: $page, pageSize: $pageSize) {
|
|
25
|
+
totalCounts items {
|
|
26
|
+
${selectFields}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}\`
|
|
30
|
+
|
|
31
|
+
return getLocalGraphql(get${capitalizedTypeName}Query, {
|
|
32
|
+
page,
|
|
33
|
+
pageSize
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const search${capitalizedTypeName}ByIdService = (id: number) => {
|
|
38
|
+
const search${capitalizedTypeName}ByIdQuery = \`query ($id: Int) { ${this.controller}Get(id: $id){
|
|
39
|
+
${selectFields}
|
|
40
|
+
}
|
|
41
|
+
}\`
|
|
42
|
+
|
|
43
|
+
return getLocalGraphql(search${capitalizedTypeName}ByIdQuery, {
|
|
44
|
+
id
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const search${capitalizedTypeName}Service = (page = 0, pageSize = 10, data: any) => {
|
|
49
|
+
const { ${searchFields.map((f) => f.name).join(', ')} } = data
|
|
50
|
+
|
|
51
|
+
const search${capitalizedTypeName}Query = \`query ($page: Int, $pageSize: Int, $data: ${capitalizedTypeName}SearchInput) {
|
|
52
|
+
${this.controller}Search(page: $page, pageSize: $pageSize, data: $data) {
|
|
53
|
+
totalCounts items {
|
|
54
|
+
${selectFields}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}\`
|
|
58
|
+
|
|
59
|
+
return getLocalGraphql(search${capitalizedTypeName}Query, {
|
|
60
|
+
page,
|
|
61
|
+
pageSize,
|
|
62
|
+
data: {
|
|
63
|
+
${searchDataObject}
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const add${capitalizedTypeName}Service = (data: any) => {
|
|
69
|
+
const { ${inputFields.map((f) => f.name).join(', ')} } = data
|
|
70
|
+
|
|
71
|
+
const add${capitalizedTypeName}Query = \`mutation ($data: ${capitalizedTypeName}AddInput) { ${this.controller}Add(data: $data) }\`
|
|
72
|
+
|
|
73
|
+
return getLocalGraphql(add${capitalizedTypeName}Query, {
|
|
74
|
+
data: {
|
|
75
|
+
${dataObject}
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const update${capitalizedTypeName}Service = (id: number, data: any) => {
|
|
81
|
+
const { ${inputFields.map((f) => f.name).join(', ')} } = data
|
|
82
|
+
|
|
83
|
+
const update${capitalizedTypeName}Query = \`mutation ($id: Int, $data: ${capitalizedTypeName}AddInput) { ${this.controller}Update(id: $id, data: $data) }\`
|
|
84
|
+
|
|
85
|
+
return getLocalGraphql(update${capitalizedTypeName}Query, {
|
|
86
|
+
id,
|
|
87
|
+
data: {
|
|
88
|
+
${dataObject}
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const delete${capitalizedTypeName}Service = (id: number) => {
|
|
94
|
+
const delete${capitalizedTypeName}Query = \`mutation ($id: Int) { ${this.controller}Delete(id: $id) }\`
|
|
95
|
+
|
|
96
|
+
return getLocalGraphql(delete${capitalizedTypeName}Query, {
|
|
97
|
+
id
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const batchAdd${capitalizedTypeName}Service = (datas: any) => {
|
|
102
|
+
const batchAdd${capitalizedTypeName}Query = \`mutation ($datas: [${capitalizedTypeName}AddInput]) { ${this.controller}BatchAdd(datas: $datas) }\`
|
|
103
|
+
|
|
104
|
+
return getLocalGraphql(batchAdd${capitalizedTypeName}Query, {
|
|
105
|
+
datas
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const batchDelete${capitalizedTypeName}Service = (ids: any) => {
|
|
110
|
+
const batchDelete${capitalizedTypeName}Query = \`mutation ($ids: [Int]) { ${this.controller}BatchDelete(ids: $ids) }\`
|
|
111
|
+
|
|
112
|
+
return getLocalGraphql(batchDelete${capitalizedTypeName}Query, {
|
|
113
|
+
ids
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.ServiceGenerator = ServiceGenerator;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SQLGenerator = void 0;
|
|
4
|
+
const base_generator_1 = require("./base-generator");
|
|
5
|
+
/**
|
|
6
|
+
* SQL生成器
|
|
7
|
+
* 专门负责生成数据库表结构
|
|
8
|
+
*/
|
|
9
|
+
class SQLGenerator extends base_generator_1.BaseGenerator {
|
|
10
|
+
generate() {
|
|
11
|
+
const fieldDefinitions = this.fields.map((field) => {
|
|
12
|
+
let sql = ` \`${field.name}\``;
|
|
13
|
+
// 数据类型
|
|
14
|
+
sql += ` ${this.getSQLType(field)}`;
|
|
15
|
+
// 是否必填
|
|
16
|
+
if (field.required && !field.isAutoIncrement) {
|
|
17
|
+
sql += ' NOT NULL';
|
|
18
|
+
}
|
|
19
|
+
else if (!field.required) {
|
|
20
|
+
sql += ' DEFAULT NULL';
|
|
21
|
+
}
|
|
22
|
+
// 自增
|
|
23
|
+
if (field.isAutoIncrement) {
|
|
24
|
+
sql += ' AUTO_INCREMENT';
|
|
25
|
+
}
|
|
26
|
+
// 默认值
|
|
27
|
+
if (field.type === 'timestamp' && field.name === 'create_date') {
|
|
28
|
+
sql += ' DEFAULT CURRENT_TIMESTAMP(3)';
|
|
29
|
+
}
|
|
30
|
+
else if (field.type === 'timestamp' && field.name === 'update_date') {
|
|
31
|
+
sql += ' DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)';
|
|
32
|
+
}
|
|
33
|
+
else if (field.type === 'varchar' && field.name !== 'id' && !field.required) {
|
|
34
|
+
sql += " DEFAULT ''";
|
|
35
|
+
}
|
|
36
|
+
// 注释
|
|
37
|
+
if (field.comment) {
|
|
38
|
+
sql += ` COMMENT '${field.comment}'`;
|
|
39
|
+
}
|
|
40
|
+
return sql;
|
|
41
|
+
});
|
|
42
|
+
const primaryKeyField = this.fields.find((f) => f.isPrimaryKey);
|
|
43
|
+
const primaryKey = primaryKeyField ? ` PRIMARY KEY (\`${primaryKeyField.name}\`)` : '';
|
|
44
|
+
return `use crm_demo;
|
|
45
|
+
|
|
46
|
+
CREATE TABLE \`${this.controller}\` (
|
|
47
|
+
${fieldDefinitions.join(',\n')},
|
|
48
|
+
${primaryKey}
|
|
49
|
+
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.SQLGenerator = SQLGenerator;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
export declare const startExpress: (options: any, callback?: () => void) => void;
|
|
2
|
+
export declare const startExpress: (options: any, callback?: () => void, command?: string) => void;
|