nsgm-cli 2.1.30 → 2.1.32
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/client/layout/index.tsx +13 -2
- package/client/redux/store.ts +10 -1
- package/client/styled/layout/index.ts +3 -1
- package/client/utils/common.ts +28 -8
- package/client/utils/fetch.ts +9 -3
- package/client/utils/sso.ts +8 -9
- package/lib/cli/commands/delete-config.js +122 -3
- package/lib/generate_init.js +13 -0
- package/lib/generators/page-generator.js +24 -6
- package/lib/generators/sql-generator.js +4 -2
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/pages/_document.tsx +1 -1
- package/server/sql/template.sql +3 -1
package/client/layout/index.tsx
CHANGED
|
@@ -32,8 +32,17 @@ interface MenuItem {
|
|
|
32
32
|
subMenus?: SubMenuItem[];
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
//
|
|
36
|
-
const
|
|
35
|
+
// 安全获取 prefix 的辅助函数
|
|
36
|
+
const getPrefix = () => {
|
|
37
|
+
try {
|
|
38
|
+
if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_PREFIX) {
|
|
39
|
+
return process.env.NEXT_PUBLIC_PREFIX;
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// 浏览器环境使用空字符串
|
|
43
|
+
}
|
|
44
|
+
return "";
|
|
45
|
+
};
|
|
37
46
|
|
|
38
47
|
const getLocationKey = () => {
|
|
39
48
|
const result = {
|
|
@@ -53,6 +62,7 @@ const getLocationKey = () => {
|
|
|
53
62
|
const locationIndex = locationStr.indexOf("/");
|
|
54
63
|
locationStr = locationStr.substring(locationIndex);
|
|
55
64
|
|
|
65
|
+
const prefix = getPrefix();
|
|
56
66
|
if (prefix && locationStr.indexOf(prefix) !== -1) {
|
|
57
67
|
locationStr = locationStr.split(prefix)[1];
|
|
58
68
|
}
|
|
@@ -92,6 +102,7 @@ const getLocationKey = () => {
|
|
|
92
102
|
|
|
93
103
|
const routerPush = (router: any, url: string) => {
|
|
94
104
|
if (router && url && typeof window !== "undefined") {
|
|
105
|
+
const prefix = getPrefix();
|
|
95
106
|
if (prefix && url.indexOf(prefix) === -1) {
|
|
96
107
|
url = prefix + url;
|
|
97
108
|
}
|
package/client/redux/store.ts
CHANGED
|
@@ -29,11 +29,20 @@ const tempStore = configureStore({
|
|
|
29
29
|
|
|
30
30
|
export type AppDispatch = typeof tempStore.dispatch;
|
|
31
31
|
|
|
32
|
+
// 安全获取 NODE_ENV
|
|
33
|
+
const isDevToolsEnabled = () => {
|
|
34
|
+
try {
|
|
35
|
+
return typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production";
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
32
41
|
function initStore(initialState?: any): EnhancedStore {
|
|
33
42
|
return configureStore({
|
|
34
43
|
reducer: combineReducer,
|
|
35
44
|
preloadedState: initialState,
|
|
36
|
-
devTools:
|
|
45
|
+
devTools: isDevToolsEnabled(),
|
|
37
46
|
middleware: (getDefaultMiddleware) =>
|
|
38
47
|
getDefaultMiddleware({
|
|
39
48
|
serializableCheck: {
|
|
@@ -54,7 +54,9 @@ export const SideMenu = styled(Menu)`
|
|
|
54
54
|
padding: 8px 0;
|
|
55
55
|
`;
|
|
56
56
|
|
|
57
|
-
export const ContentLayout = styled(Layout)
|
|
57
|
+
export const ContentLayout = styled(Layout).withConfig({
|
|
58
|
+
shouldForwardProp: (prop) => prop !== "collapsed",
|
|
59
|
+
})<{ collapsed?: boolean }>`
|
|
58
60
|
display: flex;
|
|
59
61
|
flex-direction: column;
|
|
60
62
|
flex: 1;
|
package/client/utils/common.ts
CHANGED
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
import _ from "lodash";
|
|
2
2
|
|
|
3
3
|
export const getLocalEnv = () => {
|
|
4
|
-
|
|
5
|
-
env =
|
|
6
|
-
|
|
4
|
+
// 安全地访问 process.env,避免在浏览器中直接访问 process 对象
|
|
5
|
+
let env = "uat";
|
|
6
|
+
try {
|
|
7
|
+
if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_ENV) {
|
|
8
|
+
env = process.env.NEXT_PUBLIC_ENV;
|
|
9
|
+
}
|
|
10
|
+
} catch {
|
|
11
|
+
// 在浏览器环境中 process 可能未定义,使用默认值
|
|
12
|
+
}
|
|
13
|
+
return env.toLowerCase();
|
|
7
14
|
};
|
|
8
15
|
|
|
9
16
|
export const getLocalApiPrefix = () => {
|
|
10
|
-
|
|
11
|
-
let
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
// 安全地访问 process.env
|
|
18
|
+
let protocol = "http";
|
|
19
|
+
let host = "localhost";
|
|
20
|
+
let port = "3000";
|
|
21
|
+
let prefix = "";
|
|
22
|
+
let isExport = false;
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
if (typeof process !== "undefined" && process.env) {
|
|
26
|
+
protocol = process.env.NEXT_PUBLIC_PROTOCOL || protocol;
|
|
27
|
+
host = process.env.NEXT_PUBLIC_HOST || host;
|
|
28
|
+
port = process.env.NEXT_PUBLIC_PORT || port;
|
|
29
|
+
prefix = process.env.NEXT_PUBLIC_PREFIX || "";
|
|
30
|
+
isExport = process.env.NEXT_PUBLIC_IS_EXPORT === "true";
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// 在浏览器环境中 process 可能未定义,使用默认值
|
|
34
|
+
}
|
|
15
35
|
|
|
16
36
|
let localApiPrefix = "";
|
|
17
37
|
|
package/client/utils/fetch.ts
CHANGED
|
@@ -32,9 +32,15 @@ export const GRAPHQL_CONFIG = {
|
|
|
32
32
|
cookieName: "csrfToken",
|
|
33
33
|
},
|
|
34
34
|
|
|
35
|
-
// 开发模式配置
|
|
36
|
-
development
|
|
37
|
-
enableDebugLogs
|
|
35
|
+
// 开发模式配置 - 使用 getter 延迟访问 process
|
|
36
|
+
get development() {
|
|
37
|
+
let enableDebugLogs = false;
|
|
38
|
+
try {
|
|
39
|
+
enableDebugLogs = typeof process !== "undefined" && process.env && process.env.NODE_ENV === "development";
|
|
40
|
+
} catch {
|
|
41
|
+
// 浏览器环境使用默认值
|
|
42
|
+
}
|
|
43
|
+
return { enableDebugLogs };
|
|
38
44
|
},
|
|
39
45
|
};
|
|
40
46
|
|
package/client/utils/sso.ts
CHANGED
|
@@ -3,10 +3,9 @@ import { setCookie, getCookie, delCookie } from "./cookie";
|
|
|
3
3
|
import { getUrlParamByKey, getLocalApiPrefix, getLocalEnv, handleXSS } from "./common";
|
|
4
4
|
import _ from "lodash";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const LOGIN_COOKIE_USER = `${env}_nsgm_user`;
|
|
6
|
+
// 延迟初始化 cookie 名称,避免在模块加载时访问 process
|
|
7
|
+
const getLoginCookieId = () => `${getLocalEnv()}_cas_nsgm`;
|
|
8
|
+
const getLoginCookieUser = () => `${getLocalEnv()}_nsgm_user`;
|
|
10
9
|
|
|
11
10
|
const getPrincipalUrl = () => {
|
|
12
11
|
const url = `${getLocalApiPrefix()}/rest/sso/sessionCheck`;
|
|
@@ -67,8 +66,8 @@ const handleLocationHref = () => {
|
|
|
67
66
|
};
|
|
68
67
|
|
|
69
68
|
const jumpToLogin = () => {
|
|
70
|
-
delCookie(
|
|
71
|
-
delCookie(
|
|
69
|
+
delCookie(getLoginCookieId());
|
|
70
|
+
delCookie(getLoginCookieUser());
|
|
72
71
|
|
|
73
72
|
if (typeof window !== "undefined") {
|
|
74
73
|
window.location.href = `${window.location.origin}/login`;
|
|
@@ -115,7 +114,7 @@ const storeLoginUser = (userAttr: any, callback: any) => {
|
|
|
115
114
|
"name",
|
|
116
115
|
"sn",
|
|
117
116
|
]);
|
|
118
|
-
setCookie(
|
|
117
|
+
setCookie(getLoginCookieUser(), user, null);
|
|
119
118
|
callback?.(JSON.parse(user));
|
|
120
119
|
} else {
|
|
121
120
|
callback?.();
|
|
@@ -124,7 +123,7 @@ const storeLoginUser = (userAttr: any, callback: any) => {
|
|
|
124
123
|
|
|
125
124
|
const storeLogin = (cookie: any, cookieExpire: any, userAttr: any, callback: any) => {
|
|
126
125
|
if (cookie) {
|
|
127
|
-
setCookie(
|
|
126
|
+
setCookie(getLoginCookieId(), cookie, cookieExpire);
|
|
128
127
|
}
|
|
129
128
|
|
|
130
129
|
storeLoginUser(userAttr, callback);
|
|
@@ -166,7 +165,7 @@ const validateLogin = (ticket: string, name = "", callback: any) => {
|
|
|
166
165
|
};
|
|
167
166
|
|
|
168
167
|
export const login = (callback: any) => {
|
|
169
|
-
const cookieLoginValue = getCookie(
|
|
168
|
+
const cookieLoginValue = getCookie(getLoginCookieId());
|
|
170
169
|
|
|
171
170
|
if (typeof window !== "undefined") {
|
|
172
171
|
const locationHref = window.location.href;
|
|
@@ -5,8 +5,117 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.deleteConfigCommand = void 0;
|
|
7
7
|
const utils_1 = require("../utils");
|
|
8
|
-
const generate_1 = require("../../generate");
|
|
9
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const shelljs_1 = __importDefault(require("shelljs"));
|
|
11
|
+
const utils_2 = require("../../utils");
|
|
12
|
+
const constants_1 = require("../../constants");
|
|
13
|
+
/**
|
|
14
|
+
* 生成删除路径
|
|
15
|
+
*/
|
|
16
|
+
const generateDeletePaths = (controller, dictionary) => {
|
|
17
|
+
const basePath = dictionary || process.cwd();
|
|
18
|
+
return {
|
|
19
|
+
destPagesController: path_1.default.join(basePath, "pages", controller),
|
|
20
|
+
destClientReduxController: path_1.default.join(basePath, "client", "redux", controller),
|
|
21
|
+
destClientServiceController: path_1.default.join(basePath, "client", "service", controller),
|
|
22
|
+
destClientStyledController: path_1.default.join(basePath, "client", "styled", controller),
|
|
23
|
+
destServerModulesController: path_1.default.join(basePath, "server", "modules", controller),
|
|
24
|
+
destServerApisController: path_1.default.join(basePath, "server", "apis", `${controller}.js`),
|
|
25
|
+
destServerSqlController: path_1.default.join(basePath, "server", "sql", `${controller}.sql`),
|
|
26
|
+
destServerDataLoader: path_1.default.join(basePath, "server", "dataloaders", `${controller}-dataloader.ts`),
|
|
27
|
+
destClientReduxReducersAllPath: path_1.default.join(basePath, "client", "redux", "reducers.ts"),
|
|
28
|
+
destServerRestPath: path_1.default.join(basePath, "server", "rest.js"),
|
|
29
|
+
destClientUtilsMenuPath: path_1.default.join(basePath, "client", "utils", "menu.tsx"),
|
|
30
|
+
destI18nZhCN: path_1.default.join(basePath, "public", "locales", "zh-CN", `${controller}.json`),
|
|
31
|
+
destI18nEnUS: path_1.default.join(basePath, "public", "locales", "en-US", `${controller}.json`),
|
|
32
|
+
destI18nJaJP: path_1.default.join(basePath, "public", "locales", "ja-JP", `${controller}.json`),
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* 删除文件和目录
|
|
37
|
+
*/
|
|
38
|
+
const deleteModuleFiles = (paths) => {
|
|
39
|
+
const directoriesToDelete = [
|
|
40
|
+
paths.destPagesController,
|
|
41
|
+
paths.destClientReduxController,
|
|
42
|
+
paths.destClientServiceController,
|
|
43
|
+
paths.destClientStyledController,
|
|
44
|
+
paths.destServerModulesController,
|
|
45
|
+
];
|
|
46
|
+
const filesToDelete = [
|
|
47
|
+
paths.destServerApisController,
|
|
48
|
+
paths.destServerSqlController,
|
|
49
|
+
paths.destServerDataLoader,
|
|
50
|
+
paths.destI18nZhCN,
|
|
51
|
+
paths.destI18nEnUS,
|
|
52
|
+
paths.destI18nJaJP,
|
|
53
|
+
];
|
|
54
|
+
directoriesToDelete.forEach((dir) => (0, utils_2.rmdirSync)(dir));
|
|
55
|
+
filesToDelete.forEach((file) => (0, utils_2.rmFileSync)(file));
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* 清理 reducers 配置
|
|
59
|
+
*/
|
|
60
|
+
const cleanupReducers = (controller, reducersPath) => {
|
|
61
|
+
// 删除 import 语句
|
|
62
|
+
shelljs_1.default.sed("-i", new RegExp(`^.*import.*from.*['"].*\\/${controller}\\/.*['"].*$`, "gm"), "", reducersPath);
|
|
63
|
+
// 删除 export 对象中的属性行
|
|
64
|
+
shelljs_1.default.sed("-i", new RegExp(`^\\s*${controller}\\w*:\\s*${controller}\\w*Reducer,?\\s*$`, "gm"), "", reducersPath);
|
|
65
|
+
// 修复连续逗号
|
|
66
|
+
shelljs_1.default.sed("-i", /,,+/g, ",", reducersPath);
|
|
67
|
+
// 修复对象末尾的逗号
|
|
68
|
+
shelljs_1.default.sed("-i", /,(\s*\n\s*\})/, "$1", reducersPath);
|
|
69
|
+
// 移除空对象中的逗号
|
|
70
|
+
shelljs_1.default.sed("-i", /\{\s*,\s*\}/, "{}", reducersPath);
|
|
71
|
+
// 标准化空行
|
|
72
|
+
shelljs_1.default.sed("-i", /\n\s*\n\s*\n/g, "\n\n", reducersPath);
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* 清理菜单配置
|
|
76
|
+
*/
|
|
77
|
+
const cleanupMenu = (controller, menuPath) => {
|
|
78
|
+
// 删除所有匹配的菜单项
|
|
79
|
+
shelljs_1.default.sed("-i", new RegExp(`,?\\s*\\{\\s*//\\s*${controller}_\\w+_start[\\s\\S]*?//\\s*${controller}_\\w+_end\\s*\\n\\s*\\}\\s*,?`, "gm"), "", menuPath);
|
|
80
|
+
// 修复连续逗号
|
|
81
|
+
shelljs_1.default.sed("-i", /,,+/g, ",", menuPath);
|
|
82
|
+
// 修复对象前多余的逗号
|
|
83
|
+
shelljs_1.default.sed("-i", /\n\s*,\s*\{/gm, "\n {", menuPath);
|
|
84
|
+
// 修复数组中缺失的逗号
|
|
85
|
+
shelljs_1.default.sed("-i", /(\})\s*(\{)/gm, "$1,\n $2", menuPath);
|
|
86
|
+
// 清理缩进问题
|
|
87
|
+
shelljs_1.default.sed("-i", /^[ ]{0,2}\/\*\{/gm, " /*{", menuPath);
|
|
88
|
+
shelljs_1.default.sed("-i", /^[ ]{0,4}key:/gm, " key:", menuPath);
|
|
89
|
+
shelljs_1.default.sed("-i", /^[ ]{0,4}text:/gm, " text:", menuPath);
|
|
90
|
+
shelljs_1.default.sed("-i", /^[ ]{0,4}url:/gm, " url:", menuPath);
|
|
91
|
+
shelljs_1.default.sed("-i", /^[ ]{0,4}icon:/gm, " icon:", menuPath);
|
|
92
|
+
shelljs_1.default.sed("-i", /^[ ]{0,4}subMenus:/gm, " subMenus:", menuPath);
|
|
93
|
+
shelljs_1.default.sed("-i", /^[ ]{0,2}\}\*\//gm, " }*/", menuPath);
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* 清理 REST API 配置
|
|
97
|
+
*/
|
|
98
|
+
const cleanupRestApi = (controller, restPath) => {
|
|
99
|
+
// 删除 require 语句
|
|
100
|
+
shelljs_1.default.sed("-i", new RegExp(`^const\\s+${controller}\\s*=\\s*require.*${controller}['"].*$`, "gm"), "", restPath);
|
|
101
|
+
// 删除 router.use 语句
|
|
102
|
+
shelljs_1.default.sed("-i", new RegExp(`^router\\.use\\(['"]\\/${controller}['"]\\s*,\\s*${controller}\\)\\s*$`, "gm"), "", restPath);
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* 删除数据库表
|
|
106
|
+
*/
|
|
107
|
+
const dropDatabaseTable = (controller) => {
|
|
108
|
+
try {
|
|
109
|
+
// 创建临时的 DROP TABLE SQL
|
|
110
|
+
const dropSql = `DROP TABLE IF EXISTS \`${controller}\`;`;
|
|
111
|
+
const mysqlCommand = `mysql -u${constants_1.mysqlUser} -p${constants_1.mysqlPassword} -h${constants_1.mysqlHost} -P${constants_1.mysqlPort} -e "${dropSql}"`;
|
|
112
|
+
shelljs_1.default.exec(mysqlCommand);
|
|
113
|
+
utils_1.Console.info(`已删除数据库表: ${controller}`);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
utils_1.Console.error(`删除数据库表失败: ${error}`);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
10
119
|
/**
|
|
11
120
|
* 从配置文件删除命令
|
|
12
121
|
*/
|
|
@@ -147,8 +256,18 @@ exports.deleteConfigCommand = {
|
|
|
147
256
|
try {
|
|
148
257
|
const spinner = utils_1.Console.spinner("正在删除文件...", "red");
|
|
149
258
|
spinner.start();
|
|
150
|
-
//
|
|
151
|
-
|
|
259
|
+
// 生成删除路径
|
|
260
|
+
const paths = generateDeletePaths(module.controller, module.dictionary);
|
|
261
|
+
// 1. 删除文件和目录
|
|
262
|
+
deleteModuleFiles(paths);
|
|
263
|
+
// 2. 清理配置文件
|
|
264
|
+
cleanupReducers(module.controller, paths.destClientReduxReducersAllPath);
|
|
265
|
+
cleanupRestApi(module.controller, paths.destServerRestPath);
|
|
266
|
+
cleanupMenu(module.controller, paths.destClientUtilsMenuPath);
|
|
267
|
+
// 3. 删除数据库表(如果指定)
|
|
268
|
+
if (options.db) {
|
|
269
|
+
dropDatabaseTable(module.controller);
|
|
270
|
+
}
|
|
152
271
|
spinner.succeed("删除完成!");
|
|
153
272
|
successCount++;
|
|
154
273
|
utils_1.Console.newLine();
|
package/lib/generate_init.js
CHANGED
|
@@ -32,9 +32,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.initConfigFiles = exports.initTestFiles = exports.initTypesFiles = exports.initRootFiles = exports.initScriptsFiles = exports.initPublicFiles = exports.initServerFiles = exports.initPagesFiles = exports.initClientFiles = void 0;
|
|
37
40
|
const path_1 = __importStar(require("path"));
|
|
41
|
+
const shelljs_1 = __importDefault(require("shelljs"));
|
|
38
42
|
const constants_1 = require("./constants");
|
|
39
43
|
const utils_1 = require("./utils");
|
|
40
44
|
const fs_1 = require("fs");
|
|
@@ -549,6 +553,15 @@ const initRootFiles = (dictionary, newDestFolder) => {
|
|
|
549
553
|
];
|
|
550
554
|
// 3. 复制文件
|
|
551
555
|
copyMultipleFiles(fileMappings);
|
|
556
|
+
// 4. 替换 mysql.config.js 中的数据库名称为项目名称(中横线替换为下划线)
|
|
557
|
+
const destMysqlConfigPath = (0, path_1.resolve)(baseDestPath + ROOT_FILES.mysqlConfig);
|
|
558
|
+
if ((0, fs_1.existsSync)(destMysqlConfigPath)) {
|
|
559
|
+
const projectName = path_1.default.basename(baseDestPath);
|
|
560
|
+
// 将中横线替换为下划线,生成数据库名称
|
|
561
|
+
const databaseName = projectName.replace(/-/g, "_").toLowerCase();
|
|
562
|
+
shelljs_1.default.sed("-i", /database: 'crm_demo'/, `database: '${databaseName}'`, destMysqlConfigPath);
|
|
563
|
+
console.log(`Database name set to: ${databaseName}`);
|
|
564
|
+
}
|
|
552
565
|
console.log("Root files initialization completed");
|
|
553
566
|
return {
|
|
554
567
|
destPackagePath: (0, path_1.resolve)(baseDestPath + constants_1.packagePath),
|
|
@@ -556,13 +556,13 @@ export default Page`;
|
|
|
556
556
|
*/
|
|
557
557
|
generateClientValidation() {
|
|
558
558
|
const integerFields = this.getFormFields().filter((field) => field.type === "integer");
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
559
|
+
const decimalFields = this.getFormFields().filter((field) => field.type === "decimal");
|
|
560
|
+
const validations = [];
|
|
561
|
+
// 生成 integer 字段验证
|
|
562
|
+
integerFields.forEach((field) => {
|
|
563
563
|
const fieldName = field.name;
|
|
564
564
|
const capitalizedName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
|
|
565
|
-
|
|
565
|
+
validations.push(` // 验证${fieldName}
|
|
566
566
|
const ${fieldName}Value = modalObj.${fieldName}
|
|
567
567
|
if (${fieldName}Value !== undefined && ${fieldName}Value !== null && ${fieldName}Value !== '') {
|
|
568
568
|
const parsed${capitalizedName} = parseInt(${fieldName}Value, 10)
|
|
@@ -571,8 +571,26 @@ export default Page`;
|
|
|
571
571
|
return
|
|
572
572
|
}
|
|
573
573
|
modalObj.${fieldName} = parsed${capitalizedName}
|
|
574
|
-
}
|
|
574
|
+
}`);
|
|
575
575
|
});
|
|
576
|
+
// 生成 decimal 字段验证
|
|
577
|
+
decimalFields.forEach((field) => {
|
|
578
|
+
const fieldName = field.name;
|
|
579
|
+
const capitalizedName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
|
|
580
|
+
validations.push(` // 验证${fieldName}
|
|
581
|
+
const ${fieldName}Value = modalObj.${fieldName}
|
|
582
|
+
if (${fieldName}Value !== undefined && ${fieldName}Value !== null && ${fieldName}Value !== '') {
|
|
583
|
+
const parsed${capitalizedName} = parseFloat(${fieldName}Value)
|
|
584
|
+
if (isNaN(parsed${capitalizedName})) {
|
|
585
|
+
message.error(\`${fieldName}必须是数字,当前值: "\${${fieldName}Value}"\`)
|
|
586
|
+
return
|
|
587
|
+
}
|
|
588
|
+
modalObj.${fieldName} = parsed${capitalizedName}
|
|
589
|
+
}`);
|
|
590
|
+
});
|
|
591
|
+
if (validations.length === 0) {
|
|
592
|
+
return "";
|
|
593
|
+
}
|
|
576
594
|
return `${validations.join("\n\n")}\n\n`;
|
|
577
595
|
}
|
|
578
596
|
}
|
|
@@ -96,9 +96,11 @@ class SQLGenerator extends base_generator_1.BaseGenerator {
|
|
|
96
96
|
const primaryKeyField = this.fields.find((f) => f.isPrimaryKey);
|
|
97
97
|
const primaryKey = primaryKeyField ? ` PRIMARY KEY (\`${primaryKeyField.name}\`)` : "";
|
|
98
98
|
const databaseName = this.getDatabaseName();
|
|
99
|
-
return `
|
|
99
|
+
return `CREATE DATABASE IF NOT EXISTS ${databaseName} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
use ${databaseName};
|
|
102
|
+
|
|
103
|
+
CREATE TABLE IF NOT EXISTS \`${this.controller}\` (
|
|
102
104
|
${fieldDefinitions.join(",\n")},
|
|
103
105
|
${primaryKey}
|
|
104
106
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;`;
|