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.
@@ -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",
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.1",
18
+ "moment": "^2.29.4",
19
19
  "mysql": "^2.18.1",
20
20
  "node-uuid": "^1.4.8",
21
- "node-xlsx": "^0.23.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) return defaultValue;
62
+ if (value.length != 36 || value.split('-').length != 5) value= defaultValue;
63
63
  break;
64
64
  case 'number': ///限制为数字
65
- if (isNaN(value)) return defaultValue;
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
- return value;
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)|(\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;
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 = [],params = [];
32
+ let retSearch = [];
33
33
  paraCopy.refer.forEach(element => {
34
- //retSearch.push(this.parseTagInSql(request, element.pattern, false,true));
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 {filter:retSearch.join(''),params}
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,isSearch=false) => {
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 || isSearch ? checkSqlInjection(mysql.escape(keyValue)) : mysql.escape(keyValue)
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.filter, client: clientfilter });
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.filter, client: clientfilter });
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.filter + clientfilter +
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.filter)
143
+ sql += appendSearchCondition2Count(this.parseTagInSql(req, countsql), searchCondition)
205
144
  }
206
145
  }
207
- ///如果存在统计的SQL,则参数需要Double一次
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
- retSearch.push(this.parseTagInSql(request, element.pattern, false));
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 retSearch.join('');
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.substr(1, keyValue.length - 2);
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,ignorefilter=false) => {
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 = ignorefilter?'':this.getSearchCondition({ request: req, refer: search });
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
- return { sql, fields: field, footers: footer, page, hascounter: countsql?true:false };
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
  /*