ThinkJS 是一个基于 Koa 2.x 的 Node.js MVC 框架,支持 ES6/7 特性,使用 async/await 处理异步。
config.js - 通用配置config.production.js - 生产环境配置(会覆盖 config.js)adapter.js - 适配器配置(数据库、缓存、会话等)router.js - 自定义路由middleware.js - 中间件配置extend.js - 扩展配置控制器目录,处理用户请求。
// src/controller/index.js
module.exports = class extends think.Controller {
async indexAction() {
// 获取参数
const id = this.get('id');
const data = this.post();
// 调用 model
const list = await this.model('article').select();
// 渲染模板
this.assign('list', list);
return this.display();
}
};
数据模型目录,操作数据库。
// src/model/article.js
module.exports = class extends think.Model {
// 获取文章列表
async getList(columnId, page = 1, pageSize = 10) {
return this.where({ column_id: columnId, status: 1 })
.order('create_time DESC')
.page(page, pageSize)
.countSelect();
}
};
逻辑层,用于参数校验。
// src/logic/article.js
module.exports = class extends think.Logic {
indexAction() {
this.allowMethods = 'get';
this.rules = {
id: { int: true, required: true }
};
}
};
// 获取参数
this.get('name'); // GET 参数
this.post('name'); // POST 参数
this.param('name'); // GET + POST
this.file('upload'); // 上传文件
// 响应
this.success(data); // JSON 成功响应
this.fail(errno, errmsg); // JSON 失败响应
this.json(data); // JSON 响应
this.redirect(url); // 重定向
// 模板
this.assign('key', value); // 赋值
this.display(); // 渲染模板
// Session
await this.session('user'); // 获取
await this.session('user', data); // 设置
// Cookie
this.cookie('name'); // 获取
this.cookie('name', value); // 设置
const model = this.model('article');
// 查询
model.where({ id: 1 }).find(); // 单条
model.where({ status: 1 }).select(); // 多条
model.where({ status: 1 }).count(); // 计数
model.page(1, 10).countSelect(); // 分页
// 新增
model.add({ title: 'xxx', content: 'xxx' });
model.addMany([{...}, {...}]);
// 更新
model.where({ id: 1 }).update({ title: 'new' });
// 删除
model.where({ id: 1 }).delete();
// 链式调用
model.field('id, title')
.where({ status: 1 })
.order('id DESC')
.limit(10)
.select();
// src/config/router.js
module.exports = [
// [匹配规则, 'controller/action', method]
['/article/:id', 'article/detail', 'get'],
['/api/article', 'api/article', 'rest'],
['/admin/:controller/:action?', 'admin/:controller/:action'],
];
// src/config/middleware.js
module.exports = [
{
handle: 'meta',
options: { logRequest: true }
},
{
handle: 'resource',
enable: true
},
'trace',
'payload',
'router',
'logic',
'controller'
];
// src/config/adapter.js
exports.model = {
type: 'mysql',
common: {
logConnect: true,
logSql: true,
logger: msg => think.logger.info(msg)
},
mysql: {
handle: mysql,
database: 'pap_web',
prefix: 'pap_',
encoding: 'utf8mb4',
host: '127.0.0.1',
port: '3306',
user: 'root',
password: '',
dateStrings: true
}
};
<!-- view/index_index.html -->
{% extends "layout.html" %}
{% block content %}
<ul>
{% for item in list %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
{% if pagination.totalPages > 1 %}
<div class="pagination">
第 {{ pagination.currentPage }} / {{ pagination.totalPages }} 页
</div>
{% endif %}
{% endblock %}
// src/config/middleware.js 添加
{
handle: 'cors',
options: {
origin: '*',
credentials: true
}
}
// controller
const file = this.file('image');
if (file) {
const filepath = file.path;
// 移动文件到目标目录
think.fs.move(filepath, targetPath);
}
const model = this.model('article');
await model.transaction(async () => {
await model.add(data1);
await this.model('log').add(data2);
});