chanjs 1.0.24 → 1.0.26
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 +92 -85
- 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 +4 -3
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
|
92
|
-
const
|
93
|
-
|
88
|
+
const Chanjs = require("chanjs");
|
89
|
+
const chan = new Chanjs();
|
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,12 +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
|
-
Chan.config = {...Chan.config
|
52
|
+
Chan.config = { ...Chan.config, ...config };
|
62
53
|
}
|
63
54
|
}
|
64
55
|
|
65
|
-
|
66
|
-
|
56
|
+
// 加载扩展
|
57
|
+
loadExtends() {
|
67
58
|
const extendPath = path.join(Chan.config.APP_PATH, "extend");
|
68
59
|
if (fs.existsSync(extendPath)) {
|
69
60
|
let controllers = fs
|
@@ -76,20 +67,19 @@ class Chan {
|
|
76
67
|
Chan.helper[fileName] = helper;
|
77
68
|
}
|
78
69
|
}
|
79
|
-
|
80
70
|
}
|
81
71
|
|
82
72
|
//数据库操作
|
83
|
-
loadKnex(){
|
73
|
+
loadKnex() {
|
84
74
|
// 连接数据库
|
85
75
|
const {
|
86
|
-
host=
|
87
|
-
port=
|
76
|
+
host = "localhost",
|
77
|
+
port = "3306",
|
88
78
|
user,
|
89
79
|
password,
|
90
80
|
database,
|
91
|
-
client=
|
92
|
-
charset=
|
81
|
+
client = "mysql2",
|
82
|
+
charset = "utf8mb4",
|
93
83
|
} = Chan.config.database;
|
94
84
|
|
95
85
|
const knex = require("knex")({
|
@@ -102,7 +92,7 @@ class Chan {
|
|
102
92
|
database,
|
103
93
|
charset,
|
104
94
|
},
|
105
|
-
debug: Chan.config.
|
95
|
+
debug: Chan.config.SqlDebug, //指明是否开启debug模式,默认为true表示开启
|
106
96
|
pool: {
|
107
97
|
//指明数据库连接池的大小,默认为{min: 2, max: 10}
|
108
98
|
min: 0,
|
@@ -126,89 +116,96 @@ class Chan {
|
|
126
116
|
|
127
117
|
//开始启动
|
128
118
|
beforeStart(cb) {
|
129
|
-
|
119
|
+
|
130
120
|
cb && cb();
|
131
121
|
}
|
132
|
-
|
133
122
|
//启动
|
134
|
-
start(cb){
|
123
|
+
start(cb) {
|
124
|
+
//加载模块
|
125
|
+
this.loadModules();
|
126
|
+
//加载插件
|
127
|
+
this.loadPlugins();
|
128
|
+
//加载通用路由
|
129
|
+
this.loadCommonRouter();
|
135
130
|
// 初始化一些配置
|
136
131
|
cb && cb();
|
137
132
|
}
|
138
133
|
|
139
134
|
//解决跨域
|
140
|
-
loadCors(){
|
141
|
-
|
135
|
+
loadCors() {
|
136
|
+
Chan.config?.cors?.origin && this.app.use(cors(Chan.config.cors));
|
142
137
|
}
|
143
138
|
|
144
139
|
// 加载插件
|
145
140
|
loadPlugins() {
|
146
|
-
this.loadModules(
|
141
|
+
this.loadModules("plugins");
|
147
142
|
}
|
148
143
|
|
149
144
|
/**
|
150
145
|
* @description app核心模块:日志、favicon 图标、cookie、json、url、模板引擎、静态资源
|
151
146
|
*/
|
152
|
-
loadCore(){
|
153
|
-
|
147
|
+
loadCore() {
|
154
148
|
core(this.app, Chan.config);
|
155
149
|
}
|
156
150
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
loadModules(modules=
|
161
|
-
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);
|
162
156
|
if (fs.existsSync(configPath)) {
|
163
157
|
const dirs = fs
|
164
158
|
.readdirSync(configPath, { withFileTypes: true })
|
165
159
|
.filter((dirent) => dirent.isDirectory())
|
166
160
|
.map((dirent) => dirent.name);
|
167
|
-
|
161
|
+
Chan[modules] = {};
|
168
162
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
163
|
+
// 先加载所有服务
|
164
|
+
dirs.forEach((item) => {
|
165
|
+
Chan[modules][item] = {
|
166
|
+
service: {},
|
167
|
+
controller: {},
|
168
|
+
};
|
169
|
+
this.loadServices(modules, item);
|
170
|
+
});
|
177
171
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
172
|
+
// 加载控制器和路由
|
173
|
+
dirs.forEach((item) => {
|
174
|
+
this.loadModule(modules, item);
|
175
|
+
});
|
176
|
+
|
177
|
+
//执行路由
|
178
|
+
// this.app.use(this.router);
|
185
179
|
}
|
186
180
|
}
|
187
181
|
|
188
|
-
|
189
182
|
/**
|
190
|
-
* @description 加载模块,包括 controller service router
|
183
|
+
* @description 加载模块,包括 controller service router
|
191
184
|
* @param {String} moduleName 模块名称
|
192
185
|
*/
|
193
|
-
loadModule(modules,moduleName) {
|
194
|
-
this.loadControllers(modules,moduleName);
|
195
|
-
this.loadRoutes(modules,moduleName);
|
186
|
+
loadModule(modules, moduleName) {
|
187
|
+
this.loadControllers(modules, moduleName);
|
188
|
+
this.loadRoutes(modules, moduleName);
|
196
189
|
}
|
197
190
|
|
198
|
-
|
199
191
|
/**
|
200
192
|
* @description 扫描模块下所有service
|
201
193
|
* @param {*} moduleDir 模块路径
|
202
194
|
* @param {*} moduleName 模块名称
|
203
195
|
*/
|
204
|
-
loadServices(modules,moduleName) {
|
205
|
-
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
|
+
);
|
206
203
|
if (fs.existsSync(servicesDir)) {
|
207
204
|
let services = fs
|
208
205
|
.readdirSync(servicesDir)
|
209
206
|
.filter((file) => file.endsWith(".js"));
|
210
207
|
for (let i = 0, file; i < services.length; i++) {
|
211
|
-
file= services[i]
|
208
|
+
file = services[i];
|
212
209
|
const Service = require(path.join(servicesDir, file));
|
213
210
|
const serviceName = file.replace(".js", "");
|
214
211
|
//模块文件夹-模块文件名-服务-方法
|
@@ -218,24 +215,29 @@ class Chan {
|
|
218
215
|
}
|
219
216
|
}
|
220
217
|
|
221
|
-
|
222
218
|
/**
|
223
219
|
* @description 扫描模块下所有controller
|
224
220
|
* @param {*} moduleDir 模块路径
|
225
221
|
* @param {*} moduleName 模块名称
|
226
222
|
*/
|
227
|
-
loadControllers(modules,moduleName) {
|
228
|
-
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
|
+
);
|
229
230
|
if (fs.existsSync(controllersDir)) {
|
230
231
|
let controllers = fs
|
231
232
|
.readdirSync(controllersDir)
|
232
233
|
.filter((file) => file.endsWith(".js"));
|
233
234
|
for (let i = 0, file; i < controllers.length; i++) {
|
234
|
-
file= controllers[i]
|
235
|
+
file = controllers[i];
|
235
236
|
const controller = require(path.join(controllersDir, file));
|
236
237
|
const controllerName = file.replace(".js", "");
|
237
238
|
Chan[modules][moduleName].controller[controllerName] = {};
|
238
|
-
Chan[modules][moduleName].controller[controllerName] =
|
239
|
+
Chan[modules][moduleName].controller[controllerName] =
|
240
|
+
bindClass(controller);
|
239
241
|
}
|
240
242
|
}
|
241
243
|
}
|
@@ -245,33 +247,38 @@ class Chan {
|
|
245
247
|
* @param {*} moduleDir 模块路径
|
246
248
|
* @param {*} moduleName 模块名称
|
247
249
|
*/
|
248
|
-
loadRoutes(modules,moduleName) {
|
249
|
-
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
|
+
);
|
250
257
|
if (fs.existsSync(routersDir)) {
|
251
258
|
const routes = require(routersDir);
|
252
|
-
routes({router:this.router,modules:Chan[modules],app:this.app});
|
259
|
+
routes({ router: this.router, modules: Chan[modules], app: this.app });
|
253
260
|
}
|
254
261
|
}
|
255
262
|
|
256
|
-
|
257
|
-
loadCommonRouter(){
|
263
|
+
//通用路由,加载错误处理和500路由和爬虫处理
|
264
|
+
loadCommonRouter() {
|
258
265
|
try {
|
259
266
|
const baseRouterPath = path.join(Chan.config.APP_PATH, "router.js");
|
260
267
|
if (fs.existsSync(baseRouterPath)) {
|
261
268
|
const _router = require(baseRouterPath);
|
262
|
-
_router(this.app, this.router,Chan.config);
|
263
|
-
}
|
269
|
+
_router(this.app, this.router, Chan.config);
|
270
|
+
}
|
264
271
|
} catch (error) {
|
265
272
|
console.log(error);
|
266
273
|
}
|
267
274
|
}
|
268
|
-
|
269
|
-
run() {
|
270
|
-
const port = Chan.config.port ||
|
275
|
+
|
276
|
+
run(cb) {
|
277
|
+
const port = Chan.config.port || "81";
|
271
278
|
this.app.listen(port, () => {
|
272
|
-
console.log(`Server is running on port ${port}`);
|
279
|
+
cb?cb(port):console.log(`Server is running on port ${port}`);
|
273
280
|
});
|
274
281
|
}
|
275
282
|
}
|
276
283
|
global.Chan = Chan;
|
277
|
-
module.exports = 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,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "chanjs",
|
3
|
-
"version": "1.0.
|
4
|
-
"description": "
|
3
|
+
"version": "1.0.26",
|
4
|
+
"description": "chanjs基于express 纯js研发的轻量级mvc框架。",
|
5
5
|
"main": "core/chan.js",
|
6
6
|
"module": "core/chan.js",
|
7
7
|
"keywords": [
|
@@ -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",
|