系统使用
catadmin是一套权限管理系统,管理页面,接口,页面按钮权限这些资源
目录(系统)
权限的第一层级,诸如长城系统,七桥系统,小贷系统,对应前台页面的大栏目 权限的第二层级是大栏目下面的小栏目,都是按照sort字段升序排列
权限(页面,接口)
-
在数据库中页面和接口都是属于权限这一级别的资源,只有类型不同,type一个是page一个是api,但是在界面中为了方便直观的添加和查看,把接口设置到页面下面,这样用户在某个页面所能访问的接口必须在这里定义好(不包括查询参数),如果是公共接口则需要重复定义
-
这样设计的好处最大的就是不会干扰原来程序的运行,不会增加新的数据库,对后台原先的逻辑不会有大的改动
-
在页面上通过添加权限按钮可以添加页面级别的权限,在某个页面资源右侧可以通过添加接口按钮添加所属的接口资源
-
页面和接口的编辑有所不同 页面的编辑可以设置是否展示(不展示的页面也就是不会出现在目录里,但是可以访问到,如果不定义就没有权限访问该页面了,sort字段也是升序排列),接口的编辑没有这两项
子权限管理
子权限是用来管理单个页面上面按钮的权限,控制其是否显示,这一块功能目前还没有去应用
角色管理
目前我设置了三个角色,
- 财务清算部,可以查看长城和小贷的项目
- 七桥管理员,可以查看七桥admin,七桥房产的项目
- 系统管理员,网关系统,埋点系统等 后面的设置以OA上的申请为主
系统开发
系统流程
原先把页面渲染和输出JSON通过middleware处理,但是这样增加了中间件的数量,增加了复杂度,这次增加了一个基类函数,所有的控制器通过继承基类函数开发
const BaseController = require('./baseController')
class AccountController extends BaseController
如果方法需要输出页面,
async list () {
await this.render()
}
如果方法需要输出JSON
async doEdit () {
const data = this.ctx.request.body;
this.renderJSON(await this.ctx.service.user.doEdit(data));
}
中间件
catadmin把一些权限校验的工作放在中间件里处理,这部分定义是在config.default.js里的middleware项
middleware: ['errorHandler', 'urlRedirect', 'saveSession', 'authentication']
- url_redirect 统一的路由重定向,如果用户访问的地址未经过路由定义,全部重定向到前台或者后台的首页
- saveSession 每次访问页面延长session的时效
- authentication 校验访问的路由 用户是够有权限
开发流程
- 启动项目,在根目录npm run dev启动egg服务器,在app/public目录下npm run dev开启静态资源编译
- 在view目录下面建立新项目的文件夹,左侧菜单栏统一使用layout/common/leftAside.tpl,目录结构和路由结构保持一致,其他的CSS,JS目录同理
- 访问的页面权限,接口权限在后台配置
js开发流程
引入Page页面类,采用如下的结构开发
var page = new Page({
eventsMap: {
'click #addauthority': 'addauthority',
'click .delete': 'delete'
},
mounted () {
this.initialization();
},
methods: {
initialization: function () {
}
性能优化小计
- 由于是多页面应用,有几十个文件,将它们作为chunk提取公用文件,生成的文件大约有2M
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
chunks: chunks,
minChunks: 2
}),
- 移除common.js,放在基类JS去引用,最终打包进vender.js中
- 合并component下面的css文件
后端优化
- 原先数据表中的数据转为树形结构的函数优化
let result = [];
//data.sort(ascOrder('fid'));
directory.forEach((item) => {
let flag = result.find((itemC) => { return item.fid == itemC.id; });
if (flag) {
flag.child.push({cname: item.name, isshow: item.isshow, id: item.id, sort: item.sort});
} else {
if (item.fid) {
result.push({fname: item.name, isshow: item.isshow, id: item.id, fid: item.fid, sort: item.sort, child: [{isshow: item.isshow, cname: item.name, id: item.id}]});
} else {
result.push({fname: item.name, isshow: item.isshow, id: item.id, fid: item.fid, sort: item.sort, child: []});
}
}
})
改成了
let idMap = [],
jsonTree = [];
//data.sort(ascOrder('fid'));
const pid = 'fid'
const id= 'id'
const children = 'child'
directory.forEach(v => {
idMap[v[id]] = v;
})
directory.forEach((v) => {
let parent = idMap[v[pid]];
if(parent) {
!parent[children] && (parent[children] = []);
parent[children].push(v);
} else {
jsonTree.push(v);
}
速度快了一倍
- 合并获取数据的接口