系统开发是根据thinkphp现有的权限管理系统改版而来,存在大量的thinkphp开发习惯,如:访问路径使用‘/模块/控制器/方法’
使用的插件:egg-sequelize
代码主要目录结构:
├─app
│ ├─controller
│ │ └─admin
│ ├─extend
│ ├─middleware
│ ├─model
│ ├─model_log
│ └─view
│ └─admin
└─config
相关表结构:
CREATE TABLE `admin` (
`admin_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',
`user_name` varchar(60) NOT NULL DEFAULT '' COMMENT '用户名',
`email` varchar(60) NOT NULL DEFAULT '' COMMENT 'email',
`password` varchar(32) NOT NULL DEFAULT '' COMMENT '密码',
`add_time` int(10) NOT NULL DEFAULT '0' COMMENT '添加时间',
`last_login` int(10) NOT NULL DEFAULT '0' COMMENT '最后登录时间',
`last_ip` varchar(15) NOT NULL DEFAULT '' COMMENT '最后登录ip',
`role_id` smallint(5) DEFAULT NULL COMMENT '角色id',
PRIMARY KEY (`admin_id`),
KEY `user_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='管理员表';
INSERT INTO `admin` VALUES ('1', 'admin', 'admin@126.com', '14e1b600b1fd579f47433b88e8d85291', '1467872520', '1594554332', '127.0.0.1', '1');
CREATE TABLE `admin_role` (
`role_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色ID',
`role_name` varchar(30) DEFAULT NULL COMMENT '角色名称',
`act_list` text COMMENT '权限列表,将mod_id以逗号分隔',
`role_desc` varchar(255) DEFAULT NULL COMMENT '角色描述',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='角色表';
INSERT INTO `admin_role` VALUES ('1', '超级管理员', 'all', '管理全站');
CREATE TABLE `system_module` (
`mod_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
`module` enum('top','menu','module') DEFAULT 'module' COMMENT '模块名,top:菜单分类,menu:菜单,module:模块',
`level` tinyint(1) DEFAULT '3',
`ctl` varchar(20) DEFAULT '' COMMENT '控制器',
`act` varchar(30) DEFAULT '' COMMENT '方法',
`title` varchar(20) DEFAULT '' COMMENT '菜单名称',
`visible` tinyint(1) DEFAULT '1' COMMENT '是否显示',
`parent_id` smallint(6) DEFAULT '0' COMMENT '父类菜单',
`orderby` smallint(6) DEFAULT '50' COMMENT '排序',
PRIMARY KEY (`mod_id`)
) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=utf8 COMMENT='菜单和模块表';模型创建:
// model/admin.js
module.exports = app => {
const { STRING, INTEGER } = app.Sequelize;
const Admin = app.model.define('admin', {
admin_id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
},
user_name: STRING(60),
email: STRING(60),
password: STRING(32),
add_time: INTEGER,
last_login: INTEGER,
last_ip: STRING(15),
role_id: INTEGER,
});
return Admin;
};
// model/adminrole.js
module.exports = app => {
const { STRING, INTEGER, TEXT } = app.Sequelize;
const Adminrole = app.model.define('admin_role', {
role_id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
},
role_name: STRING(30),
act_list: TEXT,
role_desc: STRING(255),
});
return Adminrole;
};
// model/systemmodule.js
module.exports = app => {
const { STRING, INTEGER, ENUM } = app.Sequelize;
const Systemmodule = app.model.define('system_module', {
mod_id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
},
module: ENUM('top', 'menu', 'module'),
level: INTEGER,
ctl: STRING(20),
act: STRING(30),
title: STRING(20),
visible: INTEGER,
parent_id: INTEGER,
orderby: INTEGER,
});
return Systemmodule;
};配置:
const config = {};
config.sequelize = {
datasources: [
{
delegate: 'model', // 加载所有的模型到 app.model and ctx.model
baseDir: 'model', // 要加载的模型目录`app/model/*.js`
database: 'egg_main',
dialect: 'mysql',
host: '127.0.0.1',
port: '3306',
username: 'root',
password: 'root',
timezone: 'Asia/Shanghai', // 时间差
benchmark: true,
define: {
freezeTableName: true, // 禁止数据读写时给表赋别名(as)
underscored: true,
timestamps: false, // 为模型添加createdAt和updatedAt字段
raw: true,
},
},
{
delegate: 'logModel', // 加载所有的模型到 app.logModel and ctx.logModel
baseDir: 'model_log', // 要加载的模型目录 `app/admin_model/*.js`
database: 'egg_log',
dialect: 'mysql',
host: '127.0.0.1',
port: '3306',
username: 'root',
password: 'root',
timezone: 'Asia/Shanghai',
benchmark: true,
define: {
freezeTableName: true, // 禁止数据读写时给表赋别名(as)
underscored: true,
timestamps: false, // 为模型添加createdAt和updatedAt字段
raw: true,
},
},
],
};context扩展:
// extend/context.js
module.exports = {
/*
* 根据url解析模版路径
* @param string req_url 要解析的URL
* @param string ext 模版后缀
* return string
* For: this.ctx.view_ptah('http://localhost:7001/admin/index/login') => admin/index/login.html
* */
view_path(req_url, ext = '.html') {
let path = '';
if (!req_url) {
path = this.request.path;
} else if (/^http/.test(req_url)) { // 判断是否为url形式
const obj_url = new URL(req_url);
path = obj_url.pathname;
} else {
path = req_url;
}
return path.substr(1) + ext;
},
/*
* 错误页面
* @param string msg 错误信息
* @param string url 跳转的url
* @param int wait 等待跳转的时间(s)
* @param string path 页面模板路径
* return string
* For: this.ctx.error('无权访问')
* */
async error(msg, url = '', wait = 2, path = '/admin/public/error') {
const jump_url = url ? url : 'javascript:history.back(-1);';
const error = msg;
return this.render(this.view_path(path), { jump_url, error, wait });
},
/*
* 成功页面
* @param string msg 提示信息
* @param string url 跳转的url
* @param int wait 等待跳转的时间(s)
* @param string path 页面模板路径
* return string
* For: this.ctx.success('编辑成功')
* */
async success(msg, url = '', wait = 2, path = '/admin/public/error') {
const jump_url = url ? url : 'javascript:history.back(-1);';
const message = msg;
return this.render(this.view_path(path), { jump_url, message, wait });
},
};
随时随地看视频