一、ERP管理系统

项目环境:React+AntPro+AntDesign
负责模块:系统框架搭建+系统登录+基础类模块

一、框架搭建

1、request请求框架

采用axios和fecth两种方式向后台发送请求,从service层看起,

export async function acceptList(params) {
  return request(createTheURL(Config.API.ACCEPT, 'list'), {
    method: 'PUT',
    body: params,
  });
}

因为我们大多数的API接口的前缀相同,例如/api/user/add /api/user/edit,所以我们可以把相同的部分提取出来,写成一个静态的配置文件。然后通过createTheURL拼接完整的请求地址。

2、用策略者模式分发不同的请求方式

export default function request(url,options) {
    const { REQUEST_METHOD } = API || 'axiosRequest';
    const requestList = {
      axiosRequest:requestAxios,
      fecthRequest:requsetFecth,
    }
    return requestList[REQUEST_METHOD](url,options);
}

我们可以通过传入不同REQUEST_METHOD ,来选择调用axios或者是fecth还是其他的请求方式。

二、基础类的编写

在管理系统中大量用到了表格的CRUD,所以我把这一块做一成了一个组件,一是为了控制整个项目风格的统一,二是为了规定开发者代码编写的规范。

1、主要思想
图片描述
把所有的数据通过index.js进行分发,通过传入{searchProps}、{btnProps}、{pageProps}、{modalProps}来进行数据,在4个组件中只是控制UI,不涉及任何数据操作。

2、注意事项

  • this.props.form是在index中注册还是在子组件中注册。
    form我们必须在子组件中注册,然后index中只需要传入向后发送请求的函数即可,因为如果我们需要控制两个form表单时,在index中注册就会造成数据浑乱。

二、Node后端开发

项目环境:Node+Thinkjs+Mysql
负责模块:鉴权中间件 + 基类Controller

一、鉴权中间件

1、鉴权流程

图片描述

2、详细描述

  • apinfo Api信息提取
module.exports = (options = {}) => {
  return (ctx, next) => {
    const url = ctx.url;
    const pathList = url.split('/');
    pathList.splice(0, 1);
    let PATH = pathList.join('_');
    PATH = PATH.toUpperCase();
    const data = ApiMap(PATH);
    if (!data) {
      Object.assign(ctx, URLERROR);
      return;
    }
    ctx.state.ApiInfo = data;
    return next();
  };
};

我们在ApiMap配置我们的接口参数,使用Map来查询对应的接口配置参数

配置示例:
  map.set('USER_USER_LISTALL', {
    model: 'user',
    method: 'listall',
    checktoken: true,
    authority: 'view_qx'
  });
  • tokencheck 校验token
module.exports = (options = {}) => {
  return (ctx, next) => {
    const { checktoken } = ctx.state.ApiInfo; // 接口是否需要检验token
    if (checktoken) {
      const { token } = ctx.request.header;
      // 验证是否有token,并且token是否过期或者被篡改
      if (token && Token.checkToken(token)) {
        const tokenInfo = Token.decodeToken(token);
        ctx.state.UserInfo = tokenInfo.payload.data;
        return next();
      } else {
        Object.assign(ctx, TOKENEXPIRED);
        return;
      }
    }
    return next();
  };
};
  • authority 是否具有路由权限
module.exports = (options = {}) => {
  return async(ctx, next) => {
    const { UserInfo, ApiInfo: {checktoken, authority} } = ctx.state;
    // 检查是否具有路由权限
    if (checktoken) {
      const UserRoleModel = ctx.model('userrole');
      const params = {
        user_id: UserInfo.id
      };
      // 查询数据库
      const userdata = await UserRoleModel.where(params).find();
      const { authority: userauth } = userdata;
      const authlist = userauth.split(';') || [];
      if (authlist.indexOf(authority) < 0) {
        Object.assign(ctx, USERAUTHERROR);
        return;
      }
      return next();
    }
    return next();
  };
};

二、基础BasicController

1、柯里化函数
由于在controller中大部分的增删查改都是大体一致的,所以说我们可以把这些通过一个柯里化函数去用函数创建函数。

// 构建柯里化函数
curry(fn) {
    const _this = this;
    const args = Array.prototype.slice.call(arguments, 1);
    return function() {
      const innerArgs = Array.prototype.slice.call(arguments);
      const finalArgs = args.concat(innerArgs);
      return fn.apply(_this, finalArgs);
    };
  }
//  函数模板
async commonAction(model, method, params) {
    let data;
    let isTrue = true;
    switch (method) {
      case 'get':
        data = await this.model(model).getAction(params);
        break;
      case 'listall':
        data = await this.model(model).listallAction(params);
        break;
      case 'del':
        data = await this.model(model).delAction(params);
        break;
      case 'edit':
        data = await this.model(model).editAction(params);
        break;
      case 'add':
        data = await this.model(model).addAction(params);
        break;
      case 'listpage':
        data = await this.model(model).listpageAction(params);
        break;
      default:
        data = null;
        isTrue = false;
        break;
    }
    return {status: isTrue, data: data};
  }
  // 传入(函数模板、model名、方法)
  const basicAction = this.curry(this.commonAction, model, method);

github地址:Thinkjs


Pjee
204 声望13 粉丝

Life is fantastic


下一篇 »
Wepy目录结构