jj.js 0.8.6 → 0.8.7

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 CHANGED
@@ -145,13 +145,13 @@ module.exports = Index;
145
145
 
146
146
  - 在控制器中,前缀为`$`字符的属性为特殊属性,框架首先会检测本类中即`this`实例中是否有`$db`属性,有的话,会直接调用。如果没有,会检测本类文件所在应用目录即`./app/`目录下,是否用`db`目录或文件,如果有,则`$db`即代表那个目录或文件,`this.$db.table`会继续在db目录下寻找table目录或文件。如果`db`目录或文件不存在,框架会在应用根目录`./`下找,是否有`db`目录或文件,如果有,和上面一样。如果还不存在,框架会在jj.js框架`lib`目录下找`db`文件或目录,而框架`lib`中有`db.js`文件,至此,`this.$db`成功访问到框架`db`类。
147
147
 
148
- - 如果将`this.$db`赋值为给一个变量,`const db = this.$db;`,得到的将是一个`db` Class类,可以进行new操作,`const db = this.$db; const db1 = new this.$db(); const db2 = new this.$db();`创建多个实例。
148
+ - 如果将`this.$db`赋值为给一个变量,`const db = this.$db;`,得到的将是一个`db` Class类,可以进行new操作,`const db = this.$db; const db1 = new db(this.ctx, options); const db2 = new this.$db(this.ctx, options);`创建多个实例。
149
149
 
150
150
  - 但上面演示代码并没有new一个实例,而是直接调用`db`类的`table()`方法,这正是框架的智能之处。当调用`this.$db.table('user')`时,框架首先会检测db类是否有`table`静态属性,有的话会直接调用。没有,则会自动new一个`db`实例,而且这个实例是个单例,然后调用此`db`实例的`table`方法,`table('user')`设置数据表名后返回实例本身,然后紧接着调用`find()`方法,读取用户ID为1的数据。
151
151
 
152
152
  > 注意:虽然系统加载很复杂, 但是基于node的常驻内存特性,上面的文件路径判断,处理一次就会被缓存下来,在下个生命周期不用重复判断,节省性能。
153
153
 
154
- > 关于单例:通过`this.$xxx`调用的类实例,在单个生命周期内是单例,即不管调用几次,都是用的同一个实例,这样非常节省内存开销。如果有多个db实例需求,可以用上面的方法,自己`new`创建。
154
+ > 关于单例:通过`this.$xxx`调用的类实例,在单个生命周期内是单例,即不管调用几次,都是用的同一个实例,这样非常节省内存开销。如果有多个db实例需求,可以用上面的方法,自己`new`创建,自己创建时注意第一个参数需传入ctx,否则部分类库使用会出现异常。
155
155
 
156
156
  > 生命周期:应用生命周期以url访问为单位,一次url访问到访问结束,是一个独立的生命周期,在这个周期内自动生成的单实例都是共用的。
157
157
 
@@ -299,6 +299,10 @@ module.exports = Index;
299
299
 
300
300
  ### Db数据库类
301
301
 
302
+ > 方法:**connect(options)** 连接数据库
303
+
304
+ > 方法:**async close()** 关闭数据库连接
305
+
302
306
  > 方法:**async startTrans(fun)** 开启事务
303
307
 
304
308
  异步方法,如果`fun`不为空,并且是函数,则开启事务后,会自动执行此函数,并提交事务,不用再手工提交或回滚事务。`fun`为异步函数。
package/lib/db.js CHANGED
@@ -11,7 +11,7 @@ const nest = new Map();
11
11
 
12
12
  class Db extends Context
13
13
  {
14
- constructor(ctx) {
14
+ constructor(ctx, options) {
15
15
  ctx = ctx || {};
16
16
  super(ctx);
17
17
  this._config = null;
@@ -19,7 +19,7 @@ class Db extends Context
19
19
  this._options = {};
20
20
  this._queryStr = '';
21
21
  this._tableField = {};
22
- this.connect();
22
+ this.connect(options);
23
23
  }
24
24
 
25
25
  reset() {
@@ -62,22 +62,21 @@ class Db extends Context
62
62
  return this;
63
63
  }
64
64
 
65
- close() {
66
- if(pool.has(this._config)) {
67
- pool.get(this._config).end(err => {
65
+ async close() {
66
+ return new Promise((resolve, reject) => {
67
+ pool.has(this._config) && pool.get(this._config).end(err => {
68
68
  if(err) {
69
69
  const message = '连接池销毁失败:' + err.message;
70
70
  this.$logger.sql(message);
71
71
  this.$logger.error(message);
72
- throw new Error('DbError: ' + message);
72
+ reject(new Error('DbError: ' + message));
73
73
  } else {
74
74
  pool.delete(this._config);
75
75
  this.$logger.sql(`连接池销毁成功:{poolTotal: ${pool.size}}`);
76
+ resolve(this);
76
77
  }
77
78
  });
78
-
79
- }
80
- return this;
79
+ });
81
80
  }
82
81
 
83
82
  release(conn) {
package/lib/loader.js CHANGED
@@ -1,4 +1,3 @@
1
- const fs = require('fs');
2
1
  const pt = require('path');
3
2
  const isClass = require('is-class');
4
3
  const {isFileSync, isDirSync} = require('./utils/fs');
package/lib/run.js CHANGED
@@ -29,11 +29,11 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
29
29
  ctx._.config.tpl = tpl;
30
30
 
31
31
  // 应用、控制器、方法名字验证
32
- if (~ctx.APP.indexOf('.') || ~ctx.CONTROLLER.indexOf('.') || ~ctx.ACTION.indexOf('.')) {
32
+ if(~ctx.APP.indexOf('.') || ~ctx.CONTROLLER.indexOf('.') || ~ctx.ACTION.indexOf('.')) {
33
33
  throw new Error(`RunError: 应用、控制器或方法名字不合法!`);
34
34
  }
35
35
 
36
- if (ctx.APP[0] == '_' || ctx.APP[0] == '$' || !ctx._[ctx.APP]) {
36
+ if(ctx.APP[0] == '_' || ctx.APP[0] == '$' || !ctx._[ctx.APP]) {
37
37
  if(cfg_app.app_debug) {
38
38
  throw new Error(`RunError: 应用:${ctx.APP}不存在!`);
39
39
  } else {
@@ -41,7 +41,7 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
41
41
  }
42
42
  }
43
43
 
44
- if (!ctx._[ctx.APP][control_type]) {
44
+ if(!ctx._[ctx.APP][control_type]) {
45
45
  if(cfg_app.app_debug) {
46
46
  throw new Error(`RunError: 目录:${ctx.APP}/${control_type}不存在!`);
47
47
  } else {
@@ -62,7 +62,7 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
62
62
  // 控制器
63
63
  const Controller = ctx._[ctx.APP][control_type][ctx.CONTROLLER] || ctx._[ctx.APP][control_type]['empty'];
64
64
 
65
- if (ctx.CONTROLLER[0] == '_' || ctx.CONTROLLER[0] == '$' || typeof Controller != 'function') {
65
+ if(ctx.CONTROLLER[0] == '_' || ctx.CONTROLLER[0] == '$' || typeof Controller != 'function') {
66
66
  if(cfg_app.app_debug) {
67
67
  throw new Error(`RunError: class文件:${ctx.APP}/${control_type}/${ctx.CONTROLLER}不存在!`);
68
68
  } else {
@@ -71,11 +71,11 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
71
71
  }
72
72
 
73
73
  // 控制器实例
74
- $controller = new Controller(ctx, next);
74
+ const $controller = new Controller(ctx, next);
75
75
  const humpAction = toHump(ctx.ACTION);
76
76
  const action = typeof $controller[humpAction] == 'function' ? humpAction : 'empty';
77
77
 
78
- if (ctx.ACTION[0] == '_' || ctx.ACTION[0] == '$' || typeof $controller[action] != 'function') {
78
+ if(ctx.ACTION[0] == '_' || ctx.ACTION[0] == '$' || typeof $controller[action] != 'function') {
79
79
  if(cfg_app.app_debug) {
80
80
  throw new Error(`RunError: class方法:${ctx.APP}/${control_type}/${ctx.CONTROLLER}/${humpAction}不存在!`);
81
81
  } else {
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "jj.js",
3
- "version": "0.8.6",
3
+ "version": "0.8.7",
4
4
  "description": "A simple and lightweight MVC framework built on nodejs+koa2",
5
5
  "main": "jj.js",
6
6
  "scripts": {
7
- "test": "node test/test.js"
8
7
  },
9
8
  "repository": {
10
9
  "type": "git",
@@ -1,250 +0,0 @@
1
- //const {Controller} = require('jj.js');
2
- const {Controller, Db, Cache, Pagination, Logger, Url, Cookie} = require('../../../jj.js');
3
-
4
- class Index extends Controller
5
- {
6
- constructor(...args) {
7
- super(...args);
8
- this.middleware = ['middle', {middleware: 'auth', accept: 'middleTest'}];
9
- }
10
-
11
- async index() {
12
- const link_list = [
13
- {title: '输出字符串内容', url: this.$url.build('show_str')},
14
- {title: '加载文件显示', url: this.$url.build('load_file')},
15
- {title: '中间件测试', url: this.$url.build('middle_test')},
16
- {title: '数据库测试,需要先配置数据库文件', url: this.$url.build('mysql')},
17
- {title: '缓存测试', url: this.$url.build('cache')},
18
- {title: '日志测试', url: this.$url.build('log')},
19
- {title: '路由直接输出', url: this.$url.build(':show')},
20
- {title: '路由到模板文件直接输出', url: this.$url.build('template')},
21
- {title: '路由到中间件(不建议这种用法)', url: this.$url.build('middleware')},
22
- {title: '路由到自定义控制器层', url: this.$url.build(':diy')},
23
- {title: '不继承系统控制器', url: this.$url.build('not_extend_sys_controller/index')},
24
- {title: '分页测试', url: this.$url.build('/pagination')},
25
- {title: 'url生成测试', url: this.$url.build('url')},
26
- {title: 'Cookie测试', url: this.$url.build('cookie')},
27
- {title: 'Context测试', url: this.$url.build('context')},
28
- {title: 'Exception测试', url: this.$url.build('exception')},
29
- {title: '成功提示', url: this.$url.build('success')},
30
- {title: '错误提示', url: this.$url.build('error')},
31
- {title: '302跳转', url: this.$url.build('redirect')},
32
- {title: 'show object', url: this.$url.build('show')},
33
- ];
34
-
35
- this.$assign('title', 'jj.js - 一个简单轻量级Node.js MVC框架');
36
- this.$assign('link_list', link_list);
37
- await this.$fetch();
38
- }
39
-
40
- async showStr() {
41
- this.$show(`<!doctype html>
42
- <html>
43
- <head>
44
- <meta charset="utf-8">
45
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
46
- <title>jj.js</title>
47
- <link rel="stylesheet" href="/static/lit.css">
48
- <style>.c{max-width:48em;}</style>
49
- </head>
50
- <body style="margin:0;">
51
- <div class="c">
52
- <h1>jj.js</h1>
53
- <hr>
54
- <div>控制器输出字符串。</div>
55
- <hr>
56
- <div>
57
- <a class="btn" href="javascript:history.go(-1);" style="display: inline-block;">返回</a>
58
- </div>
59
- </div>
60
- </body>
61
- </html>`);
62
- }
63
-
64
- async loadFile() {
65
- let readme = await this.$view.load('/../README.md');
66
- readme = readme.replace('</p>', '</p><hr>');
67
- this.$assign('content', readme);
68
- await this.$fetch('view');
69
- }
70
-
71
- async middleTest() {
72
- this.$assign('content', '请查看控制台输出!');
73
- await this.$fetch('view');
74
- }
75
-
76
- async cache() {
77
- const cache = this.$cache;
78
- Logger.info(Cache === cache, Cache.get === cache.get, Cache.get() === cache.get());
79
- Logger.info('---------------------------');
80
- Logger.info(JSON.stringify(Cache.get()), JSON.stringify(cache.get()));
81
- const key1_value = Cache.get('key1');
82
- Cache.set('key1', key1_value ? key1_value+1 : 1, 10000);
83
- cache.set('key2', key1_value ? key1_value+100 : 100, 10000);
84
- Logger.info('---------------------------');
85
- Logger.info(JSON.stringify(Cache.get()), JSON.stringify(cache.get()));
86
-
87
- this.$assign('content', '请查看控制台输出!');
88
- await this.$fetch('view');
89
- }
90
-
91
- async log() {
92
- this.$logger.info('logger.info');
93
- Logger.error('logger.error');
94
- Logger.warning('logger.warning');
95
- Logger.debug('logger.debug');
96
- Logger.sql('logger.sql');
97
- Logger.http('logger.http');
98
- Logger.log('logger.log');
99
- Logger.log('logger.diy', 'diy');
100
- Logger.info(1, 2, 3);
101
-
102
- // 自定义handle
103
- Logger.setHandle(function(msg, level) {
104
- console.log(`[${level}] [${msg}]`)
105
- });
106
- Logger.info('自定义handle');
107
-
108
- //重置系统handle
109
- Logger.setHandle();
110
- Logger.info('重置系统handle');
111
-
112
- this.$assign('content', '请查看控制台输出!');
113
- await this.$fetch('view');
114
- }
115
-
116
- async pagination() {
117
- let html = new Pagination(this.ctx).init({key_origin: 'params', url_index: '/pagination', url_page: '/pagination/list_${page}.html'}).total(200).render();
118
-
119
- const css = `<style>
120
- .page{display:flex;}
121
- .page li{list-style:none;margin:5px;}
122
- .page li a{display:block;padding:5px 10px;border:1px solid blue;text-decoration:none;color:inherit;}
123
- .page li.active a,.page li:hover a{background-color:blue;color:#fff;}
124
- </style>`;
125
- html += css;
126
-
127
- const page2 = this.$pagination.my_pagination.render(200);
128
- html += page2;
129
-
130
- this.$assign('content', html);
131
- await this.$fetch('view');
132
- }
133
-
134
- async url() {
135
- const url = new Url(this.ctx);
136
- const arr = [];
137
- arr.push(url.build());
138
- arr.push(url.build('cate', '/'));
139
- arr.push(url.build('index/cate', '.html'));
140
- arr.push(url.build('index/index/cate', '.html'));
141
- arr.push(url.build('app/index/index/cate', '.html'));
142
- arr.push(url.build('/app/index/index/cate', '.html'));
143
- arr.push(url.build('test', {var: 'test', var2: 'test2'}, '.html'));
144
- arr.push(url.build('test?var3=vvv', {var: 'test', var2: 'test2'}, '.html'));
145
- arr.push(url.build('test?var=vvv', {var: 'test', var2: 'test2'}, '.html'));
146
- arr.push(url.build('index/cate#'));
147
- arr.push(url.build('index/cate#', {var: 'test', var2: 'test2'}, '.html'));
148
- arr.push(url.build('test?var=vvv#bbb', {var: 'test', var2: 'test2'}, '.html'));
149
- arr.push(url.build(':test', {var1: 'test', var2: 'test2', var3: 'test3'}, '.html'));
150
- arr.push(url.build(':diy'));
151
- arr.push(url.build(':show'));
152
- arr.push(url.build('showStr'));
153
- arr.push(url.build('index/loadFile'));
154
-
155
- this.$assign('content', arr.join('<br>'));
156
- await this.$fetch('view');
157
- }
158
-
159
- async cookie() {
160
- const cookie = new Cookie(this.ctx);
161
- let value = cookie.get('cookie_test');
162
- if(!value) {
163
- value = 1;
164
- } else {
165
- value = parseInt(value) + 1;
166
- }
167
- cookie.set('cookie_test', value);
168
- cookie.set('cookie_test2', 'value2', {maxAge: 1000 * 3600});
169
- cookie.set('cookie_test3', 'value3', {expires: new Date('2020-07-06')});
170
-
171
- this.$assign('content', `cookie_value: ${value}`);
172
- await this.$fetch('view');
173
- }
174
-
175
- async context() {
176
- this.$logger.info(JSON.stringify(this.$controller.__node)); // 自动定位到当前应用controller目录
177
- this.$logger.info(JSON.stringify(this.$diy.__node)); // 自动定位到当前应用diy目录
178
- this.$logger.info(JSON.stringify(this.$logic.__node)); // 自动定位到公共应用logic目录
179
- this.$logger.info(JSON.stringify(this.$app.__node)); // 自动定位到当前应用根目录
180
- this.$logger.info(JSON.stringify(this.$url.__node)); // 自动定位到系统类库url文件
181
- this.$logger.info(JSON.stringify(this.$utils.__node)); // 自动定位到系统类库utils目录
182
- this.$logger.info(JSON.stringify(this.$.__node)); // 强制定位到系统类库目录
183
- this.$logger.info(JSON.stringify(this._.__node)); // 强制定位到项目根目录
184
- this.$assign('content', '请查看控制台输出!');
185
- await this.$fetch('view');
186
- }
187
-
188
- async exception() {
189
- // throw new Error('异常测试');
190
- this.$response.exception(new Error('异常测试'));
191
- }
192
-
193
- async success() {
194
- this.$success();
195
- }
196
-
197
- async error() {
198
- this.$error();
199
- }
200
-
201
- async redirect() {
202
- this.$redirect('/');
203
- }
204
-
205
- async show() {
206
- this.$show({data: 'object'});
207
- }
208
-
209
- async mysql() {
210
- const db = new Db(this.ctx);
211
-
212
- await db.startTrans();
213
- await db.startTrans();
214
- await db.startTrans();
215
- await db.commit();
216
- await db.commit();
217
- await db.commit();
218
-
219
- await this.$db.startTrans();
220
- await this.$db.startTrans();
221
- await this.$db.startTrans();
222
- await this.$db.commit();
223
- await this.$db.commit();
224
- await this.$db.commit();
225
-
226
- this.$assign('content', '请查看控制台输出!');
227
- await this.$fetch('view');
228
-
229
- // const list = await db.table('article a').field('a.title, a.id, a.click, c.c_name').join('cate c', 'c.id=a.cate_id').where({'a.click': ['in', '102,201'], source: ['=', 'me', 'or']}).where({add_time: 2, update_time: 0}, 'or').where({add_time: ['>=', 0], update_time: 0}).group('add_time').having('add_time>1').order('a.id', 'desc').limit(0, 10).select();
230
-
231
- // const Arc = require('../model/article');
232
- // const model_article = new Arc(this.ctx);
233
- // const [list2, list3, list4] = await Promise.all([
234
- // model_article.db.find(),
235
- // this.$model.article.db.find(),
236
- // this.$model.article.db.page(2, 3).select()
237
- // ]);
238
- //const list2 = model_article.db.find();
239
- //const list3 = this.ctx.$app.model.article.db.find();
240
- //const list4 = this.ctx.$app.model.article.db.page(2, 3).select();
241
- //const data = {"cate_id":2,"user_id":0,"title":"测试文章","writer":"雨思","source":"me","source_link":"","click":200,"keywords":"测试,文章","description":"这是一篇测试文章","content":"测试文章测试'文章测试文章内容"};
242
- //const data2 = {"cate_id":2,"user_id":0,"title":"rtrtrt","writer":"雨思","source":"me","source_link":"","click":200,"keywords":"测试,文章","description":"这是一篇测试文章","content":"test'cccccc"};
243
- //Logger.info(await model_article.db.table('article').getSql().insert(data));
244
-
245
-
246
- //this.ctx.body = {list, list2, list3, list4};
247
- }
248
- }
249
-
250
- module.exports = Index;
@@ -1,32 +0,0 @@
1
- class NotExtendSysController
2
- {
3
- constructor(ctx) {
4
- this.ctx = ctx;
5
- }
6
-
7
- async index() {
8
- this.ctx.body = `<!doctype html>
9
- <html>
10
- <head>
11
- <meta charset="utf-8">
12
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
13
- <title>jj.js</title>
14
- <link rel="stylesheet" href="/static/lit.css">
15
- <style>.c{max-width:48em;}</style>
16
- </head>
17
- <body style="margin:0;">
18
- <div class="c">
19
- <h1>jj.js</h1>
20
- <hr>
21
- <div>不继承系统控制器。</div>
22
- <hr>
23
- <div>
24
- <a class="btn" href="javascript:history.go(-1);" style="display: inline-block;">返回</a>
25
- </div>
26
- </div>
27
- </body>
28
- </html>`;
29
- }
30
- }
31
-
32
- module.exports = NotExtendSysController;
@@ -1,16 +0,0 @@
1
- const {Controller, Logger} = require('../../../jj.js');
2
-
3
- class DiyController extends Controller
4
- {
5
- async _init() {
6
- Logger.info('_init');
7
- }
8
-
9
- async index() {
10
- this.$assign('url_str', ':diy');
11
- this.$assign('content', '自定义控制器层!');
12
- await this.$fetch('index/view');
13
- }
14
- }
15
-
16
- module.exports = DiyController;
@@ -1,19 +0,0 @@
1
- //const {Middleware} = require('jj.js');
2
- const {Middleware, Logger} = require('../../../jj.js');
3
-
4
- class Index extends Middleware
5
- {
6
- async middle() {
7
- Logger.info('中间件:输出之前');
8
- await this.$next();
9
- Logger.info('中间件:输出之后');
10
- }
11
-
12
- async auth() {
13
- Logger.info('auth:在这里验证登录');
14
- await this.$next();
15
- Logger.info('auth:业务完成时调用');
16
- }
17
- }
18
-
19
- module.exports = Index;
@@ -1,42 +0,0 @@
1
- const {Logger} = require('../../../jj.js');
2
-
3
- module.exports = class {
4
- constructor(ctx, next) {
5
- this.ctx = ctx;
6
- this.$next = next;
7
- }
8
-
9
- async test() {
10
- Logger.info('middle1 test start');
11
- this.ctx.body = `<!doctype html>
12
- <html>
13
- <head>
14
- <meta charset="utf-8">
15
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
16
- <title>jj.js</title>
17
- <link rel="stylesheet" href="/static/lit.css">
18
- <style>.c{max-width:48em;}</style>
19
- </head>
20
- <body style="margin:0;">
21
- <div class="c">
22
- <h1>jj.js</h1>
23
- <hr>
24
- <div>路由到中间件,中间件输出内容,实际应用中不建议这种操作。</div>
25
- <hr>
26
- <div>
27
- <a class="btn" href="javascript:history.go(-1);" style="display: inline-block;">返回</a>
28
- </div>
29
- </div>
30
- </body>
31
- </html>`;
32
-
33
- // 执行$next,将继续向下匹配路由
34
- //await this.$next();
35
- }
36
-
37
- async end() {
38
- Logger.info('middle1 end');
39
- await this.$next();
40
- Logger.info('middle1 end await');
41
- }
42
- }
@@ -1,18 +0,0 @@
1
- const {Logger} = require('../../../jj.js');
2
-
3
- module.exports = class {
4
- constructor(ctx, next) {
5
- this.ctx = ctx;
6
- this.$next = next;
7
- }
8
-
9
- async start() {
10
- Logger.info('middle2 start');
11
- await this.$next();
12
- Logger.info('middle2 start await');
13
- }
14
-
15
- async end() {
16
- Logger.info('middle2 end');
17
- }
18
- }
@@ -1,9 +0,0 @@
1
- //const {Model} = require('jj.js');
2
- const {Model} = require('../../../jj.js');
3
-
4
- class Article extends Model
5
- {
6
-
7
- }
8
-
9
- module.exports = Article;
@@ -1,11 +0,0 @@
1
- //const {Pagination} = require('jj.js');
2
- const {Pagination} = require('../../../jj.js');
3
-
4
- class MyPagination extends Pagination
5
- {
6
- init(opts) {
7
- super.init(opts);
8
- }
9
- }
10
-
11
- module.exports = MyPagination;
@@ -1,21 +0,0 @@
1
- {{extend './layout.htm'}}
2
- {{block 'title'}}
3
- <title>{{title}}</title>
4
- {{/block}}
5
- {{block 'content'}}
6
- <div class="c">
7
- {{@content}}
8
- <ul>
9
- <li>{{url()}}</li>
10
- <li>{{url('cate', '/')}}</li>
11
- <li>{{url('cate/cate', '.html')}}</li>
12
- <li>{{url('cate/index/cate', '.html')}}</li>
13
- <li>{{url('test', {var: 'test', var2: 'test2'}, '.html')}}</li>
14
- <li>{{url('test?var3=vvv', {var: 'test', var2: 'test2'}, '.html', 'http://www.baidu.com')}}</li>
15
- <li>{{url('test?var=vvv', {var: 'test', var2: 'test2'}, '.html')}}</li>
16
- <li>{{url('index/cate#')}}</li>
17
- <li>{{url('test?var=vvv#bbb', {var: 'test', var2: 'test2'}, '.html')}}</li>
18
- <li>{{url(':name', {var: 'test', var2: 'test2', var3: 'test3'}, '.html')}}</li>
19
- </ul>
20
- </div>
21
- {{/block}}
@@ -1,18 +0,0 @@
1
- {{extend './layout.htm'}}
2
- {{block 'title'}}
3
- <title>{{title}}</title>
4
- {{/block}}
5
- {{block 'content'}}
6
- <div class="c">
7
- <h1>jj.js</h1>
8
- <hr>
9
- <div>本页地址:{{url()}}</div>
10
- <hr>
11
- <div>功能测试,部分功能需在控制台查看输出。</div>
12
- <ul>
13
- {{each link_list}}
14
- <li><a href="{{$value.url}}">{{$value.title}}</a></li>
15
- {{/each}}
16
- </ul>
17
- </div>
18
- {{/block}}
@@ -1,21 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
6
- <title>jj.js</title>
7
- <link rel="stylesheet" href="/static/lit.css">
8
- <style>.c{max-width:48em;}</style>
9
- </head>
10
- <body style="margin:0;">
11
- <div class="c">
12
- <h1>jj.js</h1>
13
- <hr>
14
- <div>路由直接输出模版文件内容。</div>
15
- <hr>
16
- <div>
17
- <a class="btn" href="javascript:history.go(-1);" style="display: inline-block;">返回</a>
18
- </div>
19
- </div>
20
- </body>
21
- </html>
@@ -1,17 +0,0 @@
1
- {{extend './layout.htm'}}
2
- {{block 'title'}}
3
- <title>{{title}}</title>
4
- {{/block}}
5
- {{block 'content'}}
6
- <div class="c">
7
- <h1>jj.js</h1>
8
- <hr>
9
- <div>本页地址:{{url(url_str)}}</div>
10
- <hr>
11
- {{@content}}
12
- <hr>
13
- <div>
14
- <a class="btn" href="javascript:history.go(-1);" style="display: inline-block;">返回</a>
15
- </div>
16
- </div>
17
- {{/block}}
@@ -1,14 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
6
- {{block 'title'}}<title>jj.js</title>{{/block}}
7
- {{block 'css'}}<link rel="stylesheet" href="/static/lit.css">
8
- <style>.c{max-width:48em;}</style>{{/block}}
9
- </head>
10
- <body style="margin:0;">
11
- {{block 'content'}}{{/block}}
12
- {{block 'js'}}{{/block}}
13
- </body>
14
- </html>
@@ -1,17 +0,0 @@
1
- const app = {
2
- app_debug: true, //调试模式
3
- app_multi: false, //是否开启多应用
4
-
5
- default_app: 'app', //默认应用
6
- default_controller: 'index', //默认控制器
7
- default_action: 'index', //默认方法
8
-
9
- common_app: 'common', //公共应用,存放公共模型及逻辑
10
- controller_folder: 'controller', //控制器目录名
11
-
12
- static_dir: './public', //静态文件目录,相对于应用根目录,为空或false时,关闭静态访问
13
-
14
- koa_body: null //koa-body配置参数,为''、null、false时,关闭koa-body
15
- }
16
-
17
- module.exports = app;
@@ -1,33 +0,0 @@
1
- routes = [
2
- {url: '/hello/', path: 'index/hello', method: 'get', type: 'middleware'},
3
- {url: '/show', path: async (ctx, next) => {ctx.body = `<!doctype html>
4
- <html>
5
- <head>
6
- <meta charset="utf-8">
7
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
8
- <title>jj.js</title>
9
- <link rel="stylesheet" href="/static/lit.css">
10
- <style>.c{max-width:48em;}</style>
11
- </head>
12
- <body style="margin:0;">
13
- <div class="c">
14
- <h1>jj.js</h1>
15
- <hr>
16
- <div>路由直接输出内容。</div>
17
- <hr>
18
- <div>
19
- <a class="btn" href="javascript:history.go(-1);" style="display: inline-block;">返回</a>
20
- </div>
21
- </div>
22
- </body>
23
- </html>`;}, method: 'get', name: 'show'},
24
- {url: '/index/template', path: '/index/template', type: 'view'},
25
- {url: '/index/middleware', path: 'middle1/test', type: 'middleware'},
26
- {url: '/diy', path: 'diy_controller/index', type: 'diy', name: 'diy'},
27
- {url: '/pagination', path: 'index/pagination', method: 'get'},
28
- {url: '/pagination/list_:page.html(.*)', path: 'index/pagination', method: 'get'},
29
- {url: '/file', path: 'index/index', method: 'get', type: 'view'},
30
- {url: '/test/:var1/:var2/:var3', path: 'index/index', method: 'get', name: 'test'},
31
- ];
32
-
33
- module.exports = routes;
@@ -1,5 +0,0 @@
1
- const view = {
2
- view_depr: '_', // 模版文件名分割符,'/'代表二级目录
3
- }
4
-
5
- module.exports = view;
Binary file
@@ -1 +0,0 @@
1
- *+*{box-sizing:border-box;margin:.5em 0}@media(min-width:35em){.col{display:table-cell}.\31{width:5%}.\33{width:22%}.\34{width:30%}.\35{width:40%}.\32{width:15%}.row{display:table;border-spacing:1em 0}}.row,.w-100{width:100%}.card:focus,hr{outline:0;border:solid #fa0}.card,pre{padding:1em;border:solid #eee}.btn:hover,a:hover{opacity:.6}.c{max-width:60em;padding:1em;margin:auto;font:1em/1.6 nunito}h6{font:300 1em nunito}h5{font:300 1.2em nunito}h3{font:300 2em nunito}h4{font:300 1.5em nunito}h2{font:300 2.2em nunito}h1{font:300 2.5em nunito}a{color:#fa0;text-decoration:none}.btn.primary{color:#fff;background:#fa0;border:solid #fa0}pre{overflow:auto}td,th{padding:1em;text-align:left;border-bottom:solid #eee}.btn{cursor:pointer;padding:1em;letter-spacing:.1em;text-transform:uppercase;background:#fff;border:solid;font:.7em nunito}
package/test/test.js DELETED
@@ -1,7 +0,0 @@
1
- //const {app} = require('jj.js');
2
- const {app, Logger} = require('../jj.js');
3
-
4
- //server
5
- app.run(3000, '0.0.0.0', function(err){
6
- !err && Logger.info('http server is ready on 3000');
7
- });