一、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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。