doomiwork 4.1.10 → 4.2.1
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/dist/index.esm.js +1 -0
- package/dist/index.js +1 -0
- package/package.json +22 -7
- package/configuration/appsetting.js +0 -42
- package/configuration/dataconfig.js +0 -55
- package/configuration/routerconfig.js +0 -144
- package/core/actionresult.js +0 -30
- package/core/controller.js +0 -380
- package/core/database/daoBase.js +0 -352
- package/core/database/mysqlbase.js +0 -173
- package/core/database/poolmanager.js +0 -15
- package/core/doomiwork.js +0 -76
- package/core/enumconst.js +0 -52
- package/index.js +0 -13
- package/utilities/excelutility.js +0 -202
- package/utilities/keywordparse.js +0 -115
- package/utilities/requestparser-bak.js +0 -163
- package/utilities/requestparser.js +0 -250
- package/utilities/tokenutility.js +0 -45
- package/utilities/transferutility.js +0 -105
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
const xlsx = require('node-xlsx');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const uuid = require('uuid');
|
|
5
|
-
class ExcelUtility {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.exportFolder = path.join(process.cwd(), '/public/excel/');
|
|
8
|
-
let configfile = path.join(process.cwd(), 'excelconfig.json');
|
|
9
|
-
if (fs.existsSync(configfile))
|
|
10
|
-
this.excelConfig = require(configfile);
|
|
11
|
-
else
|
|
12
|
-
this.excelConfig = {};
|
|
13
|
-
}
|
|
14
|
-
static getInstance() {
|
|
15
|
-
if (!ExcelUtility.instance) ExcelUtility.instance = new ExcelUtility();
|
|
16
|
-
return ExcelUtility.instance;
|
|
17
|
-
}
|
|
18
|
-
///读取Excel的内容
|
|
19
|
-
readExcel(fileName) {
|
|
20
|
-
//读取文件内容
|
|
21
|
-
const obj = xlsx.parse(fileName);//__dirname+'/test.xlsx');
|
|
22
|
-
const excelObj = obj[0].data;
|
|
23
|
-
console.log(excelObj);
|
|
24
|
-
return excelObj;
|
|
25
|
-
}
|
|
26
|
-
///写Excel文件
|
|
27
|
-
createExcelBuffer(data, fileName, workSheetName) {
|
|
28
|
-
var sheetName = 'sheet1';
|
|
29
|
-
if (workSheetName == null) sheetName = workSheetName;
|
|
30
|
-
var buffer = xlsx.build([{ name: 'sheet1', data: data }]);
|
|
31
|
-
|
|
32
|
-
res.set({
|
|
33
|
-
"Content-type": "application/octet-stream",
|
|
34
|
-
"Content-Disposition": "attachment;filename=" + encodeURI(fileName)
|
|
35
|
-
});
|
|
36
|
-
fReadStream = fs.createReadStream(buffer);
|
|
37
|
-
fReadStream.on("data", (chunk) => res.write(chunk, "binary"));
|
|
38
|
-
fReadStream.on("end", () => {
|
|
39
|
-
res.end();
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
///写Excel文件
|
|
43
|
-
async writeExcel(data, workSheetName) {
|
|
44
|
-
let sheetName = 'sheet1';
|
|
45
|
-
if (workSheetName == null) sheetName = workSheetName;
|
|
46
|
-
let randomFile = uuid.v4() + '.xlsx';
|
|
47
|
-
let fileName = path.resolve(this.exportFolder, randomFile);
|
|
48
|
-
let _saveDir = path.dirname(fileName);
|
|
49
|
-
///创建本地文件夹
|
|
50
|
-
if (!this.mkdirsSync(_saveDir)) return { success: false, errorcode: 1, errmessage: 'create folder failed!' };
|
|
51
|
-
const buffer = xlsx.build([{ name: sheetName, data: data }]);
|
|
52
|
-
return new Promise(reslove => {
|
|
53
|
-
return fs.writeFile(fileName, buffer, (err) => {
|
|
54
|
-
return reslove({ successed: !err, errmessage: err, fileName:randomFile })
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
///导出记录集到Excel,写入
|
|
59
|
-
///dataRow :记录集
|
|
60
|
-
///exportConfig : 导出的映射配置,如没有则将dataRow直接导出
|
|
61
|
-
///workSheetName : 导出的Excel 文件 WorkSheet名
|
|
62
|
-
async recordset2ExcelFile(dataRow, exportConfig, readyDataFunc) {
|
|
63
|
-
let _instance = this;
|
|
64
|
-
//var setting = exportConfig ? excelConfig[exportConfig] : null;
|
|
65
|
-
let setting = exportConfig ? _instance.excelConfig[exportConfig] : null;
|
|
66
|
-
let dataBuffer = [], worksheetName = "sheet1", fieldKey = [], titleRow = [];
|
|
67
|
-
if (setting != null) {
|
|
68
|
-
worksheetName = setting.worksheet ?? "sheet1"; //== null ? "sheet1" : setting.worksheet;
|
|
69
|
-
////第一行导出标题行
|
|
70
|
-
setting.columns.forEach((field) => {
|
|
71
|
-
var dataOption = { type: 'title', config: exportConfig, title: field.title, field: field.name };
|
|
72
|
-
if (readyDataFunc != null && typeof (readyDataFunc) == "function")
|
|
73
|
-
dataOption = readyDataFunc(dataOption)
|
|
74
|
-
titleRow.push(dataOption.title);
|
|
75
|
-
fieldKey.push(dataOption.field);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
else if (dataRow.length > 0) {
|
|
79
|
-
var firstRow = dataRow[0];
|
|
80
|
-
Object.keys(firstRow).forEach(key => {
|
|
81
|
-
var dataOption = { type: 'title', config: null, title: key, field: key };
|
|
82
|
-
if (readyDataFunc != null && typeof (readyDataFunc) == "function")
|
|
83
|
-
dataOption = readyDataFunc(dataOption)
|
|
84
|
-
titleRow.push(dataOption.title);
|
|
85
|
-
fieldKey.push(dataOption.field);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
if (titleRow.length > 0) {
|
|
89
|
-
dataBuffer.push(titleRow);
|
|
90
|
-
dataRow.forEach((rowItem) => {
|
|
91
|
-
var dataRow = [];
|
|
92
|
-
fieldKey.forEach((field) => {
|
|
93
|
-
var dataOption = { type: 'data', config: exportConfig, field: field, data: rowItem, value: rowItem[field] };
|
|
94
|
-
if (readyDataFunc != null && typeof (readyDataFunc) == "function")
|
|
95
|
-
dataOption = readyDataFunc(dataOption)
|
|
96
|
-
dataRow.push(dataOption.value);
|
|
97
|
-
});
|
|
98
|
-
dataBuffer.push(dataRow);
|
|
99
|
-
})
|
|
100
|
-
}
|
|
101
|
-
var result = await _instance.writeExcel(dataBuffer, worksheetName);
|
|
102
|
-
return result;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
///写Excel文件
|
|
106
|
-
async writeMutlisheetExcel(sheetinfo) {
|
|
107
|
-
//let sheetName = 'sheet1';
|
|
108
|
-
//if (workSheetName == null) sheetName = workSheetName;
|
|
109
|
-
let randomFile = uuid.v4() + '.xlsx';
|
|
110
|
-
let fileName = path.resolve(this.exportFolder, randomFile);
|
|
111
|
-
let _saveDir = path.dirname(fileName);
|
|
112
|
-
///创建本地文件夹
|
|
113
|
-
if (!this.mkdirsSync(_saveDir)) return { success: false, errorcode: 1, errmessage: 'create folder failed!' };
|
|
114
|
-
const buffer = xlsx.build(sheetinfo);// ([{ name: sheetName, data: data }]);
|
|
115
|
-
return new Promise(reslove => {
|
|
116
|
-
return fs.writeFile(fileName, buffer, (err) => {
|
|
117
|
-
return reslove({ successed: !err, errmessage: err, fileName: randomFile })
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* 导出记录集到Excel的多个worksheet中
|
|
123
|
-
* @param {*} dataRow
|
|
124
|
-
* @param {*} exportConfig
|
|
125
|
-
* @param {*} readyDataFunc
|
|
126
|
-
* @returns
|
|
127
|
-
*/
|
|
128
|
-
async recordset2MutlisheetExcelFile(sheetsInfo, readyDataFunc) {
|
|
129
|
-
let _instance = this;
|
|
130
|
-
let sheetinfo = [];
|
|
131
|
-
for (const { data: dataRow, mapping: exportConfig } of sheetsInfo){
|
|
132
|
-
let setting = exportConfig ? _instance.excelConfig[exportConfig] : null;
|
|
133
|
-
let dataBuffer = [], worksheetName = "sheet1", fieldKey = [], titleRow = [];
|
|
134
|
-
if (setting != null) {
|
|
135
|
-
worksheetName = setting.worksheet == null ? "sheet1" : setting.worksheet;
|
|
136
|
-
////第一行导出标题行
|
|
137
|
-
setting.columns.forEach((field) => {
|
|
138
|
-
var dataOption = { type: 'title', config: exportConfig, title: field.title, field: field.name };
|
|
139
|
-
if (readyDataFunc != null && typeof (readyDataFunc) == "function")
|
|
140
|
-
dataOption = readyDataFunc(dataOption)
|
|
141
|
-
titleRow.push(dataOption.title);
|
|
142
|
-
fieldKey.push(dataOption.field);
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
else if (dataRow.length > 0) {
|
|
146
|
-
var firstRow = dataRow[0];
|
|
147
|
-
Object.keys(firstRow).forEach(key => {
|
|
148
|
-
var dataOption = { type: 'title', config: null, title: key, field: key };
|
|
149
|
-
if (readyDataFunc != null && typeof (readyDataFunc) == "function")
|
|
150
|
-
dataOption = readyDataFunc(dataOption)
|
|
151
|
-
titleRow.push(dataOption.title);
|
|
152
|
-
fieldKey.push(dataOption.field);
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
if (titleRow.length > 0) {
|
|
156
|
-
dataBuffer.push(titleRow);
|
|
157
|
-
dataRow.forEach((rowItem) => {
|
|
158
|
-
var dataRow = [];
|
|
159
|
-
fieldKey.forEach((field) => {
|
|
160
|
-
var dataOption = { type: 'data', config: exportConfig, field: field, data: rowItem, value: rowItem[field] };
|
|
161
|
-
if (readyDataFunc != null && typeof (readyDataFunc) == "function")
|
|
162
|
-
dataOption = readyDataFunc(dataOption)
|
|
163
|
-
dataRow.push(dataOption.value);
|
|
164
|
-
});
|
|
165
|
-
dataBuffer.push(dataRow);
|
|
166
|
-
})
|
|
167
|
-
}
|
|
168
|
-
sheetinfo.push({ name: worksheetName, data: dataBuffer });
|
|
169
|
-
}
|
|
170
|
-
const result = await _instance.writeMutlisheetExcel(sheetinfo);
|
|
171
|
-
return result;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* 递归创建多级目录
|
|
176
|
-
* @param {*} dirpath
|
|
177
|
-
* @param {*} mode
|
|
178
|
-
* @returns
|
|
179
|
-
*/
|
|
180
|
-
mkdirsSync(dirpath, mode) {
|
|
181
|
-
if (!fs.existsSync(dirpath)) {
|
|
182
|
-
let pathtmp;
|
|
183
|
-
const splitPath = dirpath.split(path.sep);
|
|
184
|
-
for (var nLoop = 0; nLoop < splitPath.length; nLoop++) {
|
|
185
|
-
var dirname = splitPath[nLoop];
|
|
186
|
-
if (dirname.length == 0) {
|
|
187
|
-
pathtmp = "/";
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
if (pathtmp)
|
|
191
|
-
pathtmp = path.join(pathtmp, dirname);
|
|
192
|
-
else
|
|
193
|
-
pathtmp = dirname;
|
|
194
|
-
if (!fs.existsSync(pathtmp)) {
|
|
195
|
-
fs.mkdirSync(pathtmp, mode)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
exports = module.exports = ExcelUtility;
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* 解析上下文中对应dataconfig文件中的一些变量解析
|
|
4
|
-
*/
|
|
5
|
-
const uuid = require('uuid');
|
|
6
|
-
const moment = require('moment')
|
|
7
|
-
/*
|
|
8
|
-
* 从上下文 解析关键字
|
|
9
|
-
* 或者已固定的方式解析关键字
|
|
10
|
-
*/
|
|
11
|
-
module.exports.parseKeyValue=(req,str)=>{
|
|
12
|
-
if (!str) return str||'';
|
|
13
|
-
const strItems = str.split('.');
|
|
14
|
-
if (strItems.length===1)
|
|
15
|
-
{
|
|
16
|
-
switch(str.toLowerCase()){
|
|
17
|
-
case "userid()":
|
|
18
|
-
if (req.user && req.user.id) return req.user.id;
|
|
19
|
-
return uuid.v4();
|
|
20
|
-
case "uuid()" : return uuid.v4();
|
|
21
|
-
case "appid()" :
|
|
22
|
-
if (req.user && req.user.appid) return req.user.appid;
|
|
23
|
-
return null;
|
|
24
|
-
case "orgid()" :
|
|
25
|
-
if (req.user && req.user.id) return req.user.orgnizations;
|
|
26
|
-
return null;
|
|
27
|
-
case "now()": return moment().format('YYYY-MM-DD HH:mm:ss');
|
|
28
|
-
case "null()": return null;
|
|
29
|
-
default: return (req.body && req.body[str])||(req.query && req.query[str])||'';
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
else
|
|
33
|
-
{
|
|
34
|
-
let collection;
|
|
35
|
-
if (strItems[0]=="" || strItems[1]=="") return str;
|
|
36
|
-
switch(strItems[0].toLowerCase())
|
|
37
|
-
{
|
|
38
|
-
case "query" : collection = req.query; break;
|
|
39
|
-
case "form": collection = req.body;break;
|
|
40
|
-
case "params": collection = req.params; break;
|
|
41
|
-
case "value": return strItems[1];
|
|
42
|
-
case "headers": collection = req.headers; break;
|
|
43
|
-
case "user": collection = req.user || {}; break;
|
|
44
|
-
default: collection = req.body; break;
|
|
45
|
-
}
|
|
46
|
-
if (collection) return collection[strItems[1]] || '';
|
|
47
|
-
return '';
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* 校验参数的类型
|
|
53
|
-
* @param {*} value 数值
|
|
54
|
-
* @param {*} dataType 校验的类型
|
|
55
|
-
* @param {*} defaultValue 如果不满足,则返回默认的
|
|
56
|
-
* @returns
|
|
57
|
-
*/
|
|
58
|
-
module.exports.validatorParamsType = (value, dataType, defaultValue = null, inscope=[])=> {
|
|
59
|
-
if (!value || !dataType) return value;
|
|
60
|
-
switch (dataType.toLowerCase()) {
|
|
61
|
-
case 'guid': ///限制长度为36位的GUID
|
|
62
|
-
if (value.length != 36 || value.split('-').length != 5) value= defaultValue;
|
|
63
|
-
break;
|
|
64
|
-
case 'number': ///限制为数字
|
|
65
|
-
if (isNaN(value)) value= defaultValue;
|
|
66
|
-
break;
|
|
67
|
-
case 'date': ///限制为日期,格式输出为YYYY-MM-DD
|
|
68
|
-
let date = Date.parse(value);
|
|
69
|
-
if (isNaN(date)) return defaultValue;
|
|
70
|
-
return moment(date).format('YYYY-MM-DD');
|
|
71
|
-
case 'datetime': ///限制为包含时间的日期
|
|
72
|
-
let datetime = Date.parse(value);
|
|
73
|
-
if (isNaN(datetime)) return defaultValue;
|
|
74
|
-
return datetime;
|
|
75
|
-
case 'array': ///返回数组
|
|
76
|
-
value= value.split(',');
|
|
77
|
-
}
|
|
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;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* 将原始值format后输出
|
|
98
|
-
* @param {*} value 123
|
|
99
|
-
* @param {*} format ${value}
|
|
100
|
-
* @returns
|
|
101
|
-
*/
|
|
102
|
-
module.exports.formatValue = (value, format)=> {
|
|
103
|
-
if (!format) return value;
|
|
104
|
-
return format.replace(/\${value}/ig,value)
|
|
105
|
-
// let formatItem = format.split('|');
|
|
106
|
-
// let coll = {};
|
|
107
|
-
// formatItem.forEach(item => {
|
|
108
|
-
// if (item == '') return;
|
|
109
|
-
// var itemValues = item.split(':');
|
|
110
|
-
// if (itemValues.length != 2) return;
|
|
111
|
-
// coll[itemValues[keyIndex]] = itemValues[1 - keyIndex];
|
|
112
|
-
// })
|
|
113
|
-
// //let jsonFormat =JSON.parse('{'+format+'}');
|
|
114
|
-
// return coll[value];
|
|
115
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
const { parseKeyValue, validatorParamsType } = require('./keywordparse');
|
|
2
|
-
const dataconfig = require('../configuration/dataconfig').getCurrent();
|
|
3
|
-
const mysql = require('mysql');
|
|
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;
|
|
6
|
-
|
|
7
|
-
function appendSearchCondition2Count(originSql, searchCondition) {
|
|
8
|
-
///如果包含了这个特定的字符,则替换
|
|
9
|
-
if (originSql.indexOf('#APPENDSEARCH#') >= 0)
|
|
10
|
-
return originSql.replace('#APPENDSEARCH#', searchCondition);
|
|
11
|
-
return originSql + ' ' + searchCondition;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* 检查是否有Sql注入的风险
|
|
15
|
-
* @param {*} sql
|
|
16
|
-
*/
|
|
17
|
-
function checkSqlInjection(sql) {
|
|
18
|
-
if (!sql) return sql;
|
|
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
|
-
return sql;
|
|
23
|
-
}
|
|
24
|
-
/*
|
|
25
|
-
* 根据对应列表的配置(dataConfig.list.search),从请求上下文中获取用户进行搜索的参数信息
|
|
26
|
-
*/
|
|
27
|
-
module.exports.getSearchCondition = (option) => {
|
|
28
|
-
let paraCopy = option || {};
|
|
29
|
-
if (!paraCopy.request || !paraCopy.refer) return '';
|
|
30
|
-
if (!paraCopy.valueFrom) paraCopy.valueFrom = "all";
|
|
31
|
-
const request = paraCopy.request;
|
|
32
|
-
let retSearch = [];
|
|
33
|
-
paraCopy.refer.forEach(element => {
|
|
34
|
-
retSearch.push(this.parseTagInSql(request, element.pattern, false));
|
|
35
|
-
});
|
|
36
|
-
return retSearch.join('');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 解析sql字符串中特殊的占位符
|
|
41
|
-
* @param {*} req
|
|
42
|
-
* @param {*} sql
|
|
43
|
-
* @param {*} allowNull
|
|
44
|
-
* @returns
|
|
45
|
-
*/
|
|
46
|
-
module.exports.parseTagInSql = (req, sql, allowNull = true) => {
|
|
47
|
-
if (!sql) return '';
|
|
48
|
-
///定义正则准备查找sql中的特定关键字
|
|
49
|
-
const matched = sql.match(/@.*?@/g);
|
|
50
|
-
if (!matched || matched.length <= 0) return sql;
|
|
51
|
-
let parseKeyWordIsNull = false;
|
|
52
|
-
|
|
53
|
-
const charReg = /\s+|:|=/gi
|
|
54
|
-
matched.forEach(ele => {
|
|
55
|
-
let matchValue = ele.substring(1, ele.length - 1);
|
|
56
|
-
///不允许特殊字符出现
|
|
57
|
-
let notdo = matchValue.match(charReg);
|
|
58
|
-
if (notdo && notdo.length > 0) return;
|
|
59
|
-
|
|
60
|
-
let noQuoteProtect = matchValue[0] == '!';
|
|
61
|
-
if (noQuoteProtect) {
|
|
62
|
-
matchValue = matchValue.substring(1);
|
|
63
|
-
}
|
|
64
|
-
///是否有格式要求
|
|
65
|
-
let validformat = matchValue.split('|');
|
|
66
|
-
matchValue = validformat[0];
|
|
67
|
-
let keyValue = (parseKeyValue(req, matchValue) || '')+''; //utility.ifNull(keyParse.parseKeyValue(req, matchValue), '')+'';
|
|
68
|
-
if (!keyValue) {
|
|
69
|
-
parseKeyWordIsNull = true;
|
|
70
|
-
} else if (typeof (keyValue) === 'string') {
|
|
71
|
-
keyValue = noQuoteProtect ? checkSqlInjection(mysql.escape(keyValue)) : mysql.escape(keyValue)
|
|
72
|
-
keyValue = keyValue.substr(1, keyValue.length - 2);
|
|
73
|
-
///验证参数的格式合法性
|
|
74
|
-
if (keyValue && validformat.length > 1) {
|
|
75
|
-
// console.log(`参数格式合法检查==>${validformat[1]}:${matchValue} = ${keyValue}`)
|
|
76
|
-
keyValue = validatorParamsType(keyValue, validformat[1], validformat[2])
|
|
77
|
-
}
|
|
78
|
-
if (!keyValue) {
|
|
79
|
-
parseKeyWordIsNull = true;
|
|
80
|
-
}
|
|
81
|
-
///没有引号保护下发现了sql注入,则用1=0不返回任何结果
|
|
82
|
-
if (!keyValue && noQuoteProtect) {
|
|
83
|
-
keyValue = '1=0'
|
|
84
|
-
}
|
|
85
|
-
} else { ////数组形式的参数,目前框架不支持,统一认为为sql注入攻击,全部忽略
|
|
86
|
-
// console.log(`参数非法==>类型${typeof (keyValue)}:${matchValue} = ${keyValue}`)
|
|
87
|
-
parseKeyWordIsNull = true;
|
|
88
|
-
keyValue = ''
|
|
89
|
-
}
|
|
90
|
-
sql = sql.replace(ele, keyValue);
|
|
91
|
-
});
|
|
92
|
-
if (!allowNull && parseKeyWordIsNull) return '';
|
|
93
|
-
return sql;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/*
|
|
97
|
-
* 列表请求上下文中获取需要的信息
|
|
98
|
-
* 如Page ,PageSize , Sort 等等
|
|
99
|
-
*/
|
|
100
|
-
module.exports.getListInfo = (req, dataKey, cfgType = 0, dao,ignorefilter=false) => {
|
|
101
|
-
if (!dataKey) return null;
|
|
102
|
-
///确认是否是需要导出Excel
|
|
103
|
-
const export2Excel = (req.query.exportexcel + "").toLowerCase() === "true";
|
|
104
|
-
let { page = 1, rows: pageSize = 100, sort, order, clientFilter: filter } = req.query
|
|
105
|
-
///防止sortSql 注入在排序的参数中
|
|
106
|
-
if (sort) sort = checkSqlInjection(sort);
|
|
107
|
-
// 防止页面数据传入非数字
|
|
108
|
-
if (isNaN(pageSize)) pageSize = 30;
|
|
109
|
-
// 防止页面数据传入非数字
|
|
110
|
-
if (!page || isNaN(page)) page = 1
|
|
111
|
-
///最大允许获取100条数据
|
|
112
|
-
pageSize =Math.max(0,Math.min(pageSize, 10000));
|
|
113
|
-
///拼接排序的语句
|
|
114
|
-
if (order && sort && ORDER_STRING.includes(order.toLowerCase())) sort = sort + ' ' + order
|
|
115
|
-
//req.order =req.sort? utility.ifNull((req.body.order || req.query.order), ""):'';
|
|
116
|
-
const dataConfig = dataconfig.getConfig(dataKey, cfgType);
|
|
117
|
-
if (dataConfig && dataConfig.list) {
|
|
118
|
-
req.dataConfig = dataConfig
|
|
119
|
-
let { sql, listsql, countsql, sqltype = 'sql', field, footer, search, sort: constsort } = dataConfig.list
|
|
120
|
-
/**解析查询条件 */
|
|
121
|
-
const searchCondition = ignorefilter?'':this.getSearchCondition({ request: req, refer: search });
|
|
122
|
-
/**排序方式 *///
|
|
123
|
-
sort = sort || constsort;
|
|
124
|
-
/**来自req请求参数中的过滤条件 */
|
|
125
|
-
let clientfilter = checkSqlInjection(this.parseTagInSql(req, filter, false));
|
|
126
|
-
//如果配置文件中不是直接的sql语句,则从DAO对象中的指定方法来获取sql
|
|
127
|
-
if (sqltype !== 'sql' && listsql && typeof (dao[listsql]) === 'function') {
|
|
128
|
-
sql = dao[sql](req, { page, rows: pageSize, sort, filter: searchCondition, client: clientfilter });
|
|
129
|
-
if (dao[countsql] && typeof (dao[countsql]) === 'function')
|
|
130
|
-
countsql = dao[countsql](req, { page, rows: pageSize, sort, filter: searchCondition, client: clientfilter });
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**根据过滤条件、排序条件、分页获取的方式,和原始sql拼接成最终获取数据的sql */
|
|
134
|
-
if (sqltype==='sql'){
|
|
135
|
-
sql = this.parseTagInSql(req, sql) +
|
|
136
|
-
' ' + searchCondition + clientfilter +
|
|
137
|
-
(sort ? (' order by ' + sort) : '') +
|
|
138
|
-
(export2Excel ? '' : ' limit ' + Number(pageSize) + ' OFFSET ' + (Math.max(Number(page), 1) - 1) * Number(pageSize)) +
|
|
139
|
-
/////在Sql中再放入获取总记录数的语句
|
|
140
|
-
';SELECT FOUND_ROWS() AS total;';
|
|
141
|
-
/*** 如果存在汇总列的sql,则把SQL放置在最末尾 */
|
|
142
|
-
if (countsql) {
|
|
143
|
-
sql += appendSearchCondition2Count(this.parseTagInSql(req, countsql), searchCondition)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return { sql, fields: field, footers: footer, page, hascounter: countsql?true:false };
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/*
|
|
150
|
-
* 详细页面请求上下文中获取需要的信息
|
|
151
|
-
* 如Page ,PageSize , Sort 等等
|
|
152
|
-
*/
|
|
153
|
-
module.exports.getDetailInfo = (req,dataKey) => {
|
|
154
|
-
if (dataKey) {
|
|
155
|
-
const dataConfig = dataconfig.getConfig(dataKey);
|
|
156
|
-
if (dataConfig && dataConfig.detail) {
|
|
157
|
-
req.dataConfig = dataConfig;
|
|
158
|
-
const { primary, field: fields, primaryIsAutoIncrease } = dataConfig.detail;
|
|
159
|
-
return { primary, fields, autoincrease: primaryIsAutoIncrease }
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return null;
|
|
163
|
-
}
|