doomiwork 3.7.12 → 4.0.0
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/configuration/appsetting.js +2 -6
- package/configuration/routerconfig.js +126 -128
- package/core/actionresult.js +1 -1
- package/core/controller.js +73 -72
- package/core/database/mysqlbase.js +17 -13
- package/core/database/poolmanager.js +11 -14
- package/core/doomiwork.js +36 -21
- package/index.js +3 -1
- package/package.json +3 -3
- package/utilities/excelutility.js +139 -0
- package/utilities/keywordparse.js +87 -42
- package/utilities/requestparser.js +139 -203
- package/utilities/tokenutility.js +30 -15
- package/utilities/transferutility.js +96 -128
- package/core/Interceptor.js +0 -14
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* configuration文件中AppSetting一节中的配置参数封装访问
|
|
3
|
-
*/
|
|
4
|
-
var utility = require('doomi-helper').commonHelper
|
|
5
|
-
const path = require('path');
|
|
1
|
+
const path = require('path');
|
|
6
2
|
const fs = require('fs');
|
|
7
3
|
class appsetting{
|
|
8
4
|
constructor(){
|
|
@@ -29,7 +25,7 @@ class appsetting{
|
|
|
29
25
|
getSetting (settingKey,defaultValue) {
|
|
30
26
|
if (!this.settingjson || !this.settingjson.appsetting) return defaultValue;
|
|
31
27
|
const item= this.settingjson.appsetting[settingKey];
|
|
32
|
-
return
|
|
28
|
+
return item??defaultValue;
|
|
33
29
|
}
|
|
34
30
|
getSection(sectionName){
|
|
35
31
|
return this.settingjson[sectionName];
|
|
@@ -1,144 +1,142 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* dataconfig配置文件的处理模块
|
|
3
3
|
*/
|
|
4
|
-
const fs
|
|
5
|
-
const path
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path')
|
|
6
6
|
////扫描Controller文件夹时需要排除的目录
|
|
7
|
-
const IGNORE_FOLDER = ["script","scripts","js","image","data","video","images","style","css","app_themes"];
|
|
8
|
-
|
|
9
|
-
constructor(routerfile) {
|
|
10
|
-
///路由的配置文件
|
|
11
|
-
let configfile = path.join(process.cwd(), routerfile || 'routerconfig.json');
|
|
12
|
-
if (fs.existsSync(configfile)) {
|
|
13
|
-
this.routerconfig = require(configfile);
|
|
14
|
-
} else {
|
|
15
|
-
this.routerconfig = [];
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* 单例模式
|
|
20
|
-
* @param {*} config
|
|
21
|
-
*/
|
|
22
|
-
static getInstance() {
|
|
23
|
-
if (!routerconfig.setting) routerconfig.setting = new routerconfig();
|
|
24
|
-
return routerconfig.setting;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* start all router in configuration
|
|
28
|
-
* @param {*} controllerconfig
|
|
29
|
-
* @param {*} providerCollection
|
|
30
|
-
*/
|
|
31
|
-
loadController(app,routelist) {
|
|
32
|
-
///定位置项目启动目录,准备遍历所有controller目录
|
|
33
|
-
let startupRoot = process.cwd();
|
|
34
|
-
let routes = routelist?routelist:this.routerconfig ;
|
|
35
|
-
|
|
36
|
-
routes.forEach(element => {
|
|
37
|
-
//if (!element.routers || element.routers.length == 0) return;
|
|
38
|
-
///路由被禁用,则略过
|
|
39
|
-
if (element.disabled) return;
|
|
40
|
-
///包含文件
|
|
41
|
-
if (element.include) {
|
|
42
|
-
var includeRouteJson = path.join(startupRoot, element.include);
|
|
43
|
-
///如果包含文件存在,则加载这个文件里面的路由
|
|
44
|
-
if (fs.existsSync(includeRouteJson)) {
|
|
45
|
-
this.loadController(app,require(includeRouteJson));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
var modules = [];
|
|
50
|
-
let {baseUrl,groupName } = element.routefolder?element.routefolder:element;
|
|
51
|
-
if (groupName && app.Interceptor[groupName]) app.use(baseUrl,app.Interceptor[groupName])
|
|
52
|
-
if (element.routefolder) {
|
|
53
|
-
if (element.routefolder.folder) this.loadFolderFiles4Router(modules, element.routefolder);
|
|
54
|
-
}
|
|
55
|
-
////单文件
|
|
56
|
-
else {
|
|
57
|
-
if (fs.existsSync(path.join(startupRoot, element.controller)))
|
|
58
|
-
modules.push(path.join(startupRoot, element.controller));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
////单个文件的加载
|
|
62
|
-
if (modules.length > 0) {
|
|
63
|
-
modules.forEach(modulePath => {
|
|
64
|
-
app.logger.trace('initlize controller [%s] for baseUrl [%s]',modulePath,baseUrl);
|
|
65
|
-
var controllModule = require(modulePath);
|
|
66
|
-
var controller = new controllModule(app);
|
|
67
|
-
app.use(baseUrl, controller.router);
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* 设置路由的认证中间组件
|
|
76
|
-
* @param {*} url
|
|
77
|
-
* @param {*} providerCollection
|
|
78
|
-
* @param {*} authorizeName
|
|
79
|
-
*/
|
|
80
|
-
// setAuthorizationProvider(app, url, authProvider) {
|
|
81
|
-
// ////该控制器下的所有路由需要身份验证
|
|
82
|
-
// if (authProvider)
|
|
83
|
-
// app.use(url, authProvider.module.checkAuthorization);
|
|
84
|
-
// }
|
|
85
|
-
/**
|
|
7
|
+
const IGNORE_FOLDER = ["script", "scripts", "js", "image", "data", "video", "images", "style", "css", "app_themes"];
|
|
8
|
+
/**
|
|
86
9
|
* 加载控制器目录下的所有JS文件形成路由
|
|
87
10
|
* @param {*} result
|
|
88
11
|
* @param {*} routeGroup
|
|
89
12
|
*/
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
13
|
+
function loadFolderFiles4Router(result, startPath, routeGroup) {
|
|
14
|
+
let exceptFile = routeGroup.exceptfile;
|
|
15
|
+
let exceptfolder = routeGroup.exceptfolder;
|
|
16
|
+
let scanFolder = path.join(startPath, routeGroup.folder);
|
|
17
|
+
getFolderControllerFiles(result, scanFolder, exceptFile, exceptfolder);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 遍历加载整个文件夹下面的所有文件形成路由
|
|
21
|
+
* @param {*} result
|
|
22
|
+
* @param {*} startPath
|
|
23
|
+
* @param {*} execfiles
|
|
24
|
+
* @param {*} execfolder
|
|
25
|
+
*/
|
|
26
|
+
function getFolderControllerFiles(result, startPath, execfiles, execfolder) {
|
|
27
|
+
let files = fs.readdirSync(startPath);
|
|
28
|
+
for (const val of files) {
|
|
29
|
+
let fPath = path.join(startPath, val);
|
|
30
|
+
let stats = fs.statSync(fPath);
|
|
31
|
+
////是个目录
|
|
32
|
+
if (stats.isDirectory()) {
|
|
33
|
+
if (execfolder == null || execfolder.indexOf(fileName) < 0)
|
|
34
|
+
findFolderFiles(result, fPath, fPath, execfiles, execfolder);
|
|
35
|
+
}
|
|
36
|
+
///是个文件
|
|
37
|
+
else if (stats.isFile()) {
|
|
38
|
+
let fileExtion = path.extname(fPath).toLowerCase();
|
|
39
|
+
if (fileExtion !== ".js") continue;
|
|
40
|
+
let fileName = path.basename(fPath);
|
|
41
|
+
fileName = fileName.substr(0, fileName.length - fileExtion.length);
|
|
42
|
+
if (!execfiles || execfiles.indexOf(fileName) < 0) result.push(fPath);
|
|
43
|
+
}
|
|
95
44
|
}
|
|
45
|
+
}
|
|
96
46
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
47
|
+
/**
|
|
48
|
+
* 遍历加载整个文件夹下面的所有文件形成路由
|
|
49
|
+
* @param {*} result
|
|
50
|
+
* @param {*} baseFolder
|
|
51
|
+
* @param {*} startPath
|
|
52
|
+
* @param {*} execfiles
|
|
53
|
+
* @param {*} execfolder
|
|
54
|
+
*/
|
|
55
|
+
function findFolderFiles(result, baseFolder, startPath, execfiles, execfolder) {
|
|
56
|
+
let files = fs.readdirSync(startPath);
|
|
57
|
+
// files.forEach((val) => {
|
|
58
|
+
for (const val of files) {
|
|
59
|
+
let fPath = path.join(startPath, val), stats = fs.statSync(fPath), fileName = fPath.substr(baseFolder.length + 1);
|
|
60
|
+
if (stats.isDirectory()) {
|
|
61
|
+
///排除基本的忽略目录
|
|
62
|
+
if (IGNORE_FOLDER.includes(fileName.toLowerCase())) continue;
|
|
63
|
+
if (execfolder == null || execfolder.indexOf(fileName) < 0)
|
|
64
|
+
findFolderFiles(result, baseFolder, fPath, execfiles, execfolder);
|
|
65
|
+
}
|
|
66
|
+
if (stats.isFile()) {
|
|
67
|
+
let fileExtion = path.extname(fPath).toLowerCase();
|
|
68
|
+
if (fileExtion != ".html") continue;
|
|
69
|
+
let fileName = fPath.substr(baseFolder.length + 1);
|
|
70
|
+
fileName = fileName.substr(0, fileName.length - fileExtion.length);
|
|
71
|
+
if (execfiles == null || execfiles.indexOf(fileName) < 0) result.push(fileName);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// class routerconfig {
|
|
76
|
+
// constructor(routerfile) {
|
|
77
|
+
// ///路由的配置文件
|
|
78
|
+
// let configfile = path.join(process.cwd(), routerfile || 'routerconfig.json');
|
|
79
|
+
// if (fs.existsSync(configfile)) {
|
|
80
|
+
// this.routerconfig = require(configfile);
|
|
81
|
+
// } else {
|
|
82
|
+
// this.routerconfig = [];
|
|
83
|
+
// }
|
|
84
|
+
// }
|
|
85
|
+
// /**
|
|
86
|
+
// * 单例模式
|
|
87
|
+
// * @param {*} config
|
|
88
|
+
// */
|
|
89
|
+
// static getInstance() {
|
|
90
|
+
// if (!routerconfig.setting) routerconfig.setting = new routerconfig();
|
|
91
|
+
// return routerconfig.setting;
|
|
92
|
+
// }
|
|
93
|
+
/**
|
|
94
|
+
* 加载应用下所有配置的controller文件
|
|
95
|
+
* @param {*} controllerconfig
|
|
96
|
+
* @param {*} providerCollection
|
|
97
|
+
*/
|
|
98
|
+
module.exports.loadController=(app, routes)=> {
|
|
99
|
+
///定位置项目启动目录,准备遍历所有controller目录
|
|
100
|
+
if (!Array.isArray(routes) || !routes.length) return;
|
|
101
|
+
let startupRoot = process.cwd();
|
|
102
|
+
//let routes = routelist?routelist:this.routerconfig ;
|
|
103
|
+
for (const element of routes) {
|
|
104
|
+
//if (!element.routers || element.routers.length == 0) return;
|
|
105
|
+
///路由被禁用,则略过
|
|
106
|
+
if (element.disabled) continue;
|
|
107
|
+
///包含文件
|
|
108
|
+
if (element.include) {
|
|
109
|
+
let includeRouteJson = path.join(startupRoot, element.include);
|
|
110
|
+
///如果包含文件存在,则加载这个文件里面的路由
|
|
111
|
+
if (fs.existsSync(includeRouteJson)) {
|
|
112
|
+
this.loadController(app, require(includeRouteJson));
|
|
108
113
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
let modules = [];
|
|
117
|
+
let { baseUrl, groupName } = element.routefolder ? element.routefolder : element;
|
|
118
|
+
if (groupName && app.Interceptor[groupName]) app.use(baseUrl, app.Interceptor[groupName])
|
|
119
|
+
if (element.routefolder) {
|
|
120
|
+
if (element.routefolder.folder) loadFolderFiles4Router(modules, startupRoot, element.routefolder);
|
|
115
121
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
* 遍历加载整个文件夹下面的所有文件形成路由
|
|
121
|
-
*/
|
|
122
|
-
findFolderFiles(result, baseFolder, startPath, execfiles, execfolder) {
|
|
123
|
-
let files = fs.readdirSync(startPath);
|
|
124
|
-
files.forEach((val) => {
|
|
125
|
-
let fPath = path.join(startPath, val);
|
|
126
|
-
let stats = fs.statSync(fPath);
|
|
127
|
-
let fileName = fPath.substr(baseFolder.length + 1);
|
|
128
|
-
if (stats.isDirectory()) {
|
|
129
|
-
///排除基本的忽略目录
|
|
130
|
-
if (IGNORE_FOLDER.indexOf(fileName.toLowerCase()) >= 0) return;
|
|
131
|
-
if (execfolder == null || execfolder.indexOf(fileName) < 0)
|
|
132
|
-
this.findFolderFiles(result, baseFolder, fPath, execfiles, execfolder);
|
|
122
|
+
////单文件
|
|
123
|
+
else {
|
|
124
|
+
if (fs.existsSync(path.join(startupRoot, element.controller)))
|
|
125
|
+
modules.push(path.join(startupRoot, element.controller));
|
|
133
126
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
127
|
+
////单个文件的加载
|
|
128
|
+
if (modules.length > 0) {
|
|
129
|
+
for (const modulePath of modules) {
|
|
130
|
+
if (app.logger) app.logger.trace('initlize controller [%s] for baseUrl [%s]', modulePath, baseUrl);
|
|
131
|
+
const controllModule = require(modulePath);
|
|
132
|
+
const controller = new controllModule(app);
|
|
133
|
+
app.use(baseUrl, controller.router);
|
|
134
|
+
}
|
|
135
|
+
|
|
140
136
|
}
|
|
141
|
-
}
|
|
137
|
+
}
|
|
142
138
|
}
|
|
143
139
|
}
|
|
144
|
-
|
|
140
|
+
|
|
141
|
+
// }
|
|
142
|
+
// module.exports = routerconfig;
|
package/core/actionresult.js
CHANGED
package/core/controller.js
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* 基类主要实现了数据基础的增删改查的基本操作,如无特殊业务逻辑子类已无需再
|
|
6
6
|
* 重新实现,如有特殊的业务可以重写几个方法
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const constEnum
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const exportUtility
|
|
8
|
+
const express = require('express');
|
|
9
|
+
const {Data2View,View2Data} = require('../utilities/transferutility');
|
|
10
|
+
const ExcelUtility = require('../utilities/excelutility');
|
|
11
|
+
const constEnum = require('./enumconst');
|
|
12
|
+
const { getListInfo, getDetailInfo, parseTagInSql } = require('../utilities/requestparser');
|
|
13
|
+
const apiResult = require('./actionresult');
|
|
14
|
+
const daoBase = require('./database/daoBase');
|
|
15
|
+
const exportUtility = ExcelUtility.getInstance();
|
|
16
16
|
|
|
17
17
|
class controller {
|
|
18
18
|
/**
|
|
@@ -22,14 +22,16 @@ class controller {
|
|
|
22
22
|
*/
|
|
23
23
|
constructor(application, dao) {
|
|
24
24
|
this.app = application;
|
|
25
|
-
|
|
25
|
+
///高速缓存
|
|
26
|
+
this._redisHelper = this.app.redis;
|
|
26
27
|
///日志记录器
|
|
27
28
|
this.logger = this.app.logger;
|
|
28
29
|
///用户行为记录器
|
|
29
|
-
this.actionLogger =
|
|
30
|
+
this.actionLogger = this.app.actionLogger;
|
|
30
31
|
///需要数据访问实体的实例
|
|
31
32
|
this._daoModel = dao?dao:new daoBase();
|
|
32
33
|
this._daoModel.actionLogger = this.actionLogger;
|
|
34
|
+
this._daoModel.logger = application.logger;
|
|
33
35
|
this._router = express.Router();
|
|
34
36
|
///实现的集成类中只需要去重写此方法
|
|
35
37
|
this.initializeRouter(this);
|
|
@@ -84,12 +86,6 @@ class controller {
|
|
|
84
86
|
result = await instance[actionType.func](req, datakey);
|
|
85
87
|
////执行完CRUD方法之后的处理
|
|
86
88
|
result = await instance.afterCRUD(result,actionType,datakey,url,req,res)
|
|
87
|
-
|
|
88
|
-
//CJJ add
|
|
89
|
-
// if (req.query.exportexcel === 'true' && result.buffer && result.successed) {
|
|
90
|
-
// res.attachment('export.xlsx');
|
|
91
|
-
// return res.end(result.buffer);
|
|
92
|
-
// }
|
|
93
89
|
return res.json(result)
|
|
94
90
|
})
|
|
95
91
|
}
|
|
@@ -105,7 +101,7 @@ class controller {
|
|
|
105
101
|
*/
|
|
106
102
|
initializeCRUDRouter(url, datakey, action = 'SCRUD', middleware){
|
|
107
103
|
if(!url || !datakey) return;
|
|
108
|
-
let urlWithId =
|
|
104
|
+
let urlWithId = url.endsWith('/')?`${url}:id`:`${url}/:id`;
|
|
109
105
|
if (action.indexOf('C') >= 0) this.createCRUDRoute(constEnum.CRUDAction.Create, url, datakey, middleware)
|
|
110
106
|
if (action.indexOf('S') >= 0) this.createCRUDRoute(constEnum.CRUDAction.Single, urlWithId, datakey, middleware)
|
|
111
107
|
if (action.indexOf('R') >= 0) this.createCRUDRoute(constEnum.CRUDAction.Retrieve, url, datakey, middleware)
|
|
@@ -118,7 +114,7 @@ class controller {
|
|
|
118
114
|
* @param {*} result
|
|
119
115
|
* @param {*} action
|
|
120
116
|
*/
|
|
121
|
-
async beforeCRUD(
|
|
117
|
+
async beforeCRUD(_action, _req,_res){
|
|
122
118
|
return {successed:true}
|
|
123
119
|
}
|
|
124
120
|
/**
|
|
@@ -126,7 +122,7 @@ class controller {
|
|
|
126
122
|
* @param {*} result
|
|
127
123
|
* @param {*} action
|
|
128
124
|
*/
|
|
129
|
-
async afterCRUD(result,
|
|
125
|
+
async afterCRUD(result,_action,_datakey,_url, _req,_res){
|
|
130
126
|
return result;
|
|
131
127
|
}
|
|
132
128
|
/*
|
|
@@ -134,12 +130,12 @@ class controller {
|
|
|
134
130
|
* 除了在routerConfig中配置的路由以外,继承的子类可以重写实现此方法来
|
|
135
131
|
* 继续配置你的路由
|
|
136
132
|
*/
|
|
137
|
-
initializeRouter(
|
|
133
|
+
initializeRouter(_instance) { }
|
|
138
134
|
/*
|
|
139
135
|
* 数据加载之前的动作
|
|
140
136
|
* 子类可以重写该方法
|
|
141
137
|
*/
|
|
142
|
-
async beforeAccessDB(
|
|
138
|
+
async beforeAccessDB(_req, sql, sqlParams, _type, _instance) {
|
|
143
139
|
return { sql: sql, sqlParams: sqlParams, canceled: false };
|
|
144
140
|
}
|
|
145
141
|
/**
|
|
@@ -156,7 +152,7 @@ class controller {
|
|
|
156
152
|
async batchUpdate(req,model,id){
|
|
157
153
|
if (!id) id = req.params.id;
|
|
158
154
|
if (!id) return {successed:false,errcode:-2,errmsg:'缺失批量操作的id'}
|
|
159
|
-
let batchSql =
|
|
155
|
+
let batchSql = parseTagInSql(req,this._daoModel.BatchSql());
|
|
160
156
|
let result = await this._daoModel.batchUpdate(batchSql, model, id, req.user?.id)
|
|
161
157
|
this.logUserAction(req,this._daoModel.getBusiness(),6,result.successed?0:-1);
|
|
162
158
|
return result;
|
|
@@ -165,13 +161,14 @@ class controller {
|
|
|
165
161
|
* 获取查询列表记录的方法
|
|
166
162
|
*/
|
|
167
163
|
async getListData(req, dataKey, configFile = 0) {
|
|
168
|
-
this.logger.trace("准备获取dataconfig文件中对应的 %s list数据",dataKey)
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
if (this.logger) this.logger.trace("准备获取dataconfig文件中对应的 %s list数据",dataKey)
|
|
165
|
+
const listinfo = getListInfo(req, dataKey, configFile,this._daoModel);
|
|
166
|
+
if (!listinfo) return { successed: false, errcode: -10, errmsg:`缺失${dataKey}对应的查询语句`};
|
|
167
|
+
|
|
171
168
|
////直接操作数据库之前,可由子类再次Handler
|
|
172
|
-
let beforeData = await this.beforeAccessDB(req,
|
|
169
|
+
let beforeData = await this.beforeAccessDB(req, listinfo.sql,null, "list", this);
|
|
173
170
|
////如果返回Null,则表示不加载数据了
|
|
174
|
-
if (beforeData.canceled
|
|
171
|
+
if (beforeData.canceled === true) return { successed: false, errorcode: 1, errmsg: "操作取消" };
|
|
175
172
|
////操作数据库
|
|
176
173
|
let result = await this._daoModel.loadData(beforeData.sql, beforeData.sqlParams);
|
|
177
174
|
if(!result.successed) {
|
|
@@ -179,49 +176,55 @@ class controller {
|
|
|
179
176
|
if (req.query.exportexcel==='true') this.logUserAction(req,this._daoModel.getBusiness(),5,-1);
|
|
180
177
|
return result;
|
|
181
178
|
}
|
|
182
|
-
|
|
179
|
+
///从数据库中获取到了原始数据
|
|
180
|
+
if (result.rows) {
|
|
183
181
|
///将从数据库中获得的结果集根据dataconfig中的配置进行映射转换
|
|
184
|
-
let resultItem =
|
|
185
|
-
///输出的结果是否需要装饰带有successed,total
|
|
186
|
-
|
|
187
|
-
let outputData = { "successed": true, page: req.page, rows: resultItem.data };
|
|
182
|
+
let resultItem = Data2View(result.rows[0], listinfo.fields)
|
|
183
|
+
///输出的结果是否需要装饰带有successed,total等,便于列表
|
|
184
|
+
let outputData = { successed: true, page: listinfo.page, rows: resultItem.data };
|
|
188
185
|
///需要进行尾部统计的列表
|
|
189
|
-
if (
|
|
190
|
-
let footerItem =
|
|
186
|
+
if (listinfo.hascounter) {
|
|
187
|
+
let footerItem = Data2View(result.rows[2], listinfo.footers)
|
|
191
188
|
outputData.footer = footerItem.data;
|
|
192
189
|
}
|
|
193
|
-
outputData.total = result
|
|
190
|
+
outputData.total = await this.getListRecordCount(result);
|
|
194
191
|
///处理导出Excel
|
|
195
192
|
if (req.query.exportexcel==='true') {
|
|
196
193
|
outputData= await this.export2Excel(outputData.rows,req.query.excelkey || dataKey)
|
|
197
194
|
this.logUserAction(req,this._daoModel.getBusiness(),5,0);
|
|
198
195
|
}
|
|
199
|
-
|
|
200
196
|
return outputData;
|
|
201
197
|
}
|
|
202
198
|
return {successed:false, errcode: -1, total: 0, rows: [] };
|
|
203
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* 返回数据结果的记录总数
|
|
202
|
+
* @param {*} data
|
|
203
|
+
*/
|
|
204
|
+
async getListRecordCount(data){
|
|
205
|
+
return result.rows[1][0].total;
|
|
206
|
+
}
|
|
204
207
|
/*
|
|
205
208
|
* 获取详细记录的方法
|
|
206
209
|
*/
|
|
207
210
|
async getDataById(req, dataKey, sqlCommand) {
|
|
208
|
-
this.logger.trace("准备获取dataconfig文件中对应的 %s 详细数据",dataKey)
|
|
209
|
-
|
|
210
|
-
|
|
211
|
+
if (this.logger) this.logger.trace("准备获取dataconfig文件中对应的 %s 详细数据",dataKey)
|
|
212
|
+
const detailinfo = getDetailInfo(dataKey);
|
|
213
|
+
if (!detailinfo) return { successed: false, errcode: -10, errmsg: `缺失${dataKey}对应的详情配置` };
|
|
211
214
|
let beforeData = await this.beforeAccessDB(req, sqlCommand || this._daoModel.getByIdSql(), req.params.id, "detail", this);
|
|
212
215
|
////如果返回Null,则表示不加载数据了
|
|
213
|
-
if (beforeData.canceled) return { successed: false, errorcode: 1, errormessage: "
|
|
216
|
+
if (beforeData.canceled===true) return { successed: false, errorcode: 1, errormessage: "操作已取消" };
|
|
214
217
|
/////处理SQL中的一些定义符
|
|
215
|
-
let parseSql =
|
|
218
|
+
let parseSql = parseTagInSql(req,beforeData.sql);
|
|
216
219
|
////操作数据库
|
|
217
220
|
let result = await this._daoModel.getBykey(parseSql, beforeData.sqlParams);
|
|
218
221
|
if (!result.successed) return result;
|
|
219
|
-
if (result.rows
|
|
222
|
+
if (result.rows && result.rows.length == 1) {
|
|
220
223
|
///如果对象有数据权限控制,则需要插入
|
|
221
224
|
///提交的权限设置
|
|
222
|
-
|
|
223
225
|
///将从数据库中获得的结果集根据dataconfig中的配置进行映射转换
|
|
224
|
-
let resultMapping =
|
|
226
|
+
let resultMapping = Data2View(result.rows, detailinfo.fields);
|
|
227
|
+
///如果业务对象具备权限控制的业务,则需要将该数据的所赋予的权限对象加载出来
|
|
225
228
|
if (this._daoModel.hasPermissionControl) {
|
|
226
229
|
const accessResult = await this._daoModel.getDataPermissionSetting(req.params.id,this.PermissonBusiness(req))
|
|
227
230
|
if (accessResult.successed) {
|
|
@@ -237,36 +240,34 @@ class controller {
|
|
|
237
240
|
* 新增实体记录的方法
|
|
238
241
|
*/
|
|
239
242
|
async create(req, dataKey, sqlCommand) {
|
|
240
|
-
this.logger.trace("准备根据dataconfig文件中对应的 %s 配置插入数据",dataKey)
|
|
241
|
-
let mapping = commonHelper.ifNull(req.query.Mapping, true);
|
|
242
|
-
let resultItem = { successed: true, data: req.body };
|
|
243
|
+
if (this.logger) this.logger.trace("准备根据dataconfig文件中对应的 %s 配置插入数据",dataKey)
|
|
244
|
+
let mapping = req.query.Mapping??true; //|| 'true'==='true' ;//commonHelper.ifNull(req.query.Mapping, true);
|
|
245
|
+
let detailinfo, resultItem = { successed: true, data: req.body };
|
|
243
246
|
///是否需要将data中的key-value值到配置文件中进行转换
|
|
244
247
|
if (mapping == true) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
resultItem =
|
|
248
|
+
detailinfo = getDetailInfo(dataKey);
|
|
249
|
+
if (!detailinfo) return { successed: false, errcode: -10, errmsg: `缺失${dataKey}对应的详情配置` };
|
|
250
|
+
resultItem = View2Data(req, detailinfo.fields, "create");
|
|
248
251
|
///如果转换的验证过程中出现错误,则返回
|
|
249
|
-
if (!resultItem.successed)
|
|
250
|
-
return resultItem;
|
|
251
|
-
}
|
|
252
|
+
if (!resultItem.successed) return resultItem;
|
|
252
253
|
}
|
|
253
254
|
let beforeData = await this.beforeAccessDB(req, sqlCommand || this._daoModel.insertSql(), resultItem.data, "create", this);
|
|
254
255
|
////如果返回Null,则表示不加载数据了
|
|
255
|
-
if (beforeData.canceled) return { successed: false, errorcode: 1, errormessage: "
|
|
256
|
-
this.logger.trace("插入数据准备 : ",beforeData)
|
|
256
|
+
if (beforeData.canceled) return { successed: false, errorcode: 1, errormessage: "操作取消" };
|
|
257
|
+
if (this.logger) this.logger.trace("插入数据准备 : ",beforeData)
|
|
257
258
|
let result = await this._daoModel.create(beforeData.sql, beforeData.sqlParams, req)
|
|
258
259
|
if(!result.successed) {
|
|
259
260
|
this.logUserAction(req,this._daoModel.getBusiness(),1,-1);
|
|
260
261
|
return result;
|
|
261
262
|
}
|
|
262
263
|
let primaryKey;
|
|
263
|
-
if (mapping &&
|
|
264
|
+
if (mapping && detailinfo.primary) {
|
|
264
265
|
///自动增长的主键字段
|
|
265
|
-
if (
|
|
266
|
+
if (detailinfo.autoincrease === true) primaryKey = result.rows.insertId;
|
|
266
267
|
else {
|
|
267
|
-
if (typeof (
|
|
268
|
-
if (typeof (
|
|
269
|
-
primaryKey =
|
|
268
|
+
if (typeof (detailinfo.primary) === "string") primaryKey = beforeData.sqlParams[detailinfo.primary];
|
|
269
|
+
if (typeof (detailinfo.primary) === "object")
|
|
270
|
+
primaryKey = detailinfo.primary.map(element => { return beforeData.sqlParams[element]; });
|
|
270
271
|
}
|
|
271
272
|
}
|
|
272
273
|
///如果对象有数据权限控制,则需要插入
|
|
@@ -290,24 +291,24 @@ class controller {
|
|
|
290
291
|
* 修改实体记录的方法
|
|
291
292
|
*/
|
|
292
293
|
async update(req, dataKey, sqlCommand, id) {
|
|
293
|
-
this.logger.trace("准备根据dataconfig文件中对应的 %s 配置修改数据",dataKey)
|
|
294
|
+
if (this.logger) this.logger.trace("准备根据dataconfig文件中对应的 %s 配置修改数据",dataKey)
|
|
294
295
|
if (id == null) id = req.params.id;
|
|
295
|
-
let mapping = commonHelper.ifNull(req.query.Mapping, true);
|
|
296
|
-
|
|
296
|
+
let mapping = req.query.Mapping??true;// commonHelper.ifNull(req.query.Mapping, true);
|
|
297
|
+
let detailinfo, resultItem = { successed: true, data: req.body };
|
|
297
298
|
///是否需要将data中的key-value值到配置文件中进行转换
|
|
298
299
|
if (mapping == true) {
|
|
299
|
-
|
|
300
|
-
|
|
300
|
+
detailinfo = getDetailInfo(dataKey);
|
|
301
|
+
if (!detailinfo) return { successed: false, errcode: -10, errmsg: `缺失${dataKey}对应的详情配置` };
|
|
301
302
|
///从Request中获取到用户提交的数据
|
|
302
|
-
resultItem =
|
|
303
|
+
resultItem = View2Data(req, detailinfo.fields, "update");
|
|
303
304
|
}
|
|
304
305
|
///如果不需要转换,则直接使用前端提交上来的值
|
|
305
306
|
let beforeData = await this.beforeAccessDB(req, sqlCommand || this._daoModel.updateSql(), resultItem.data, "update", this);
|
|
306
307
|
////如果返回Null,则表示不加载数据了
|
|
307
|
-
if (beforeData.canceled) return { successed: false, errorcode: 1, errormessage: "
|
|
308
|
-
this.logger.trace("修改数据准备 : ",beforeData)
|
|
308
|
+
if (beforeData.canceled) return { successed: false, errorcode: 1, errormessage: "操作取消" };
|
|
309
|
+
if (this.logger) this.logger.trace("修改数据准备 : ",beforeData)
|
|
309
310
|
/////处理SQL中的一些定义符
|
|
310
|
-
let parseSql =
|
|
311
|
+
let parseSql = parseTagInSql(req,beforeData.sql);
|
|
311
312
|
let result = await this._daoModel.update(parseSql, beforeData.sqlParams, id);
|
|
312
313
|
if(!result.successed) {
|
|
313
314
|
this.logUserAction(req,this._daoModel.getBusiness(),3,-1);
|
|
@@ -340,12 +341,12 @@ class controller {
|
|
|
340
341
|
* 删除实体记录的方法
|
|
341
342
|
*/
|
|
342
343
|
async delete(req, id, sqlCommand) {
|
|
343
|
-
this.logger.trace("准备删除数据",id)
|
|
344
|
+
if (this.logger) this.logger.trace("准备删除数据",id)
|
|
344
345
|
let beforeData = await this.beforeAccessDB(req, sqlCommand || this._daoModel.deleteSql(), id, "delete", this);
|
|
345
346
|
////如果返回Null,则表示不加载数据了
|
|
346
|
-
if (beforeData.canceled) return { successed: false, errorcode: 1, errormessage: "
|
|
347
|
+
if (beforeData.canceled) return { successed: false, errorcode: 1, errormessage: "操作取消" };
|
|
347
348
|
/////处理SQL中的一些定义符
|
|
348
|
-
let parseSql =
|
|
349
|
+
let parseSql = parseTagInSql(req,beforeData.sql);
|
|
349
350
|
////操作数据库
|
|
350
351
|
let result = await this._daoModel.delete(parseSql, beforeData.sqlParams,req.user?.id)
|
|
351
352
|
if(!result.successed) {
|