chanjs 1.0.23 → 1.0.25
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/README.md +20 -18
- package/core/chan.js +90 -79
- package/core/lib/config/config.js +6 -0
- package/core/lib/controller/controller.js +15 -20
- package/core/lib/extend/bindClass.js +14 -15
- package/core/lib/extend/router.js +15 -16
- package/core/lib/index.js +9 -9
- package/core/lib/middleware/template.js +25 -6
- package/core/lib/service/service.js +189 -190
- package/package.json +3 -2
package/README.md
CHANGED
@@ -34,7 +34,7 @@ Chan.js 基于express 纯js研发的轻量级mvc框架。基于函数式编程
|
|
34
34
|
|- extend 扩展
|
35
35
|
|- middleware 中间件
|
36
36
|
|- plugin 插件
|
37
|
-
|
37
|
+
|- plus-module1 插件1
|
38
38
|
|- controller 控制器
|
39
39
|
|- service 服务模型
|
40
40
|
|- view 视图模板
|
@@ -67,28 +67,30 @@ Chan.js 基于express 纯js研发的轻量级mvc框架。基于函数式编程
|
|
67
67
|
### 官网
|
68
68
|
|
69
69
|
基于Chanjs开发的cms系统
|
70
|
-
|
70
|
+
网址:<https://www.chancms.top>
|
71
71
|
|
72
|
-
|
73
72
|
### 特点
|
74
73
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
74
|
+
- 配置文件
|
75
|
+
- 多模块mvc
|
76
|
+
- 插件mvc
|
77
|
+
- 支持cors跨域配置
|
78
|
+
- mysql数据库支持
|
79
|
+
- 路由控制
|
80
|
+
- art-template模板
|
81
|
+
- 静态资源
|
82
|
+
- cookie
|
83
|
+
- 日志功能
|
87
84
|
|
88
85
|
### 运行
|
89
86
|
|
90
87
|
```javascript
|
91
|
-
const Chan = require('
|
92
|
-
const
|
93
|
-
|
88
|
+
const Chan = require('Chan');
|
89
|
+
const chan = new Chan();
|
90
|
+
//加载中间件
|
91
|
+
chan.beforeStart(fn);
|
92
|
+
//加载模块
|
93
|
+
chan.start();
|
94
|
+
//启动服务
|
95
|
+
chan.run();
|
94
96
|
```
|
package/core/chan.js
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
const express = require("express");
|
2
2
|
const config = require("./lib/config/config.js");
|
3
3
|
const bindClass = require("./lib/extend/bindClass.js");
|
4
|
-
const Controller = require("./lib/controller/controller.js")
|
5
|
-
const Service = require("./lib/service/service.js")
|
4
|
+
const Controller = require("./lib/controller/controller.js");
|
5
|
+
const Service = require("./lib/service/service.js");
|
6
6
|
const path = require("path");
|
7
7
|
const fs = require("fs");
|
8
8
|
const core = require("./lib/index.js");
|
9
|
-
const cors = require(
|
9
|
+
const cors = require("cors");
|
10
10
|
|
11
11
|
/**
|
12
12
|
* @description 基于express封装的mvc框架,遵循约定优于配置原则
|
@@ -15,20 +15,22 @@ class Chan {
|
|
15
15
|
static config = {};
|
16
16
|
//模块
|
17
17
|
static modules = {};
|
18
|
-
|
18
|
+
//插件
|
19
19
|
static plugins = {};
|
20
|
-
|
20
|
+
//工具
|
21
21
|
static helper = {};
|
22
22
|
static Controller = null;
|
23
23
|
static Service = null;
|
24
|
-
constructor(options={}) {
|
24
|
+
constructor(options = {}) {
|
25
25
|
//配置
|
26
|
-
Chan.config = {...config
|
26
|
+
Chan.config = { ...config, ...options };
|
27
27
|
//控制器基类
|
28
28
|
Chan.Controller = Controller;
|
29
|
-
|
29
|
+
this.init();
|
30
|
+
}
|
31
|
+
|
32
|
+
init() {
|
30
33
|
this.app = express();
|
31
|
-
// this.app.config = Chan.config;
|
32
34
|
this.router = express.Router();
|
33
35
|
//加载配置
|
34
36
|
this.loadConfig();
|
@@ -38,19 +40,8 @@ class Chan {
|
|
38
40
|
this.loadCore();
|
39
41
|
//加载实例化数据库
|
40
42
|
this.loadKnex();
|
41
|
-
|
42
|
-
//生命周期钩子:开始启动
|
43
|
-
this.beforeStart();
|
44
43
|
//解决跨域
|
45
44
|
this.loadCors();
|
46
|
-
//加载模块
|
47
|
-
this.loadModules();
|
48
|
-
//加载插件
|
49
|
-
this.loadPlugins();
|
50
|
-
//加载通用路由
|
51
|
-
this.loadCommonRouter();
|
52
|
-
//生命周期:初始化完成
|
53
|
-
this.start()
|
54
45
|
}
|
55
46
|
|
56
47
|
// 加载配置
|
@@ -58,14 +49,12 @@ class Chan {
|
|
58
49
|
const configPath = path.join(Chan.config.APP_PATH, "config/index.js");
|
59
50
|
if (fs.existsSync(configPath)) {
|
60
51
|
const config = require(configPath);
|
61
|
-
|
62
|
-
// this.app.config = Chan.config = allConfig;
|
63
|
-
Chan.config = {...Chan.config,...config};
|
52
|
+
Chan.config = { ...Chan.config, ...config };
|
64
53
|
}
|
65
54
|
}
|
66
55
|
|
67
|
-
|
68
|
-
|
56
|
+
// 加载扩展
|
57
|
+
loadExtends() {
|
69
58
|
const extendPath = path.join(Chan.config.APP_PATH, "extend");
|
70
59
|
if (fs.existsSync(extendPath)) {
|
71
60
|
let controllers = fs
|
@@ -78,20 +67,19 @@ class Chan {
|
|
78
67
|
Chan.helper[fileName] = helper;
|
79
68
|
}
|
80
69
|
}
|
81
|
-
|
82
70
|
}
|
83
71
|
|
84
72
|
//数据库操作
|
85
|
-
loadKnex(){
|
73
|
+
loadKnex() {
|
86
74
|
// 连接数据库
|
87
75
|
const {
|
88
|
-
host=
|
89
|
-
port=
|
76
|
+
host = "localhost",
|
77
|
+
port = "3306",
|
90
78
|
user,
|
91
79
|
password,
|
92
80
|
database,
|
93
|
-
client=
|
94
|
-
charset=
|
81
|
+
client = "mysql2",
|
82
|
+
charset = "utf8mb4",
|
95
83
|
} = Chan.config.database;
|
96
84
|
|
97
85
|
const knex = require("knex")({
|
@@ -104,7 +92,7 @@ class Chan {
|
|
104
92
|
database,
|
105
93
|
charset,
|
106
94
|
},
|
107
|
-
debug: Chan.config.
|
95
|
+
debug: Chan.config.SqlDebug, //指明是否开启debug模式,默认为true表示开启
|
108
96
|
pool: {
|
109
97
|
//指明数据库连接池的大小,默认为{min: 2, max: 10}
|
110
98
|
min: 0,
|
@@ -131,80 +119,93 @@ class Chan {
|
|
131
119
|
// 初始化一些配置
|
132
120
|
cb && cb();
|
133
121
|
}
|
134
|
-
|
135
122
|
//启动
|
136
|
-
start(cb){
|
123
|
+
start(cb) {
|
124
|
+
//加载模块
|
125
|
+
this.loadModules();
|
126
|
+
//加载插件
|
127
|
+
this.loadPlugins();
|
128
|
+
//加载通用路由
|
129
|
+
this.loadCommonRouter();
|
137
130
|
// 初始化一些配置
|
138
131
|
cb && cb();
|
139
132
|
}
|
140
133
|
|
141
134
|
//解决跨域
|
142
|
-
loadCors(){
|
143
|
-
|
135
|
+
loadCors() {
|
136
|
+
Chan.config?.cors?.origin && this.app.use(cors(Chan.config.cors));
|
144
137
|
}
|
145
138
|
|
146
139
|
// 加载插件
|
147
140
|
loadPlugins() {
|
148
|
-
this.loadModules(
|
141
|
+
this.loadModules("plugins");
|
149
142
|
}
|
150
143
|
|
151
144
|
/**
|
152
145
|
* @description app核心模块:日志、favicon 图标、cookie、json、url、模板引擎、静态资源
|
153
146
|
*/
|
154
|
-
loadCore(){
|
155
|
-
console.log()
|
147
|
+
loadCore() {
|
156
148
|
core(this.app, Chan.config);
|
157
149
|
}
|
158
150
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
loadModules(modules=
|
163
|
-
const configPath = path.join(Chan.config.APP_PATH,modules);
|
151
|
+
/**
|
152
|
+
* @description 模块加载入口(路由&控制器& 服务)
|
153
|
+
*/
|
154
|
+
loadModules(modules = "modules") {
|
155
|
+
const configPath = path.join(Chan.config.APP_PATH, modules);
|
164
156
|
if (fs.existsSync(configPath)) {
|
165
157
|
const dirs = fs
|
166
158
|
.readdirSync(configPath, { withFileTypes: true })
|
167
159
|
.filter((dirent) => dirent.isDirectory())
|
168
160
|
.map((dirent) => dirent.name);
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
}
|
176
|
-
|
177
|
-
|
161
|
+
Chan[modules] = {};
|
162
|
+
|
163
|
+
// 先加载所有服务
|
164
|
+
dirs.forEach((item) => {
|
165
|
+
Chan[modules][item] = {
|
166
|
+
service: {},
|
167
|
+
controller: {},
|
168
|
+
};
|
169
|
+
this.loadServices(modules, item);
|
170
|
+
});
|
171
|
+
|
172
|
+
// 加载控制器和路由
|
173
|
+
dirs.forEach((item) => {
|
174
|
+
this.loadModule(modules, item);
|
175
|
+
});
|
176
|
+
|
178
177
|
//执行路由
|
179
178
|
// this.app.use(this.router);
|
180
179
|
}
|
181
180
|
}
|
182
181
|
|
183
|
-
|
184
182
|
/**
|
185
|
-
* @description 加载模块,包括 controller service router
|
183
|
+
* @description 加载模块,包括 controller service router
|
186
184
|
* @param {String} moduleName 模块名称
|
187
185
|
*/
|
188
|
-
loadModule(modules,moduleName) {
|
189
|
-
this.
|
190
|
-
this.
|
191
|
-
this.loadRoutes(modules,moduleName);
|
186
|
+
loadModule(modules, moduleName) {
|
187
|
+
this.loadControllers(modules, moduleName);
|
188
|
+
this.loadRoutes(modules, moduleName);
|
192
189
|
}
|
193
190
|
|
194
|
-
|
195
191
|
/**
|
196
192
|
* @description 扫描模块下所有service
|
197
193
|
* @param {*} moduleDir 模块路径
|
198
194
|
* @param {*} moduleName 模块名称
|
199
195
|
*/
|
200
|
-
loadServices(modules,moduleName) {
|
201
|
-
const servicesDir = path.join(
|
196
|
+
loadServices(modules, moduleName) {
|
197
|
+
const servicesDir = path.join(
|
198
|
+
Chan.config.APP_PATH,
|
199
|
+
modules,
|
200
|
+
moduleName,
|
201
|
+
"service"
|
202
|
+
);
|
202
203
|
if (fs.existsSync(servicesDir)) {
|
203
204
|
let services = fs
|
204
205
|
.readdirSync(servicesDir)
|
205
206
|
.filter((file) => file.endsWith(".js"));
|
206
207
|
for (let i = 0, file; i < services.length; i++) {
|
207
|
-
file= services[i]
|
208
|
+
file = services[i];
|
208
209
|
const Service = require(path.join(servicesDir, file));
|
209
210
|
const serviceName = file.replace(".js", "");
|
210
211
|
//模块文件夹-模块文件名-服务-方法
|
@@ -214,24 +215,29 @@ class Chan {
|
|
214
215
|
}
|
215
216
|
}
|
216
217
|
|
217
|
-
|
218
218
|
/**
|
219
219
|
* @description 扫描模块下所有controller
|
220
220
|
* @param {*} moduleDir 模块路径
|
221
221
|
* @param {*} moduleName 模块名称
|
222
222
|
*/
|
223
|
-
loadControllers(modules,moduleName) {
|
224
|
-
const controllersDir = path.join(
|
223
|
+
loadControllers(modules, moduleName) {
|
224
|
+
const controllersDir = path.join(
|
225
|
+
Chan.config.APP_PATH,
|
226
|
+
modules,
|
227
|
+
moduleName,
|
228
|
+
"controller"
|
229
|
+
);
|
225
230
|
if (fs.existsSync(controllersDir)) {
|
226
231
|
let controllers = fs
|
227
232
|
.readdirSync(controllersDir)
|
228
233
|
.filter((file) => file.endsWith(".js"));
|
229
234
|
for (let i = 0, file; i < controllers.length; i++) {
|
230
|
-
file= controllers[i]
|
235
|
+
file = controllers[i];
|
231
236
|
const controller = require(path.join(controllersDir, file));
|
232
237
|
const controllerName = file.replace(".js", "");
|
233
238
|
Chan[modules][moduleName].controller[controllerName] = {};
|
234
|
-
Chan[modules][moduleName].controller[controllerName] =
|
239
|
+
Chan[modules][moduleName].controller[controllerName] =
|
240
|
+
bindClass(controller);
|
235
241
|
}
|
236
242
|
}
|
237
243
|
}
|
@@ -241,33 +247,38 @@ class Chan {
|
|
241
247
|
* @param {*} moduleDir 模块路径
|
242
248
|
* @param {*} moduleName 模块名称
|
243
249
|
*/
|
244
|
-
loadRoutes(modules,moduleName) {
|
245
|
-
const routersDir = path.join(
|
250
|
+
loadRoutes(modules, moduleName) {
|
251
|
+
const routersDir = path.join(
|
252
|
+
Chan.config.APP_PATH,
|
253
|
+
modules,
|
254
|
+
moduleName,
|
255
|
+
"router.js"
|
256
|
+
);
|
246
257
|
if (fs.existsSync(routersDir)) {
|
247
258
|
const routes = require(routersDir);
|
248
|
-
routes({router:this.router,modules:Chan[modules],app:this.app});
|
259
|
+
routes({ router: this.router, modules: Chan[modules], app: this.app });
|
249
260
|
}
|
250
261
|
}
|
251
262
|
|
252
|
-
|
253
|
-
loadCommonRouter(){
|
263
|
+
//通用路由,加载错误处理和500路由和爬虫处理
|
264
|
+
loadCommonRouter() {
|
254
265
|
try {
|
255
266
|
const baseRouterPath = path.join(Chan.config.APP_PATH, "router.js");
|
256
267
|
if (fs.existsSync(baseRouterPath)) {
|
257
268
|
const _router = require(baseRouterPath);
|
258
|
-
_router(this.app, this.router,Chan.config);
|
259
|
-
}
|
269
|
+
_router(this.app, this.router, Chan.config);
|
270
|
+
}
|
260
271
|
} catch (error) {
|
261
272
|
console.log(error);
|
262
273
|
}
|
263
274
|
}
|
264
|
-
|
275
|
+
|
265
276
|
run() {
|
266
|
-
const port = Chan.config.port ||
|
277
|
+
const port = Chan.config.port || "81";
|
267
278
|
this.app.listen(port, () => {
|
268
279
|
console.log(`Server is running on port ${port}`);
|
269
280
|
});
|
270
281
|
}
|
271
282
|
}
|
272
|
-
|
273
|
-
module.exports = Chan;
|
283
|
+
global.Chan = Chan;
|
284
|
+
module.exports = Chan;
|
@@ -12,12 +12,18 @@ const APP_PATH = path.join(ROOT_PATH, 'app');
|
|
12
12
|
|
13
13
|
let config = {
|
14
14
|
JSON_LIMIT:"100kb",
|
15
|
+
SqlDebug:true,
|
15
16
|
logger : {
|
16
17
|
level: 'dev',
|
17
18
|
},
|
18
19
|
env:'dev',
|
19
20
|
template:'default',
|
20
21
|
views:[], //模板路径
|
22
|
+
static:[{ //静态文件路径
|
23
|
+
prefix: "/public/",
|
24
|
+
dir: ["app/public"],
|
25
|
+
maxAge: 0,
|
26
|
+
}],
|
21
27
|
database:{
|
22
28
|
client: "mysql2",
|
23
29
|
host: "localhost",
|
@@ -2,29 +2,24 @@
|
|
2
2
|
* @description
|
3
3
|
* 控制器基类
|
4
4
|
*/
|
5
|
-
class Controller{
|
5
|
+
class Controller {
|
6
|
+
constructor() {}
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
download(res, file) {
|
9
|
+
res.download(file);
|
10
|
+
}
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
success(res, data = null) {
|
13
|
+
res.json({ code: 200, msg: "success", data: data });
|
14
|
+
}
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
fail(res, msg = "操作失败,请稍后再试") {
|
17
|
+
res.json({ code: 400, msg: msg });
|
18
|
+
}
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
error(res,msg){
|
24
|
-
res.json({code:500,msg:msg})
|
25
|
-
}
|
20
|
+
error(res, msg) {
|
21
|
+
res.json({ code: 500, msg: msg });
|
22
|
+
}
|
26
23
|
}
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
module.exports = Controller;
|
25
|
+
module.exports = Controller;
|
@@ -4,20 +4,19 @@
|
|
4
4
|
*@returns {Object} 包含绑定方法的对象。
|
5
5
|
*/
|
6
6
|
function bindClass(className) {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
}
|
7
|
+
let obj = {};
|
8
|
+
const cls = new className();
|
9
|
+
Object.getOwnPropertyNames(cls.constructor.prototype).forEach(
|
10
|
+
(methodName) => {
|
11
|
+
if (
|
12
|
+
methodName !== "constructor" &&
|
13
|
+
typeof cls[methodName] === "function"
|
14
|
+
) {
|
15
|
+
obj[methodName] = cls[methodName].bind(cls);
|
17
16
|
}
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
}
|
18
|
+
);
|
19
|
+
return obj;
|
20
|
+
}
|
21
21
|
|
22
|
-
|
23
|
-
module.exports = bindClass;
|
22
|
+
module.exports = bindClass;
|
@@ -1,17 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
1
|
module.exports = {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
}
|
17
|
-
|
2
|
+
/**
|
3
|
+
* @description 给路由加前缀
|
4
|
+
* @returns viod 0
|
5
|
+
*/
|
6
|
+
addRoutePrefix: () => {
|
7
|
+
return function (req, res, next) {
|
8
|
+
req.baseUrl = `${prefix}${req.baseUrl || ""}`;
|
9
|
+
// 如果有 query 参数,则保留原有参数
|
10
|
+
req.url = `${req.baseUrl}${
|
11
|
+
req.url.includes("?") ? req.url.split("?")[1] : ""
|
12
|
+
}`;
|
13
|
+
next();
|
14
|
+
};
|
15
|
+
},
|
16
|
+
};
|
package/core/lib/index.js
CHANGED
@@ -4,8 +4,8 @@ const favicon = require("serve-favicon");
|
|
4
4
|
const morgan = require("morgan");
|
5
5
|
const path = require("path");
|
6
6
|
const template = require("./middleware/template.js");
|
7
|
-
module.exports = async function (app,config) {
|
8
|
-
const { logger, APP_PATH, cookieKey,
|
7
|
+
module.exports = async function (app, config) {
|
8
|
+
const { logger, APP_PATH, cookieKey, static, JSON_LIMIT, appName, version } =
|
9
9
|
config;
|
10
10
|
//日志
|
11
11
|
app.use(morgan(logger.level));
|
@@ -21,15 +21,15 @@ module.exports = async function (app,config) {
|
|
21
21
|
app.use(express.urlencoded({ extended: false }));
|
22
22
|
|
23
23
|
//配置模板引擎
|
24
|
-
template(app,config);
|
24
|
+
template(app, config);
|
25
25
|
|
26
26
|
//使用静态资源 ,
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
maxAge: maxAge
|
31
|
-
})
|
32
|
-
|
27
|
+
if (static.length > 0) {
|
28
|
+
static.forEach((item) => {
|
29
|
+
const { prefix, dir, maxAge } = item;
|
30
|
+
app.use(prefix, express.static(dir, { maxAge: maxAge || 0 }));
|
31
|
+
});
|
32
|
+
}
|
33
33
|
|
34
34
|
//设置头信息
|
35
35
|
app.use((req, res, next) => {
|
@@ -1,15 +1,34 @@
|
|
1
1
|
const path = require("path");
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
const template = require("art-template");
|
3
|
+
const dayjs = require("dayjs");
|
4
|
+
|
5
|
+
// 注册 dateFormat 函数
|
6
|
+
template.defaults.imports.dateFormat = function (date, format) {
|
7
|
+
if (!date) {
|
8
|
+
return "";
|
9
|
+
}
|
10
|
+
// 如果传入的是一个 Date 对象,转换为 dayjs 对象
|
11
|
+
if (
|
12
|
+
date instanceof Date ||
|
13
|
+
typeof date === "string" ||
|
14
|
+
typeof date === "number"
|
15
|
+
) {
|
16
|
+
date = dayjs(date);
|
17
|
+
} else {
|
18
|
+
return "";
|
19
|
+
}
|
20
|
+
return date.format(format);
|
21
|
+
};
|
22
|
+
module.exports = (app, config) => {
|
23
|
+
const { APP_PATH, views, env } = config;
|
5
24
|
//默认home view
|
6
25
|
const home = path.join(APP_PATH, `modules/web/view`);
|
7
26
|
//合并插件中的view
|
8
27
|
const all = [...views, home];
|
9
|
-
|
28
|
+
|
10
29
|
app.set("view options", {
|
11
|
-
debug: env
|
12
|
-
cache: env
|
30
|
+
debug: env === "dev",
|
31
|
+
cache: env === "prd",
|
13
32
|
minimize: true,
|
14
33
|
});
|
15
34
|
app.set("view engine", "html");
|
@@ -1,195 +1,194 @@
|
|
1
1
|
class BaseService {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
insert(params)
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
}
|
2
|
+
/**
|
3
|
+
* @description 构造函数
|
4
|
+
* @param {*} knex - knex实例
|
5
|
+
* @param {*} model - 模型名称
|
6
|
+
*/
|
7
|
+
constructor(knex, model = "") {
|
8
|
+
this.knex = knex;
|
9
|
+
this.model = model;
|
10
|
+
}
|
11
|
+
|
12
|
+
/**
|
13
|
+
* @description 查找所有符合条件的记录
|
14
|
+
* @param {*} query - 查询条件,例如:{name: 'test', age: 18}
|
15
|
+
* @returns {Promise} 返回符合条件的记录
|
16
|
+
*/
|
17
|
+
query(query) {
|
18
|
+
return this.knex(this.model).where(query);
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* @description 查询表所有记录,慎用
|
23
|
+
* @returns {Promise} 返回所有记录
|
24
|
+
*/
|
25
|
+
all() {
|
26
|
+
return this.knex(this.model).select();
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* @description 查询指定id的记录
|
31
|
+
* @param {*} id
|
32
|
+
* @returns {Promise} 返回指定id的记录
|
33
|
+
*/
|
34
|
+
findById(id) {
|
35
|
+
return this.knex(this.model).where("id", id).first();
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @description 查询分页数据
|
40
|
+
* @param {*} current
|
41
|
+
* @param {*} pageSize
|
42
|
+
* @param {*} query
|
43
|
+
* @returns {Promise} 返回分页数据
|
44
|
+
*/
|
45
|
+
async findListAndQuery(current = 1, pageSize = 10, query = {}) {
|
46
|
+
const offset = (current - 1) * pageSize;
|
47
|
+
|
48
|
+
let countQuery = this.knex(this.model).count("* as total");
|
49
|
+
let dataQuery = this.knex(this.model);
|
50
|
+
|
51
|
+
// 应用查询条件
|
52
|
+
for (const key in query) {
|
53
|
+
dataQuery = dataQuery.where(key, query[key]);
|
54
|
+
countQuery = countQuery.where(key, query[key]);
|
55
|
+
}
|
56
|
+
|
57
|
+
// 获取总记录数
|
58
|
+
const total = await countQuery.first();
|
59
|
+
|
60
|
+
// 获取分页数据
|
61
|
+
const data = await dataQuery.offset(offset).limit(pageSize);
|
62
|
+
|
63
|
+
return { data, total: parseInt(total.total, 10) };
|
64
|
+
}
|
65
|
+
|
66
|
+
/**
|
67
|
+
* @description 查询指定id的记录
|
68
|
+
* @param {*} id - 记录id
|
69
|
+
* @returns {Promise} 返回指定id的记录
|
70
|
+
*/
|
71
|
+
findOneById(id) {
|
72
|
+
return this.knex(this.model).where("id", id).select();
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* @description 查询指定条件的记录
|
77
|
+
* @param {Object} query - {<key>:<value>}
|
78
|
+
* @returns {Promise} 返回指定条件的记录
|
79
|
+
*/
|
80
|
+
findOne(query) {
|
81
|
+
return this.knex(this.model).where(query).first();
|
82
|
+
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* @description 更新指定id的记录
|
86
|
+
* @param {*} id - 记录id
|
87
|
+
* @param {*} params - {<key>:<value>}
|
88
|
+
* @returns {Promise} 返回更新后的记录
|
89
|
+
*/
|
90
|
+
findOneAndUpdate(id, params) {
|
91
|
+
return this.knex(this.model).where("id", id).update(params).returning("*");
|
92
|
+
}
|
93
|
+
|
94
|
+
/**
|
95
|
+
* @description 查询指定条件的记录数量
|
96
|
+
* @param {*} query - {<key>:<value>}
|
97
|
+
* @returns {Promise} 返回指定条件的记录数量
|
98
|
+
*/
|
99
|
+
count(query) {
|
100
|
+
return this.knex(this.model).where(query).count("* as total").first();
|
101
|
+
}
|
102
|
+
|
103
|
+
/**
|
104
|
+
* @description 插入一条记录
|
105
|
+
* @param {*} params - {<key>:<value>}
|
106
|
+
* @returns {Promise} 返回插入后的记录
|
107
|
+
*/
|
108
|
+
insert(params) {
|
109
|
+
return this.knex(this.model).insert(params);
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* @description 插入多条记录
|
114
|
+
* @param {*} records - [{<key>:<value>}, {<key>:<value>}, ...]
|
115
|
+
* @returns {Promise} 返回插入后的记录
|
116
|
+
*/
|
117
|
+
insertMany(records) {
|
118
|
+
return this.knex(this.model).insert(records);
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* @description 更新指定id的记录
|
123
|
+
* @param {*} id - 记录id
|
124
|
+
* @param {*} params - {<key>:<value>}
|
125
|
+
* @returns {Promise} 返回更新后的记录
|
126
|
+
*/
|
127
|
+
updateById(id, params) {
|
128
|
+
return this.knex(this.model).where("id", id).update(params);
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* @description 更新数据
|
133
|
+
* @param {*} query - {<key>:<value>}
|
134
|
+
* @param {*} update - {<key>:<value>}
|
135
|
+
* @returns {Promise<*>} - 返回更新后的数据
|
136
|
+
*/
|
137
|
+
update(query, update) {
|
138
|
+
return this.knex(this.model).where(query).update(update);
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* @description 查询并更新
|
143
|
+
* @param {*} query - {<key>:<value>}
|
144
|
+
* @param {*} update - {<key>:<value>}
|
145
|
+
* @returns {Promise<*>} - 返回更新后的记录
|
146
|
+
*/
|
147
|
+
findAndModify(query, update) {
|
148
|
+
return this.knex(this.model).where(query).update(update);
|
149
|
+
}
|
150
|
+
|
151
|
+
/**
|
152
|
+
*
|
153
|
+
* @param {*} id - id
|
154
|
+
* @param {*} update - {<key>:<value>}
|
155
|
+
* @returns {Promise<*>} - 返回更新后的记录
|
156
|
+
*/
|
157
|
+
findByIdAndUpdate(id, update) {
|
158
|
+
return this.knex(this.model).where("id", id).update(update);
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* @description 根据条件更新记录
|
163
|
+
* @param {*} query - {<key>:<value>}
|
164
|
+
* @param {*} update - {<key>:<value>}
|
165
|
+
* @returns {Promise} - 返回更新后的记录
|
166
|
+
*/
|
167
|
+
findOneAndUpdate(query, update) {
|
168
|
+
return this.knex(this.model).where(query).update(update);
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* @description 根据id删除一条记录
|
173
|
+
* @param {*} id - 记录id
|
174
|
+
* @returns {Promise} - 返回删除的记录
|
175
|
+
*/
|
176
|
+
findByIdAndRemove(id) {
|
177
|
+
return this.knex(this.model).where("id", id).del();
|
178
|
+
}
|
179
|
+
|
180
|
+
/**
|
181
|
+
* @description 根据条件删除一条记录
|
182
|
+
* @param {*} query
|
183
|
+
* @returns {Promise} - 返回删除的记录
|
184
|
+
*/
|
185
|
+
findOneAndRemove(query) {
|
186
|
+
return this.knex(this.model).where(query).del();
|
187
|
+
}
|
189
188
|
}
|
190
189
|
|
191
|
-
const Service = (knex, model=
|
192
|
-
|
190
|
+
const Service = (knex, model = "") => {
|
191
|
+
return new BaseService(knex, model);
|
193
192
|
};
|
194
193
|
|
195
|
-
module.exports = Service;
|
194
|
+
module.exports = Service;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "chanjs",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.25",
|
4
4
|
"description": "Chan.js基于express 纯js研发的轻量级mvc框架。",
|
5
5
|
"main": "core/chan.js",
|
6
6
|
"module": "core/chan.js",
|
@@ -21,7 +21,8 @@
|
|
21
21
|
"express-art-template": "^1.0.1",
|
22
22
|
"knex": "^3.1.0",
|
23
23
|
"morgan": "^1.10.0",
|
24
|
-
"mysql2": "^3.11.0"
|
24
|
+
"mysql2": "^3.11.0",
|
25
|
+
"dayjs": "^1.11.12"
|
25
26
|
},
|
26
27
|
"__npminstall_done": true,
|
27
28
|
"_from": "chanjs@1.0.22",
|