doomiwork 4.1.3 → 4.1.4
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/core/controller.js
CHANGED
|
@@ -182,7 +182,6 @@ class controller {
|
|
|
182
182
|
*/
|
|
183
183
|
async getListData(req, dataKey, configFile = 0) {
|
|
184
184
|
if (this.logger) this.logger.trace("准备获取dataconfig文件中对应的 %s list数据",dataKey)
|
|
185
|
-
const ignorefilter = await this._redisHelper.get('key:ignorefilter');
|
|
186
185
|
const listinfo = getListInfo(req, dataKey, configFile, this._daoModel, ignorefilter==1);
|
|
187
186
|
if (!listinfo) return { successed: false, errcode: -10, errmsg:`缺失${dataKey}对应的查询语句`};
|
|
188
187
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "doomiwork",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.4",
|
|
4
4
|
"description": "doomisoft nodejs web framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"license": "ISC",
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"express": "^4.17.1",
|
|
18
|
-
"moment": "^2.29.
|
|
18
|
+
"moment": "^2.29.4",
|
|
19
19
|
"mysql": "^2.18.1",
|
|
20
20
|
"node-uuid": "^1.4.8",
|
|
21
|
-
"node-xlsx": "^0.
|
|
21
|
+
"node-xlsx": "^0.24.0"
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -55,14 +55,14 @@ module.exports.parseKeyValue=(req,str)=>{
|
|
|
55
55
|
* @param {*} defaultValue 如果不满足,则返回默认的
|
|
56
56
|
* @returns
|
|
57
57
|
*/
|
|
58
|
-
module.exports.validatorParamsType=(value, dataType, defaultValue = null)=> {
|
|
58
|
+
module.exports.validatorParamsType = (value, dataType, defaultValue = null, inscope=[])=> {
|
|
59
59
|
if (!value || !dataType) return value;
|
|
60
60
|
switch (dataType.toLowerCase()) {
|
|
61
61
|
case 'guid': ///限制长度为36位的GUID
|
|
62
|
-
if (value.length != 36 || value.split('-').length != 5)
|
|
62
|
+
if (value.length != 36 || value.split('-').length != 5) value= defaultValue;
|
|
63
63
|
break;
|
|
64
64
|
case 'number': ///限制为数字
|
|
65
|
-
if (isNaN(value))
|
|
65
|
+
if (isNaN(value)) value= defaultValue;
|
|
66
66
|
break;
|
|
67
67
|
case 'date': ///限制为日期,格式输出为YYYY-MM-DD
|
|
68
68
|
let date = Date.parse(value);
|
|
@@ -72,8 +72,25 @@ module.exports.validatorParamsType=(value, dataType, defaultValue = null)=> {
|
|
|
72
72
|
let datetime = Date.parse(value);
|
|
73
73
|
if (isNaN(datetime)) return defaultValue;
|
|
74
74
|
return datetime;
|
|
75
|
+
case 'array': ///返回数组
|
|
76
|
+
value= value.split(',');
|
|
75
77
|
}
|
|
76
|
-
|
|
78
|
+
///检查值在不在范围内取值
|
|
79
|
+
let inRange = true;
|
|
80
|
+
if (inscope.length > 0 && value) {
|
|
81
|
+
inRange = false;
|
|
82
|
+
if (Array.isArray(value)) {
|
|
83
|
+
for(const item of value){
|
|
84
|
+
if (inscope.some(scope => scope.toLowerCase() === item.toLowerCase())){
|
|
85
|
+
inRange = true;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
inRange = inscope.some(scope => scope.toLowerCase() === value.toLowerCase())
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return inRange ? value : defaultValue;
|
|
77
94
|
}
|
|
78
95
|
|
|
79
96
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const dataconfig = require('../configuration/dataconfig').getCurrent();
|
|
3
3
|
const mysql = require('mysql');
|
|
4
4
|
const ORDER_STRING = ['asc', 'desc']
|
|
5
|
-
const FORBID_SQL_KEYWORD = /;|(--)|(\bWHERE\b)|(\
|
|
5
|
+
const FORBID_SQL_KEYWORD = /;|(--)|(\bWHERE\b)|(\bSHOW\b)|(\bCOUNT\(\b)|(\bCREATE\b)|(\bCALL\b)|(\bBY\b)|(\bORDER\b)|(\bJOIN\b)|(\bUNION\b)|(\bFROM\b)|(\bSELECT\b)|(\bDROP\b)|(\bTRUNCATE\b)|(\bDELETE\b)|(\bUPDATE\b)|(\bINSERT\b)|(\bEXEC\b)|(\bEXECUTE\b)/gi;
|
|
6
6
|
|
|
7
7
|
function appendSearchCondition2Count(originSql, searchCondition) {
|
|
8
8
|
///如果包含了这个特定的字符,则替换
|
|
@@ -16,9 +16,9 @@ function appendSearchCondition2Count(originSql, searchCondition) {
|
|
|
16
16
|
*/
|
|
17
17
|
function checkSqlInjection(sql) {
|
|
18
18
|
if (!sql) return sql;
|
|
19
|
+
if (FORBID_SQL_KEYWORD.test(sql)) return '';
|
|
19
20
|
//let sqlError = sql.match(FORBID_SQL_KEYWORD); //strict ? sql.match(FORBID_SQL_KEYWORD_STRICT):sql.match(FORBID_SQL_KEYWORD);
|
|
20
21
|
//if (sqlError && sqlError.length > 0) return '';
|
|
21
|
-
if (FORBID_SQL_KEYWORD.test(sql)) return '';
|
|
22
22
|
return sql;
|
|
23
23
|
}
|
|
24
24
|
/*
|
|
@@ -29,17 +29,11 @@ module.exports.getSearchCondition = (option) => {
|
|
|
29
29
|
if (!paraCopy.request || !paraCopy.refer) return '';
|
|
30
30
|
if (!paraCopy.valueFrom) paraCopy.valueFrom = "all";
|
|
31
31
|
const request = paraCopy.request;
|
|
32
|
-
let retSearch = []
|
|
32
|
+
let retSearch = [];
|
|
33
33
|
paraCopy.refer.forEach(element => {
|
|
34
|
-
|
|
35
|
-
const paramSql=this.parseTagForParamtersSearch(request, element);
|
|
36
|
-
if (paramSql.sql) {
|
|
37
|
-
retSearch.push(paramSql.sql);
|
|
38
|
-
params = params.concat(paramSql.params||[]);
|
|
39
|
-
}
|
|
34
|
+
retSearch.push(this.parseTagInSql(request, element.pattern, false));
|
|
40
35
|
});
|
|
41
|
-
return
|
|
42
|
-
//return retSearch.join('');
|
|
36
|
+
return retSearch.join('');
|
|
43
37
|
}
|
|
44
38
|
|
|
45
39
|
/**
|
|
@@ -49,7 +43,7 @@ module.exports.getSearchCondition = (option) => {
|
|
|
49
43
|
* @param {*} allowNull
|
|
50
44
|
* @returns
|
|
51
45
|
*/
|
|
52
|
-
module.exports.parseTagInSql = (req, sql, allowNull = true
|
|
46
|
+
module.exports.parseTagInSql = (req, sql, allowNull = true) => {
|
|
53
47
|
if (!sql) return '';
|
|
54
48
|
///定义正则准备查找sql中的特定关键字
|
|
55
49
|
const matched = sql.match(/@.*?@/g);
|
|
@@ -74,7 +68,7 @@ module.exports.parseTagInSql = (req, sql, allowNull = true,isSearch=false) => {
|
|
|
74
68
|
if (!keyValue) {
|
|
75
69
|
parseKeyWordIsNull = true;
|
|
76
70
|
} else if (typeof (keyValue) === 'string') {
|
|
77
|
-
keyValue = noQuoteProtect
|
|
71
|
+
keyValue = noQuoteProtect ? checkSqlInjection(mysql.escape(keyValue)) : mysql.escape(keyValue)
|
|
78
72
|
keyValue = keyValue.substr(1, keyValue.length - 2);
|
|
79
73
|
///验证参数的格式合法性
|
|
80
74
|
if (keyValue && validformat.length > 1) {
|
|
@@ -99,66 +93,11 @@ module.exports.parseTagInSql = (req, sql, allowNull = true,isSearch=false) => {
|
|
|
99
93
|
return sql;
|
|
100
94
|
}
|
|
101
95
|
|
|
102
|
-
/**
|
|
103
|
-
* 为列表查询定义参数化查询
|
|
104
|
-
* @param {*} req
|
|
105
|
-
* @param {*} sql
|
|
106
|
-
* @param {*} allowNull
|
|
107
|
-
* @param {*} isSearch
|
|
108
|
-
* @returns
|
|
109
|
-
*/
|
|
110
|
-
module.exports.parseTagForParamtersSearch = (req, filterSetting={}) => {
|
|
111
|
-
let {pattern:sql,mode=''} = filterSetting;
|
|
112
|
-
if (!sql) return {sql:''};
|
|
113
|
-
///定义正则准备查找sql中的特定关键字
|
|
114
|
-
const matched = sql.match(/@.*?@/g);
|
|
115
|
-
let params = [];
|
|
116
|
-
if (!matched || matched.length <= 0) return {sql};
|
|
117
|
-
for(const ele of matched){
|
|
118
|
-
let patternModel = mode;
|
|
119
|
-
let matchValue = ele.substring(1, ele.length - 1);
|
|
120
|
-
///不允许特殊字符出现
|
|
121
|
-
let noQuoteProtect = matchValue[0] == '!';
|
|
122
|
-
if (noQuoteProtect) {
|
|
123
|
-
matchValue = matchValue.substring(1);
|
|
124
|
-
patternModel='';
|
|
125
|
-
}
|
|
126
|
-
///是否有格式要求
|
|
127
|
-
let validformat = matchValue.split('|');
|
|
128
|
-
matchValue = validformat[0];
|
|
129
|
-
let keyValue = (parseKeyValue(req, matchValue) || '') + ''; //utility.ifNull(keyParse.parseKeyValue(req, matchValue), '')+'';
|
|
130
|
-
if (keyValue && typeof (keyValue) === 'string') {
|
|
131
|
-
///验证参数的格式合法性
|
|
132
|
-
if (keyValue && validformat.length > 1) {
|
|
133
|
-
keyValue = validatorParamsType(keyValue, validformat[1], validformat[2])
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
///如果解析不出这个KeyValue ,则认为当前这条SQL过滤无效
|
|
137
|
-
if (!keyValue) return {sql:'',params:[]};
|
|
138
|
-
if (keyValue) {
|
|
139
|
-
switch (patternModel.toLowerCase()) {
|
|
140
|
-
case 'like':
|
|
141
|
-
sql = sql.replace(ele, '?'); ///变成参数化查询
|
|
142
|
-
params.push('%' + keyValue + '%')
|
|
143
|
-
break;
|
|
144
|
-
case 'in':
|
|
145
|
-
sql = sql.replace(ele, '?'); ///变成参数化查询
|
|
146
|
-
params.push(keyValue.split(','))
|
|
147
|
-
break;
|
|
148
|
-
default:
|
|
149
|
-
sql = sql.replace(ele, '?'); ///变成参数化查询
|
|
150
|
-
params.push(keyValue)
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return {sql,params};
|
|
156
|
-
}
|
|
157
96
|
/*
|
|
158
97
|
* 列表请求上下文中获取需要的信息
|
|
159
98
|
* 如Page ,PageSize , Sort 等等
|
|
160
99
|
*/
|
|
161
|
-
module.exports.getListInfo = (req, dataKey, cfgType = 0, dao) => {
|
|
100
|
+
module.exports.getListInfo = (req, dataKey, cfgType = 0, dao,ignorefilter=false) => {
|
|
162
101
|
if (!dataKey) return null;
|
|
163
102
|
///确认是否是需要导出Excel
|
|
164
103
|
const export2Excel = (req.query.exportexcel + "").toLowerCase() === "true";
|
|
@@ -179,34 +118,32 @@ module.exports.getListInfo = (req, dataKey, cfgType = 0, dao) => {
|
|
|
179
118
|
req.dataConfig = dataConfig
|
|
180
119
|
let { sql, listsql, countsql, sqltype = 'sql', field, footer, search, sort: constsort } = dataConfig.list
|
|
181
120
|
/**解析查询条件 */
|
|
182
|
-
const searchCondition = this.getSearchCondition({ request: req, refer: search });
|
|
121
|
+
const searchCondition = ignorefilter?'':this.getSearchCondition({ request: req, refer: search });
|
|
183
122
|
/**排序方式 *///
|
|
184
123
|
sort = sort || constsort;
|
|
185
124
|
/**来自req请求参数中的过滤条件 */
|
|
186
125
|
let clientfilter = checkSqlInjection(this.parseTagInSql(req, filter, false));
|
|
187
126
|
//如果配置文件中不是直接的sql语句,则从DAO对象中的指定方法来获取sql
|
|
188
127
|
if (sqltype !== 'sql' && listsql && typeof (dao[listsql]) === 'function') {
|
|
189
|
-
sql = dao[sql](req, { page, rows: pageSize, sort, filter: searchCondition
|
|
128
|
+
sql = dao[sql](req, { page, rows: pageSize, sort, filter: searchCondition, client: clientfilter });
|
|
190
129
|
if (dao[countsql] && typeof (dao[countsql]) === 'function')
|
|
191
|
-
countsql = dao[countsql](req, { page, rows: pageSize, sort, filter: searchCondition
|
|
130
|
+
countsql = dao[countsql](req, { page, rows: pageSize, sort, filter: searchCondition, client: clientfilter });
|
|
192
131
|
}
|
|
193
132
|
|
|
194
133
|
/**根据过滤条件、排序条件、分页获取的方式,和原始sql拼接成最终获取数据的sql */
|
|
195
134
|
if (sqltype==='sql'){
|
|
196
135
|
sql = this.parseTagInSql(req, sql) +
|
|
197
|
-
' ' + searchCondition
|
|
136
|
+
' ' + searchCondition + clientfilter +
|
|
198
137
|
(sort ? (' order by ' + sort) : '') +
|
|
199
138
|
(export2Excel ? '' : ' limit ' + Number(pageSize) + ' OFFSET ' + (Math.max(Number(page), 1) - 1) * Number(pageSize)) +
|
|
200
139
|
/////在Sql中再放入获取总记录数的语句
|
|
201
140
|
';SELECT FOUND_ROWS() AS total;';
|
|
202
141
|
/*** 如果存在汇总列的sql,则把SQL放置在最末尾 */
|
|
203
142
|
if (countsql) {
|
|
204
|
-
sql += appendSearchCondition2Count(this.parseTagInSql(req, countsql), searchCondition
|
|
143
|
+
sql += appendSearchCondition2Count(this.parseTagInSql(req, countsql), searchCondition)
|
|
205
144
|
}
|
|
206
145
|
}
|
|
207
|
-
|
|
208
|
-
const sqlParams = countsql ? [].concat(searchCondition.params, searchCondition.params):searchCondition.params;
|
|
209
|
-
return { sql, fields: field, params: sqlParams, footers: footer, page, hascounter: countsql?true:false };
|
|
146
|
+
return { sql, fields: field, footers: footer, page, hascounter: countsql?true:false };
|
|
210
147
|
}
|
|
211
148
|
}
|
|
212
149
|
/*
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const dataconfig = require('../configuration/dataconfig').getCurrent();
|
|
3
3
|
const mysql = require('mysql');
|
|
4
4
|
const ORDER_STRING = ['asc', 'desc']
|
|
5
|
-
const FORBID_SQL_KEYWORD = /;|(--)|(\bWHERE\b)|(\bSHOW\b)|(\bCOUNT\(\b)|(\bCREATE\b)|(\bCALL\b)|(\bBY\b)|(\bORDER\b)|(\bJOIN\b)|(\bUNION\b)|(\bFROM\b)|(\bSELECT\b)|(\bDROP\b)|(\bTRUNCATE\b)|(\bDELETE\b)|(\bUPDATE\b)|(\bINSERT\b)|(\bEXEC\b)|(\bEXECUTE\b)/gi;
|
|
5
|
+
const FORBID_SQL_KEYWORD = /;|(--)|(\bWHERE\b)|(\bCASE\b)|(\bWHEN\b)|(\bSLEEP\b)|(\bSHOW\b)|(\bCOUNT\(\b)|(\bCREATE\b)|(\bCALL\b)|(\bBY\b)|(\bORDER\b)|(\bJOIN\b)|(\bUNION\b)|(\bFROM\b)|(\bSELECT\b)|(\bDROP\b)|(\bTRUNCATE\b)|(\bDELETE\b)|(\bUPDATE\b)|(\bINSERT\b)|(\bEXEC\b)|(\bEXECUTE\b)/gi;
|
|
6
6
|
|
|
7
7
|
function appendSearchCondition2Count(originSql, searchCondition) {
|
|
8
8
|
///如果包含了这个特定的字符,则替换
|
|
@@ -17,8 +17,6 @@ function appendSearchCondition2Count(originSql, searchCondition) {
|
|
|
17
17
|
function checkSqlInjection(sql) {
|
|
18
18
|
if (!sql) return sql;
|
|
19
19
|
if (FORBID_SQL_KEYWORD.test(sql)) return '';
|
|
20
|
-
//let sqlError = sql.match(FORBID_SQL_KEYWORD); //strict ? sql.match(FORBID_SQL_KEYWORD_STRICT):sql.match(FORBID_SQL_KEYWORD);
|
|
21
|
-
//if (sqlError && sqlError.length > 0) return '';
|
|
22
20
|
return sql;
|
|
23
21
|
}
|
|
24
22
|
/*
|
|
@@ -29,11 +27,16 @@ module.exports.getSearchCondition = (option) => {
|
|
|
29
27
|
if (!paraCopy.request || !paraCopy.refer) return '';
|
|
30
28
|
if (!paraCopy.valueFrom) paraCopy.valueFrom = "all";
|
|
31
29
|
const request = paraCopy.request;
|
|
32
|
-
let retSearch = [];
|
|
30
|
+
let retSearch = [],params = [];
|
|
33
31
|
paraCopy.refer.forEach(element => {
|
|
34
|
-
|
|
32
|
+
const paramSql = this.parseTagForParameterize(request, element);
|
|
33
|
+
if (paramSql.sql) {
|
|
34
|
+
retSearch.push(paramSql.sql);
|
|
35
|
+
params = params.concat(paramSql.params||[]);
|
|
36
|
+
}
|
|
35
37
|
});
|
|
36
|
-
return
|
|
38
|
+
return {filter:retSearch.join(''),params}
|
|
39
|
+
//return retSearch.join('');
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
/**
|
|
@@ -49,7 +52,6 @@ module.exports.parseTagInSql = (req, sql, allowNull = true) => {
|
|
|
49
52
|
const matched = sql.match(/@.*?@/g);
|
|
50
53
|
if (!matched || matched.length <= 0) return sql;
|
|
51
54
|
let parseKeyWordIsNull = false;
|
|
52
|
-
|
|
53
55
|
const charReg = /\s+|:|=/gi
|
|
54
56
|
matched.forEach(ele => {
|
|
55
57
|
let matchValue = ele.substring(1, ele.length - 1);
|
|
@@ -69,19 +71,14 @@ module.exports.parseTagInSql = (req, sql, allowNull = true) => {
|
|
|
69
71
|
parseKeyWordIsNull = true;
|
|
70
72
|
} else if (typeof (keyValue) === 'string') {
|
|
71
73
|
keyValue = noQuoteProtect ? checkSqlInjection(mysql.escape(keyValue)) : mysql.escape(keyValue)
|
|
72
|
-
keyValue = keyValue.
|
|
74
|
+
keyValue = keyValue.substring(1, keyValue.length - 1);
|
|
73
75
|
///验证参数的格式合法性
|
|
74
|
-
if (keyValue && validformat.length > 1)
|
|
75
|
-
// console.log(`参数格式合法检查==>${validformat[1]}:${matchValue} = ${keyValue}`)
|
|
76
|
-
keyValue = validatorParamsType(keyValue, validformat[1], validformat[2])
|
|
77
|
-
}
|
|
76
|
+
if (keyValue && validformat.length > 1) keyValue = validatorParamsType(keyValue, validformat[1], validformat[2])
|
|
78
77
|
if (!keyValue) {
|
|
79
78
|
parseKeyWordIsNull = true;
|
|
80
79
|
}
|
|
81
80
|
///没有引号保护下发现了sql注入,则用1=0不返回任何结果
|
|
82
|
-
if (!keyValue && noQuoteProtect)
|
|
83
|
-
keyValue = '1=0'
|
|
84
|
-
}
|
|
81
|
+
if (!keyValue && noQuoteProtect) keyValue = '1=0'
|
|
85
82
|
} else { ////数组形式的参数,目前框架不支持,统一认为为sql注入攻击,全部忽略
|
|
86
83
|
// console.log(`参数非法==>类型${typeof (keyValue)}:${matchValue} = ${keyValue}`)
|
|
87
84
|
parseKeyWordIsNull = true;
|
|
@@ -93,11 +90,59 @@ module.exports.parseTagInSql = (req, sql, allowNull = true) => {
|
|
|
93
90
|
return sql;
|
|
94
91
|
}
|
|
95
92
|
|
|
93
|
+
/**
|
|
94
|
+
* 为列表查询定义参数化查询
|
|
95
|
+
* @param {*} req
|
|
96
|
+
* @param {*} sql
|
|
97
|
+
* @param {*} allowNull
|
|
98
|
+
* @param {*} isSearch
|
|
99
|
+
* @returns
|
|
100
|
+
*/
|
|
101
|
+
module.exports.parseTagForParameterize = (req, filterSetting={}) => {
|
|
102
|
+
///type=parameter表示参数化方式查询
|
|
103
|
+
///type=joint 表示拼接sql语句查询
|
|
104
|
+
///scope=[] 表示需要解析的字段必须在此列表内容中
|
|
105
|
+
let {pattern:sql,type='parameter',inscope=[]} = filterSetting;
|
|
106
|
+
if (!sql) return {sql:''};
|
|
107
|
+
///定义正则准备查找sql中的特定关键字
|
|
108
|
+
const matched = sql.match(/@.*?@/g);
|
|
109
|
+
let params = [];
|
|
110
|
+
if (!matched || matched.length <= 0) return {sql};
|
|
111
|
+
for(const ele of matched){
|
|
112
|
+
let matchValue = ele.substring(1, ele.length - 1);
|
|
113
|
+
///检查是否有特殊的字符比如 % 等
|
|
114
|
+
const specialRegex = /^[^a-zA-Z0-9]*(.*?)[^a-zA-Z0-9]*$/
|
|
115
|
+
const matchContent = matchValue.match(specialRegex);
|
|
116
|
+
matchValue = matchContent ? matchContent[1]:matchValue;
|
|
117
|
+
if (!matchValue) return {sql:'',params:[]};
|
|
118
|
+
///是否有格式要求
|
|
119
|
+
let validformat = matchValue.split('|');
|
|
120
|
+
matchValue = validformat[0];
|
|
121
|
+
let keyValue = parseKeyValue(req, matchValue)||''; //utility.ifNull(keyParse.parseKeyValue(req, matchValue), '')+'';
|
|
122
|
+
if (keyValue && validformat.length > 1) keyValue = validatorParamsType(keyValue, validformat[1], validformat[2], inscope)
|
|
123
|
+
///如果解析不出这个KeyValue ,则认为当前这条SQL过滤无效
|
|
124
|
+
if (!keyValue) return {sql:'',params:[]};
|
|
125
|
+
if (keyValue) {
|
|
126
|
+
if(type.toLowerCase() === 'parameter'){
|
|
127
|
+
sql = sql.replace(ele, '?'); ///变成参数化查询
|
|
128
|
+
if (Array.isArray(keyValue))
|
|
129
|
+
params.push(keyValue)
|
|
130
|
+
else
|
|
131
|
+
params.push(matchContent[0].replace(matchContent[1], keyValue));// '%' + keyValue + '%')
|
|
132
|
+
} else if (type.toLowerCase() === 'joint'){ ///拼接sql语句查询
|
|
133
|
+
///拼接的SQL语句,keyvalue必须在scope列表中,否则不予拼接
|
|
134
|
+
const result = inscope.some(item => item.toLowerCase() === matchValue.toLowerCase());
|
|
135
|
+
if (result)sql = sql.replace(ele, keyValue);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {sql,params};
|
|
140
|
+
}
|
|
96
141
|
/*
|
|
97
142
|
* 列表请求上下文中获取需要的信息
|
|
98
143
|
* 如Page ,PageSize , Sort 等等
|
|
99
144
|
*/
|
|
100
|
-
module.exports.getListInfo = (req, dataKey, cfgType = 0, dao
|
|
145
|
+
module.exports.getListInfo = (req, dataKey, cfgType = 0, dao) => {
|
|
101
146
|
if (!dataKey) return null;
|
|
102
147
|
///确认是否是需要导出Excel
|
|
103
148
|
const export2Excel = (req.query.exportexcel + "").toLowerCase() === "true";
|
|
@@ -118,32 +163,34 @@ module.exports.getListInfo = (req, dataKey, cfgType = 0, dao,ignorefilter=false)
|
|
|
118
163
|
req.dataConfig = dataConfig
|
|
119
164
|
let { sql, listsql, countsql, sqltype = 'sql', field, footer, search, sort: constsort } = dataConfig.list
|
|
120
165
|
/**解析查询条件 */
|
|
121
|
-
const searchCondition =
|
|
166
|
+
const searchCondition = this.getSearchCondition({ request: req, refer: search });
|
|
122
167
|
/**排序方式 *///
|
|
123
168
|
sort = sort || constsort;
|
|
124
169
|
/**来自req请求参数中的过滤条件 */
|
|
125
170
|
let clientfilter = checkSqlInjection(this.parseTagInSql(req, filter, false));
|
|
126
171
|
//如果配置文件中不是直接的sql语句,则从DAO对象中的指定方法来获取sql
|
|
127
172
|
if (sqltype !== 'sql' && listsql && typeof (dao[listsql]) === 'function') {
|
|
128
|
-
sql = dao[sql](req, { page, rows: pageSize, sort, filter: searchCondition, client: clientfilter });
|
|
173
|
+
sql = dao[sql](req, { page, rows: pageSize, sort, filter: searchCondition.filter, client: clientfilter });
|
|
129
174
|
if (dao[countsql] && typeof (dao[countsql]) === 'function')
|
|
130
|
-
countsql = dao[countsql](req, { page, rows: pageSize, sort, filter: searchCondition, client: clientfilter });
|
|
175
|
+
countsql = dao[countsql](req, { page, rows: pageSize, sort, filter: searchCondition.filter, client: clientfilter });
|
|
131
176
|
}
|
|
132
177
|
|
|
133
178
|
/**根据过滤条件、排序条件、分页获取的方式,和原始sql拼接成最终获取数据的sql */
|
|
134
179
|
if (sqltype==='sql'){
|
|
135
180
|
sql = this.parseTagInSql(req, sql) +
|
|
136
|
-
' ' + searchCondition + clientfilter +
|
|
181
|
+
' ' + searchCondition.filter + clientfilter +
|
|
137
182
|
(sort ? (' order by ' + sort) : '') +
|
|
138
183
|
(export2Excel ? '' : ' limit ' + Number(pageSize) + ' OFFSET ' + (Math.max(Number(page), 1) - 1) * Number(pageSize)) +
|
|
139
184
|
/////在Sql中再放入获取总记录数的语句
|
|
140
185
|
';SELECT FOUND_ROWS() AS total;';
|
|
141
186
|
/*** 如果存在汇总列的sql,则把SQL放置在最末尾 */
|
|
142
187
|
if (countsql) {
|
|
143
|
-
sql += appendSearchCondition2Count(this.parseTagInSql(req, countsql), searchCondition)
|
|
188
|
+
sql += appendSearchCondition2Count(this.parseTagInSql(req, countsql), searchCondition.filter)
|
|
144
189
|
}
|
|
145
190
|
}
|
|
146
|
-
|
|
191
|
+
///如果存在统计的SQL,则参数需要Double一次
|
|
192
|
+
const sqlParams = countsql ? [].concat(searchCondition.params, searchCondition.params):searchCondition.params;
|
|
193
|
+
return { sql, fields: field, params: sqlParams, footers: footer, page, hascounter: countsql?true:false };
|
|
147
194
|
}
|
|
148
195
|
}
|
|
149
196
|
/*
|