Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev

This commit is contained in:
suxiaoxin 2017-08-30 15:56:42 +08:00
commit d86f7f47d1
7 changed files with 164 additions and 65 deletions

View File

@ -3032,7 +3032,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#585" target="_blank">./server/controllers/project.js:585</a>
<a href="./static/server/controllers/project.js.html#583" target="_blank">./server/controllers/project.js:583</a>
</p>
@ -3127,7 +3127,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#639" target="_blank">./server/controllers/project.js:639</a>
<a href="./static/server/controllers/project.js.html#637" target="_blank">./server/controllers/project.js:637</a>
</p>
@ -3192,7 +3192,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#18" target="_blank">./server/controllers/interface.js:18</a>
<a href="./static/server/controllers/interface.js.html#19" target="_blank">./server/controllers/interface.js:19</a>
</p>
@ -3513,7 +3513,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#137" target="_blank">./server/controllers/interface.js:137</a>
<a href="./static/server/controllers/interface.js.html#155" target="_blank">./server/controllers/interface.js:155</a>
</p>
@ -3578,7 +3578,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#162" target="_blank">./server/controllers/interface.js:162</a>
<a href="./static/server/controllers/interface.js.html#180" target="_blank">./server/controllers/interface.js:180</a>
</p>
@ -3643,7 +3643,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#224" target="_blank">./server/controllers/interface.js:224</a>
<a href="./static/server/controllers/interface.js.html#242" target="_blank">./server/controllers/interface.js:242</a>
</p>
@ -3876,7 +3876,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#379" target="_blank">./server/controllers/interface.js:379</a>
<a href="./static/server/controllers/interface.js.html#396" target="_blank">./server/controllers/interface.js:396</a>
</p>
@ -4805,7 +4805,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interfaceCol.js.html#327" target="_blank">./server/controllers/interfaceCol.js:327</a>
<a href="./static/server/controllers/interfaceCol.js.html#329" target="_blank">./server/controllers/interfaceCol.js:329</a>
</p>
@ -4879,7 +4879,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interfaceCol.js.html#368" target="_blank">./server/controllers/interfaceCol.js:368</a>
<a href="./static/server/controllers/interfaceCol.js.html#370" target="_blank">./server/controllers/interfaceCol.js:370</a>
</p>
@ -4939,7 +4939,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interfaceCol.js.html#410" target="_blank">./server/controllers/interfaceCol.js:410</a>
<a href="./static/server/controllers/interfaceCol.js.html#412" target="_blank">./server/controllers/interfaceCol.js:412</a>
</p>

View File

@ -65,9 +65,53 @@
<div class="ydoc-container">
<div class="ydoc-container-content " id="readme">
<div class="ydoc-container-content ">
<article class="markdown-body">
<div class="content-left staticsidenav" role="complementary">
<nav class="docs-sidebar hidden-print hidden-xs hidden-sm">
<ul class="nav docs-sidenav">
<!-- <li > -->
<li >
<a href="#Mock介绍">Mock介绍</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#1_如何使用Mock?">1 如何使用Mock?</a>
</li>
<li >
<a href="#1.1_最简单最直接的方式">1.1 最简单最直接的方式</a>
</li>
<li >
<a href="#1.2_基于本地服务器反向代理">1.2 基于本地服务器反向代理</a>
</li>
<li >
<a href="#2.1_Mock语法规范">2.1 Mock语法规范</a>
</li>
<li >
<a href="#数据模板定义规范Data_Template_DefinitionDTD">数据模板定义规范Data Template DefinitionDTD</a>
</li>
<li >
<a href="#数据占位符定义规范Data_Placeholder_DefinitionDPD">数据占位符定义规范Data Placeholder DefinitionDPD</a>
</li>
</ul>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<h2 class="subject" id="Mock介绍">Mock介绍 <a class="hashlink" href="#Mock介绍">#</a></h2><p> <p style='text-indent:2em;line-height:1.8em'>yapi的Mock功能可以根据用户的输入接口信息如协议、URL、接口名、请求头、请求参数、mock规则(<a href="#mock">点击到Mock规则</a>生成Mock接口这些接口会自动生成模拟数据创建者可以自由构造需要的数据。而且与常见的Mock方式如将Mock写在代码里和JS拦截等相比yapi的Mock在使用场景和效率和复杂度上是相差甚远的正是由于yapi的Mock是一个第三方平台那么在团队开发时任何人都可以权限许可下创建、修改接口信息等操作这对于团队开发是很有好处的。</p>
<p> <strong>mock地址解析</strong>yapi平台网址+mock+<strong>您的项目id</strong>+<strong>接口实际请求path</strong></p>
<p>项目id可以在项目设置里查看到</p>
@ -198,7 +242,7 @@ name<span class="token operator">:</span> <span class="token punctuation">{</spa
<span class="token property">"full"</span><span class="token operator">:</span> <span class="token string">"Charles Brenda Lopez"</span>
<span class="token punctuation">}</span>
</code></pre>
</article>
</div>
</div>
</div>
@ -212,6 +256,9 @@ name<span class="token operator">:</span> <span class="token punctuation">{</spa
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>

View File

@ -65,9 +65,41 @@
<div class="ydoc-container">
<div class="ydoc-container-content " id="readme">
<div class="ydoc-container-content ">
<article class="markdown-body">
<div class="content-left staticsidenav" role="complementary">
<nav class="docs-sidebar hidden-print hidden-xs hidden-sm">
<ul class="nav docs-sidenav">
<!-- <li > -->
<li >
<a href="#快速开始">快速开始</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#1_创建项目分组">1 创建项目分组</a>
</li>
<li >
<a href="#3_添加项目">3 添加项目</a>
</li>
<li >
<a href="#4_项目详情页面">4 项目详情页面</a>
</li>
</ul>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<h2 class="subject" id="快速开始">快速开始 <a class="hashlink" href="#快速开始">#</a></h2><h3 class="subject" id="1_创建项目分组">1 创建项目分组 <a class="hashlink" href="#1_创建项目分组">#</a></h3><p>登录之后进到项目首页,左边侧边栏显示的即分组列表。</p>
<p><img src="./images/project_group.png" width = "200" style="margin-left:170px;display:block;" alt="图片名称" align=center /></p>
<p>联系管理员添加分组并且把你设置为组长或让组长邀请你加入到某项目分组</p>
@ -85,7 +117,7 @@
<img src="./images/interface_run.png" width="800" style="margin:0px auto;display:block;" alt="图片名称" align=center />
点击保存按钮可把当前测试保存到测试集,方便下次调试</p>
</article>
</div>
</div>
</div>
@ -99,6 +131,9 @@
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>

View File

@ -29,6 +29,7 @@
import interfaceCatModel from '../models/interfaceCat.js';
import interfaceCaseModel from '../models/interfaceCase.js'
import _ from 'underscore';
import baseController from './base.js';
import yapi from '../yapi.js';
import userModel from '../models/user.js';
@ -88,6 +89,7 @@ class interfaceController extends baseController {
}
params.method = params.method || 'GET';
params.method = params.method.toUpperCase();
params.req_params = params.req_params || [];
params.res_body_type = params.res_body_type ? params.res_body_type.toLowerCase() : 'json';
if (!params.project_id) {
@ -132,7 +134,23 @@ class interfaceController extends baseController {
if (params.req_body_form) {
data.req_body_form = params.req_body_form;
}
if (params.req_params && Array.isArray(params.req_params) && params.req_params.length > 0) {
if (params.path.indexOf(":") > 0) {
let paths = params.path.split("/"), name, i;
for (i = 1; i < paths.length; i++) {
if (paths[i][0] === ':') {
name = paths[i].substr(1);
if (!_.find(params.req_params, { name: name })) {
params.req_params.push({
name: name,
desc: ''
})
}
}
}
}
if ( params.req_params.length > 0) {
data.type = 'var'
data.req_params = params.req_params;
} else {
@ -143,9 +161,9 @@ class interfaceController extends baseController {
}
let result = await this.Model.save(data);
// let project = await this.projectModel.get(params.project_id);
this.catModel.get(params.catid).then((cate)=>{
this.catModel.get(params.catid).then((cate) => {
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 为分类 "${cate.name}" 添加了接口 "${data.title}"`,
@ -155,7 +173,7 @@ class interfaceController extends baseController {
typeid: params.project_id
});
});
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
@ -278,7 +296,6 @@ class interfaceController extends baseController {
async up(ctx) {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
title: 'string',
path: 'string',
@ -306,7 +323,7 @@ class interfaceController extends baseController {
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/');
}
if (params.path && params.path !== interfaceData.path && params.method !== interfaceData.method) {
if (params.path && (params.path !== interfaceData.path || params.method !== interfaceData.method)) {
let checkRepeat = await this.Model.checkRepeat(interfaceData.project_id, params.path, params.method);
if (checkRepeat > 0) {
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']');
@ -317,28 +334,28 @@ class interfaceController extends baseController {
up_time: yapi.commons.time()
};
if (params.path) {
if (!_.isUndefined(params.path)) {
data.path = params.path;
}
if (params.title) {
if (!_.isUndefined(params.title)) {
data.title = params.title;
}
if (params.desc) {
if (!_.isUndefined(params.desc)) {
data.desc = params.desc;
}
if (params.method) {
if (!_.isUndefined(params.method)) {
data.method = params.method;
}
if (params.catid) {
if (!_.isUndefined(params.catid)) {
data.catid = params.catid;
}
if (params.req_headers) {
if (!_.isUndefined(params.req_headers)) {
data.req_headers = params.req_headers;
}
if (params.req_body_form) {
if (!_.isUndefined(params.req_body_form)) {
data.req_body_form = params.req_body_form;
}
if (params.req_params && Array.isArray(params.req_params) && params.req_params.length > 0) {
@ -348,25 +365,25 @@ class interfaceController extends baseController {
data.type = 'static'
}
if (params.req_query) {
if (!_.isUndefined(params.req_query)) {
data.req_query = params.req_query;
}
if (params.req_body_other) {
if (!_.isUndefined(params.req_body_other)) {
data.req_body_other = params.req_body_other;
}
if (params.req_body_type) {
if (!_.isUndefined(params.req_body_type)) {
data.req_body_type = params.req_body_type;
}
if (params.res_body_type) {
if (!_.isUndefined(params.res_body_type)) {
data.res_body_type = params.res_body_type;
}
if (params.res_body) {
if (!_.isUndefined(params.res_body)) {
data.res_body = params.res_body;
}
if (params.status) {
if (!_.isUndefined(params.status)) {
data.status = params.status;
}
@ -374,7 +391,7 @@ class interfaceController extends baseController {
let result = await this.Model.up(id, data);
let username = this.getUsername();
if (params.catid) {
this.catModel.get(+params.catid).then((cate)=>{
this.catModel.get(+params.catid).then((cate) => {
yapi.commons.saveLog({
content: `用户 "${username}" 更新了分类 "${cate.name}" 下的接口 "${data.title}"`,
type: 'project',
@ -385,7 +402,7 @@ class interfaceController extends baseController {
});
} else {
let cateid = interfaceData.catid;
this.catModel.get(cateid).then((cate)=>{
this.catModel.get(cateid).then((cate) => {
yapi.commons.saveLog({
content: `用户 "${username}" 更新了分类 "${cate.name}" 下的接口 "${data.title}"`,
type: 'project',
@ -396,7 +413,7 @@ class interfaceController extends baseController {
});
}
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
@ -436,7 +453,7 @@ class interfaceController extends baseController {
let result = await this.Model.del(id);
await this.caseModel.delByInterfaceId(id);
let username = this.getUsername();
this.catModel.get(inter.catid).then((cate)=>{
this.catModel.get(inter.catid).then((cate) => {
yapi.commons.saveLog({
content: `用户 "${username}" 删除了分类 "${cate.name}" 下的接口 "${inter.title}"`,
type: 'project',
@ -445,7 +462,7 @@ class interfaceController extends baseController {
typeid: cate.project_id
});
})
ctx.body = yapi.commons.resReturn(result);
} catch (err) {
@ -535,7 +552,7 @@ class interfaceController extends baseController {
name: params.name,
desc: params.desc,
up_time: yapi.commons.time()
});
});
let username = this.getUsername();
let cate = await this.catModel.get(params.catid);

View File

@ -52,7 +52,7 @@ class interfaceColController extends baseController{
* @example
*/
async list(ctx){
try {
try {
let id = ctx.query.project_id;
let result = await this.colModel.list(id);
@ -140,7 +140,7 @@ class interfaceColController extends baseController{
let inst = yapi.getInst(interfaceCaseModel);
let result = await inst.list(id, 'all');
for(let index=0; index< result.length; index++){
result[index] = result[index].toObject();
let interfaceData = await this.interfaceModel.getBaseinfo(result[index].interface_id);
let projectData = await this.projectModel.getBaseInfo(interfaceData.project_id);
@ -224,8 +224,8 @@ class interfaceColController extends baseController{
typeid: params.project_id
});
});
ctx.body = yapi.commons.resReturn(result);
}catch(e){
@ -292,8 +292,8 @@ class interfaceColController extends baseController{
typeid: caseData.project_id
});
});
ctx.body = yapi.commons.resReturn(result);
@ -322,16 +322,18 @@ class interfaceColController extends baseController{
}
result = result.toObject();
let data = await this.interfaceModel.get(result.interface_id);
data = data.toObject();
let projectData = await this.projectModel.getBaseInfo(data.project_id);
result.path = projectData.basepath + data.path;
result.method = data.method;
result.req_body_type = data.req_body_type;
result.req_headers = data.req_headers;
result.req_body_form = this.handleParamsValue(data.req_body_form, result.req_body_form)
result.req_query = this.handleParamsValue(data.req_query, result.req_query)
result.req_params = this.handleParamsValue(data.req_params, result.req_params)
ctx.body = yapi.commons.resReturn(result);
}catch(e){
ctx.body = yapi.commons.resReturn(null, 400, e.message)
@ -429,7 +431,7 @@ class interfaceColController extends baseController{
// typeid: params.project_id
// });
return ctx.body = yapi.commons.resReturn('success')
return ctx.body = yapi.commons.resReturn('成功!')
}catch(e){
ctx.body = yapi.commons.resReturn(null, 400, e.message)
}
@ -508,7 +510,7 @@ class interfaceColController extends baseController{
typeid: caseData.project_id
});
});
return ctx.body = yapi.commons.resReturn(result);

View File

@ -371,7 +371,7 @@ class projectController extends baseController {
for(let index=0, item, r = 1; index< result.length; index++){
item = result[index].toObject();
if(item.project_type === 'private' && auth === false){
r = await this.Model.checkMemberRepeat(this.getUid());
r = await this.Model.checkMemberRepeat(item._id, this.getUid());
if(r === 0){
continue;
}
@ -458,7 +458,7 @@ class projectController extends baseController {
if (check === 0) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在');
}
if (await this.checkAuth(params.id, 'group', 'danger') !== true) {
if (await this.checkAuth(params.id, 'project', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
@ -587,14 +587,12 @@ class projectController extends baseController {
data.project_type = params.project_type
}
if (params.name) data.name = params.name;
if (params.desc) data.desc = params.desc;
if (params.basepath) {
data.basepath = params.basepath;
}
if (params.env) data.env = params.env;
if (params.color) data.color = params.color;
if (params.icon) data.icon = params.icon;
if (!_.isUndefined(params.name)) data.name = params.name;
if (!_.isUndefined(params.desc)) data.desc = params.desc;
data.basepath = params.basepath;
if (!_.isUndefined(params.env)) data.env = params.env;
if (!_.isUndefined(params.color)) data.color = params.color;
if (!_.isUndefined(params.icon)) data.icon = params.icon;
let result = await this.Model.up(id, data);
let username = this.getUsername();
yapi.commons.saveLog({

View File

@ -12,15 +12,15 @@
"homeUrl": "http://ued.qunar.com/ymfe/" // logourl
},
"options": {
"foldcode": true
// "markdown": { // markdown
// "menuLevel": 4 // head -1
// }
"foldcode": true,
"markdown": { // markdown
"menuLevel": 2 // head -1
}
},
"pages": [{
"name": "index", // Page Name html : index.html
"title": "首页", // Page Title
"homepage": { //
"homepage": { //
"version": "v1.0.0", // banner
"button": [{ // banner
"name": "开始",