catadmin 管理系统

475 阅读4分钟

系统使用

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);
    }

速度快了一倍

  • 合并获取数据的接口

后续计划