2017-09-03 08:43:13 +08:00
|
|
|
|
const yapi = require('../yapi.js');
|
|
|
|
|
const projectModel = require('../models/project.js');
|
|
|
|
|
const interfaceModel = require('../models/interface.js');
|
|
|
|
|
const mockExtra = require('../../common/mock-extra.js');
|
|
|
|
|
const _ = require('underscore');
|
|
|
|
|
const Mock = require('mockjs');
|
2017-08-16 17:13:14 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function matchApi(apiPath, apiRule) {
|
|
|
|
|
let apiRules = apiRule.split("/");
|
2017-09-19 13:22:36 +08:00
|
|
|
|
let apiPaths = apiPath.split("/");
|
2017-08-16 17:13:14 +08:00
|
|
|
|
if (apiPaths.length !== apiRules.length) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
for (let i = 0; i < apiRules.length; i++) {
|
|
|
|
|
if (apiRules[i] && apiRules[i].indexOf(":") !== 0) {
|
|
|
|
|
if (apiRules[i] !== apiPaths[i]) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2017-07-10 20:02:44 +08:00
|
|
|
|
|
2017-07-05 16:17:58 +08:00
|
|
|
|
module.exports = async (ctx, next) => {
|
2017-09-08 11:18:30 +08:00
|
|
|
|
// no used variable 'hostname' & 'config'
|
|
|
|
|
// let hostname = ctx.hostname;
|
|
|
|
|
// let config = yapi.WEBCONFIG;
|
2017-08-15 12:08:59 +08:00
|
|
|
|
let path = ctx.path;
|
2017-08-16 17:13:14 +08:00
|
|
|
|
|
2017-07-27 19:49:26 +08:00
|
|
|
|
|
2017-08-15 12:08:59 +08:00
|
|
|
|
if (path.indexOf('/mock/') !== 0) {
|
2017-07-27 19:49:26 +08:00
|
|
|
|
if (next) await next();
|
2017-07-10 20:02:44 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2017-07-27 19:49:26 +08:00
|
|
|
|
|
2017-08-15 12:08:59 +08:00
|
|
|
|
let paths = path.split("/");
|
|
|
|
|
let projectId = paths[2];
|
|
|
|
|
paths.splice(0, 3);
|
|
|
|
|
path = "/" + paths.join("/");
|
2017-08-16 17:13:14 +08:00
|
|
|
|
if (!projectId) {
|
2017-08-15 12:08:59 +08:00
|
|
|
|
return ctx.body = yapi.commons.resReturn(null, 400, 'projectId不能为空');
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-27 19:49:26 +08:00
|
|
|
|
yapi.commons.log('MockServer Running...');
|
2017-08-15 12:08:59 +08:00
|
|
|
|
let projectInst = yapi.getInst(projectModel), project;
|
2017-07-27 19:49:26 +08:00
|
|
|
|
try {
|
2017-08-15 12:08:59 +08:00
|
|
|
|
project = await projectInst.get(projectId);
|
2017-07-27 19:49:26 +08:00
|
|
|
|
} catch (e) {
|
2017-07-10 20:02:44 +08:00
|
|
|
|
return ctx.body = yapi.commons.resReturn(null, 403, e.message);
|
|
|
|
|
}
|
2017-07-27 19:49:26 +08:00
|
|
|
|
|
2017-08-15 12:08:59 +08:00
|
|
|
|
if (project === false) {
|
|
|
|
|
return ctx.body = yapi.commons.resReturn(null, 400, '不存在的项目');
|
2017-07-10 20:02:44 +08:00
|
|
|
|
}
|
2017-08-16 17:13:14 +08:00
|
|
|
|
|
2017-09-08 11:18:30 +08:00
|
|
|
|
let interfaceData, newpath;
|
2017-07-10 20:02:44 +08:00
|
|
|
|
let interfaceInst = yapi.getInst(interfaceModel);
|
|
|
|
|
|
2017-07-27 19:49:26 +08:00
|
|
|
|
try {
|
2017-08-16 17:13:14 +08:00
|
|
|
|
newpath = path.substr(project.basepath.length);
|
|
|
|
|
interfaceData = await interfaceInst.getByPath(project._id, newpath, ctx.method);
|
2017-09-19 13:22:36 +08:00
|
|
|
|
|
|
|
|
|
//处理query_path情况
|
2017-07-27 19:49:26 +08:00
|
|
|
|
if (!interfaceData || interfaceData.length === 0) {
|
2017-09-19 13:22:36 +08:00
|
|
|
|
interfaceData = await interfaceInst.getByQueryPath(project._id, newpath, ctx.method);
|
|
|
|
|
|
|
|
|
|
let i, l, j, len, curQuery, match = false;
|
|
|
|
|
for (i = 0, l = interfaceData.length; i < l; i++) {
|
|
|
|
|
match = false;
|
|
|
|
|
currentInterfaceData = interfaceData[i];
|
|
|
|
|
curQuery = currentInterfaceData.query_path;
|
|
|
|
|
if (!curQuery || typeof curQuery !== 'object' || !curQuery.path) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
for (j = 0, len = curQuery.params.length; j < len; j++) {
|
|
|
|
|
if (ctx.query[curQuery.params[j].name] !== curQuery.params[j].value) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if(j === len -1){
|
|
|
|
|
match = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (match) {
|
|
|
|
|
interfaceData = [currentInterfaceData];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(i === l -1){
|
|
|
|
|
interfaceData = [];
|
|
|
|
|
}
|
2017-07-31 10:15:16 +08:00
|
|
|
|
}
|
2017-09-19 13:22:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//处理动态路由
|
|
|
|
|
if (!interfaceData || interfaceData.length === 0) {
|
2017-08-16 17:13:14 +08:00
|
|
|
|
let newData = await interfaceInst.getVar(project._id, ctx.method);
|
|
|
|
|
let findInterface = _.find(newData, (item) => {
|
|
|
|
|
return matchApi(newpath, item.path)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!findInterface) {
|
2017-09-19 13:22:36 +08:00
|
|
|
|
//非正常跨域预检请求回应
|
|
|
|
|
if (ctx.method === 'OPTIONS') {
|
|
|
|
|
ctx.set("Access-Control-Allow-Origin", "*")
|
|
|
|
|
ctx.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
|
|
|
|
|
return ctx.body = 'ok'
|
|
|
|
|
}
|
2017-09-21 16:16:08 +08:00
|
|
|
|
return ctx.body = yapi.commons.resReturn(null, 404, `不存在的api, 当前请求path为 ${newpath}, 请求方法为 ${ctx.method} ,请确认是否定义此请求。`);
|
2017-08-16 17:13:14 +08:00
|
|
|
|
}
|
|
|
|
|
interfaceData = [
|
|
|
|
|
await interfaceInst.get(findInterface._id)
|
|
|
|
|
]
|
|
|
|
|
|
2017-07-10 20:02:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-27 19:49:26 +08:00
|
|
|
|
if (interfaceData.length > 1) {
|
2017-09-19 13:22:36 +08:00
|
|
|
|
|
|
|
|
|
|
2017-07-10 20:02:44 +08:00
|
|
|
|
return ctx.body = yapi.commons.resReturn(null, 405, '存在多个api,请检查数据库');
|
2017-09-19 13:22:36 +08:00
|
|
|
|
} else {
|
|
|
|
|
interfaceData = interfaceData[0];
|
2017-07-10 20:02:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-19 13:22:36 +08:00
|
|
|
|
|
2017-07-31 10:15:16 +08:00
|
|
|
|
ctx.set("Access-Control-Allow-Origin", "*")
|
2017-07-27 19:49:26 +08:00
|
|
|
|
if (interfaceData.res_body_type === 'json') {
|
2017-08-16 17:13:14 +08:00
|
|
|
|
try {
|
2017-09-17 13:36:51 +08:00
|
|
|
|
let res = mockExtra(
|
2017-08-30 14:43:44 +08:00
|
|
|
|
yapi.commons.json_parse(interfaceData.res_body),
|
|
|
|
|
{
|
|
|
|
|
query: ctx.request.query,
|
|
|
|
|
body: ctx.request.body
|
|
|
|
|
}
|
2017-08-01 15:47:06 +08:00
|
|
|
|
);
|
2017-09-17 13:36:51 +08:00
|
|
|
|
res = Mock.mock(res);
|
|
|
|
|
let context = {
|
|
|
|
|
projectData: project,
|
|
|
|
|
interfaceData: interfaceData,
|
|
|
|
|
ctx: ctx,
|
|
|
|
|
mockJson: res
|
|
|
|
|
}
|
|
|
|
|
await yapi.emitHook('mock_after', context);
|
|
|
|
|
return ctx.body = context.mockJson;
|
2017-08-16 17:13:14 +08:00
|
|
|
|
} catch (e) {
|
2017-08-30 14:43:44 +08:00
|
|
|
|
yapi.commons.log(e, 'error')
|
2017-08-01 15:47:06 +08:00
|
|
|
|
return ctx.body = {
|
|
|
|
|
errcode: 400,
|
2017-09-17 19:22:13 +08:00
|
|
|
|
errmsg: '解析出错,请检查。Error: '+ e.message,
|
|
|
|
|
data: null
|
2017-08-01 15:47:06 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-07-10 20:02:44 +08:00
|
|
|
|
}
|
|
|
|
|
return ctx.body = interfaceData.res_body;
|
2017-07-27 19:49:26 +08:00
|
|
|
|
} catch (e) {
|
2017-08-16 17:13:14 +08:00
|
|
|
|
console.error(e)
|
2017-07-10 20:02:44 +08:00
|
|
|
|
return ctx.body = yapi.commons.resReturn(null, 409, e.message);
|
|
|
|
|
}
|
2017-08-10 12:14:35 +08:00
|
|
|
|
};
|