opti: docs

This commit is contained in:
suxiaoxin 2018-01-05 22:50:50 +08:00
parent 0861d90051
commit 8626c70c4b
7 changed files with 277 additions and 67 deletions

View File

@ -303,6 +303,10 @@
<li >
<a href="#-interface-getCatMenu">/interface/getCatMenu</a>
</li>
<li >
<a href="#-interface-get_custom_field">/interface/get_custom_field</a>
</li>
</ul>
@ -420,7 +424,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#74" target="_blank">./server/controllers/group.js:74</a>
<a href="./static/server/controllers/group.js.html#88" target="_blank">./server/controllers/group.js:88</a>
</p>
@ -482,7 +486,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#97" target="_blank">./server/controllers/group.js:97</a>
<a href="./static/server/controllers/group.js.html#111" target="_blank">./server/controllers/group.js:111</a>
</p>
@ -575,7 +579,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#184" target="_blank">./server/controllers/group.js:184</a>
<a href="./static/server/controllers/group.js.html#198" target="_blank">./server/controllers/group.js:198</a>
</p>
@ -661,7 +665,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#245" target="_blank">./server/controllers/group.js:245</a>
<a href="./static/server/controllers/group.js.html#259" target="_blank">./server/controllers/group.js:259</a>
</p>
@ -747,7 +751,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#287" target="_blank">./server/controllers/group.js:287</a>
<a href="./static/server/controllers/group.js.html#301" target="_blank">./server/controllers/group.js:301</a>
</p>
@ -809,7 +813,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#305" target="_blank">./server/controllers/group.js:305</a>
<a href="./static/server/controllers/group.js.html#319" target="_blank">./server/controllers/group.js:319</a>
</p>
@ -883,7 +887,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#344" target="_blank">./server/controllers/group.js:344</a>
<a href="./static/server/controllers/group.js.html#358" target="_blank">./server/controllers/group.js:358</a>
</p>
@ -945,7 +949,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#404" target="_blank">./server/controllers/group.js:404</a>
<a href="./static/server/controllers/group.js.html#418" target="_blank">./server/controllers/group.js:418</a>
</p>
@ -1017,7 +1021,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/group.js.html#441" target="_blank">./server/controllers/group.js:441</a>
<a href="./static/server/controllers/group.js.html#455" target="_blank">./server/controllers/group.js:455</a>
</p>
@ -2565,7 +2569,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#358" target="_blank">./server/controllers/project.js:358</a>
<a href="./static/server/controllers/project.js.html#359" target="_blank">./server/controllers/project.js:359</a>
</p>
@ -2781,7 +2785,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#417" target="_blank">./server/controllers/project.js:417</a>
<a href="./static/server/controllers/project.js.html#418" target="_blank">./server/controllers/project.js:418</a>
</p>
@ -2853,7 +2857,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#447" target="_blank">./server/controllers/project.js:447</a>
<a href="./static/server/controllers/project.js.html#448" target="_blank">./server/controllers/project.js:448</a>
</p>
@ -2939,7 +2943,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#494" target="_blank">./server/controllers/project.js:494</a>
<a href="./static/server/controllers/project.js.html#495" target="_blank">./server/controllers/project.js:495</a>
</p>
@ -3028,7 +3032,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#539" target="_blank">./server/controllers/project.js:539</a>
<a href="./static/server/controllers/project.js.html#540" target="_blank">./server/controllers/project.js:540</a>
</p>
@ -3146,7 +3150,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#624" target="_blank">./server/controllers/project.js:624</a>
<a href="./static/server/controllers/project.js.html#628" target="_blank">./server/controllers/project.js:628</a>
</p>
@ -3248,7 +3252,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/project.js.html#685" target="_blank">./server/controllers/project.js:685</a>
<a href="./static/server/controllers/project.js.html#689" target="_blank">./server/controllers/project.js:689</a>
</p>
@ -3346,7 +3350,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#82" target="_blank">./server/controllers/interface.js:82</a>
<a href="./static/server/controllers/interface.js.html#95" target="_blank">./server/controllers/interface.js:95</a>
</p>
@ -3667,7 +3671,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#182" target="_blank">./server/controllers/interface.js:182</a>
<a href="./static/server/controllers/interface.js.html#195" target="_blank">./server/controllers/interface.js:195</a>
</p>
@ -3732,7 +3736,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#225" target="_blank">./server/controllers/interface.js:225</a>
<a href="./static/server/controllers/interface.js.html#238" target="_blank">./server/controllers/interface.js:238</a>
</p>
@ -3797,7 +3801,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#323" target="_blank">./server/controllers/interface.js:323</a>
<a href="./static/server/controllers/interface.js.html#336" target="_blank">./server/controllers/interface.js:336</a>
</p>
@ -4030,7 +4034,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#454" target="_blank">./server/controllers/interface.js:454</a>
<a href="./static/server/controllers/interface.js.html#495" target="_blank">./server/controllers/interface.js:495</a>
</p>
@ -4102,7 +4106,7 @@
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#652" target="_blank">./server/controllers/interface.js:652</a>
<a href="./static/server/controllers/interface.js.html#693" target="_blank">./server/controllers/interface.js:693</a>
</p>
@ -4147,6 +4151,68 @@
<pre class="ydoc-example" data-foldnumber=10><code class="js-code"><span class="token punctuation">.</span><span class="token operator">/</span>api<span class="token operator">/</span><span class="token keyword">interface</span><span class="token operator">/</span>getCatMenu</code></pre>
</div>
<div class="con-list-item">
<blockquote class="api">
<h3 id="-interface-get_custom_field" class="page-header subject">
/interface/get_custom_field
<span class="ui-badge">GET</span>
<a class="hashlink" href="#-interface-get_custom_field">#</a>
</h3>
</blockquote>
<p>
<small class="text-muted">描述:</small>
获取自定义接口字段数据
</p>
<p>
<small class="text-muted">源码位置:</small>
<a href="./static/server/controllers/interface.js.html#725" target="_blank">./server/controllers/interface.js:725</a>
</p>
<p>
<small class="text-muted">参数:</small>
</p>
<div class="docs-table">
<table class="yo-table yo-table-border">
<colgroup>
<col class="c1">
<col class="c2">
<col class="c3">
<col class="c4">
</colgroup>
<thead>
<tr class="active">
<th>参数名</th>
<th>类型</th>
<th>描述</th>
<th>必选</th>
<th>支持版本</th>
</tr>
</thead>
<tr>
<td>app_code</td>
<td>String</td>
<td>= '111'</td>
<td>
<i class="yo-ico glyphicon glyphicon-ok text-success"></i>
</td>
<td></td>
</tr>
</table>
</div>
</div>

View File

@ -106,7 +106,7 @@
<p class="home-version">当前版本v1.3.1</p>
<p class="home-version">当前版本v1.3.3</p>
</div>

View File

@ -102,6 +102,14 @@
<nav class="docs-sidebar hidden-print hidden-xs hidden-sm">
<ul class="nav docs-sidenav">
<li >
<a href="#v1.3.3">v1.3.3</a>
</li>
<li >
<a href="#v1.3.2">v1.3.2</a>
</li>
<li >
<a href="#v1.3.1">v1.3.1</a>
</li>
@ -166,7 +174,13 @@
<div class="content-right markdown-body use-sidebar" role="main">
<h3 class="subject" id="v1.3.1">v1.3.1 <a class="hashlink" href="#v1.3.1">#</a></h3><h4 class="subject" id="Bug_Fixed">Bug Fixed <a class="hashlink" href="#Bug_Fixed">#</a></h4><ol>
<h3 class="subject" id="v1.3.3">v1.3.3 <a class="hashlink" href="#v1.3.3">#</a></h3><h4 class="subject" id="Feature">Feature <a class="hashlink" href="#Feature">#</a></h4><ul>
<li>邮件功能中: 1接口信息改动增加通知对应项目所有的成员2默认开启接口改动邮件提醒3) 增加邮件内容的jsondiff信息</li></ul>
<h4 class="subject" id="Bug_Fixed">Bug Fixed <a class="hashlink" href="#Bug_Fixed">#</a></h4><ul>
<li>优化接口运行页面插件提醒</li><li>完善 log 记录不到的问题</li><li>修复接口内容改动不发送邮件问题</li><li>修复部分swagger数据导入丢失问题</li></ul>
<h3 class="subject" id="v1.3.2">v1.3.2 <a class="hashlink" href="#v1.3.2">#</a></h3><h4 class="subject" id="Feature">Feature <a class="hashlink" href="#Feature">#</a></h4><ul>
<li>分组中新增接口自定义字段,便于用户在项目中添加额外字段数据</li><li>导入数据时新增导入loading显示</li></ul>
<h3 class="subject" id="v1.3.1">v1.3.1 <a class="hashlink" href="#v1.3.1">#</a></h3><h4 class="subject" id="Bug_Fixed">Bug Fixed <a class="hashlink" href="#Bug_Fixed">#</a></h4><ol>
<li>修复接口状态和req_params参数无法更新问题</li><li>修复搜索测试集合不展开问题</li><li>修复测试过程中全局header不存在的问题</li></ol>
<h3 class="subject" id="v1.3.0">v1.3.0 <a class="hashlink" href="#v1.3.0">#</a></h3><h4 class="subject" id="Feature">Feature <a class="hashlink" href="#Feature">#</a></h4><ul>
<li>yapi 默认集成 ldap 登录方式</li><li>yapi 做一个 sso 登录插件,基于现有的 qsso 改造成大多数公司可用的</li><li>环境设置支持全局 header</li><li>接口运行页面选择环境增加管理环境的弹层</li><li>接口运行支持加工运行前后的 request 和 response ,主要是处理加密的接口或各种 token 参数问题</li><li>自动化测试除提供自定义脚本外,还提供可视化表单形式验证一些数据,例如 statusCode、bodyContent </li><li>增加查看接口详细改动</li><li>支持接口运行页面 body 全屏编辑</li><li>数据导出到 html 支持了分类</li></ul>

View File

@ -62,6 +62,8 @@ class groupController extends baseController {
minItems: 1
}
this.schemaMap = {
get: {
"*id": id
@ -77,7 +79,7 @@ class groupController extends baseController {
"*member_uids": member_uids
},
changeMemberRole: {
"*member_uids": member_uids,
"*member_uid": "number",
"*id": id,
role: role
},
@ -94,7 +96,19 @@ class groupController extends baseController {
up: {
"*id": id,
"*group_name": group_name,
"group_desc": group_desc
"group_desc": group_desc,
"custom_field1": {
name: 'string',
enable: 'boolen'
},
"custom_field2": {
name: 'string',
enable: 'boolen'
},
"custom_field3": {
name: 'string',
enable: 'boolen'
}
}
}
}

View File

@ -29,12 +29,21 @@
const interfaceCatModel = require('../models/interfaceCat.js');
const interfaceCaseModel = require('../models/interfaceCase.js');
const followModel = require('../models/follow.js');
const groupModel = require('../models/group.js')
const _ = require('underscore');
const url = require('url');
const baseController = require('./base.js');
const yapi = require('../yapi.js');
const userModel = require('../models/user.js');
const projectModel = require('../models/project.js');
const jsondiffpatch = require('jsondiffpatch')
const formattersHtml = jsondiffpatch.formatters.html;
const showDiffMsg = require('../../common/diff-view.js');
const fs = require('fs-extra')
const path = require('path');
// const annotatedCss = require("jsondiffpatch/public/formatters-styles/annotated.css");
// const htmlCss = require("jsondiffpatch/public/formatters-styles/html.css");
class interfaceController extends baseController {
constructor(ctx) {
@ -45,6 +54,7 @@ class interfaceController extends baseController {
this.caseModel = yapi.getInst(interfaceCaseModel);
this.followModel = yapi.getInst(followModel);
this.userModel = yapi.getInst(userModel);
this.groupModel = yapi.getInst(groupModel);
const minLengthStringField = {
type: 'string',
@ -69,7 +79,7 @@ class interfaceController extends baseController {
required: 'string'
}],
req_body_type: 'string',
req_params:[{
req_params: [{
name: 'string',
example: 'string',
desc: 'string'
@ -85,7 +95,8 @@ class interfaceController extends baseController {
}],
'req_body_other': 'string',
res_body_type: 'string',
res_body: 'string'
res_body: 'string',
custom_field_value: 'string'
}
this.schemaMap = {
@ -102,7 +113,9 @@ class interfaceController extends baseController {
'path': minLengthStringField,
'title': minLengthStringField,
'method': minLengthStringField,
'catid': 'number'
'catid': 'number',
'switch_notice': 'boolean',
'message': minLengthStringField
}, addAndUpCommonField)
}
}
@ -223,9 +236,9 @@ class interfaceController extends baseController {
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
}
try {
let result = await this.Model.get(params.id);
// console.log('result', result);
if (!result) {
return ctx.body = yapi.commons.resReturn(null, 490, '不存在的');
}
@ -334,7 +347,7 @@ class interfaceController extends baseController {
let result = await this.catModel.list(project_id), newResult = [];
for (let i = 0, item, list; i < result.length; i++) {
item = result[i].toObject()
list = await this.Model.listByCatid(item._id, '_id title method path')
list = await this.Model.listByCatid(item._id)
for (let j = 0; j < list.length; j++) {
list[j] = list[j].toObject()
}
@ -377,7 +390,6 @@ class interfaceController extends baseController {
async up(ctx) {
let params = ctx.params;
// console.log('params', params.req_params);
if (!_.isUndefined(params.method)) {
params.method = params.method || 'GET';
@ -440,6 +452,12 @@ class interfaceController extends baseController {
let result = await this.Model.up(id, data);
let username = this.getUsername();
let CurrentInterfaceData = await this.Model.get(id);
let logData = {
interface_id: id,
current: CurrentInterfaceData.toObject(),
old: interfaceData.toObject()
}
this.catModel.get(interfaceData.catid).then((cate) => {
yapi.commons.saveLog({
content: `<a href="/user/profile/${this.getUid()}">${username}</a>
@ -449,28 +467,38 @@ class interfaceController extends baseController {
uid: this.getUid(),
username: username,
typeid: cate.project_id,
data: {
interface_id: id,
current: CurrentInterfaceData,
old: interfaceData
}
data: logData
});
});
this.projectModel.up(interfaceData.project_id, { up_time: new Date().getTime() }).then();
if (params.switch_notice === true) {
let diffView = showDiffMsg(jsondiffpatch, formattersHtml, logData);
let annotatedCss = fs.readFileSync(path.resolve(yapi.WEBROOT, 'node_modules/jsondiffpatch/public/formatters-styles/annotated.css'), 'utf8');
let htmlCss = fs.readFileSync(path.resolve(yapi.WEBROOT, 'node_modules/jsondiffpatch/public/formatters-styles/html.css'), 'utf8');
let project = await this.projectModel.getBaseInfo(interfaceData.project_id);
let interfaceUrl = `http://${ctx.request.host}/project/${interfaceData.project_id}/interface/api/${id}`
this.sendNotice(interfaceData.project_id, {
title: `${username} 更新了接口`,
content: `<div><h3>${username}更新了接口(${data.title})</h3>
<p>项目名:${project.name} </p>
<p>修改用户: ${username}</p>
<p>接口名: <a href="${interfaceUrl}">${data.title}</a></p>
<p>接口路径: [${data.method}]${data.path}</p>
<p>详细改动日志: ${params.message}</p></div>`
content: `<html>
<head>
<style>
${annotatedCss}
${htmlCss}
</style>
</head>
<body>
<div><h3>${username}更新了接口(${data.title})</h3>
<p>项目名:${project.name} </p>
<p>修改用户: ${username}</p>
<p>接口名: <a href="${interfaceUrl}">${data.title}</a></p>
<p>接口路径: [${data.method}]${data.path}</p>
<p>详细改动日志: ${this.diffHTML(diffView)}</p></div>
</body>
</html>`
})
}
@ -479,6 +507,19 @@ class interfaceController extends baseController {
}
diffHTML(html) {
if (html.length === 0) {
return `<span style="color: #555">没有改动该操作未改动Api数据</span>`
}
return html.map(item => {
return (`<div>
<h4 class="title">${item.title}</h4>
<div>${item.content}</div>
</div>`)
})
}
/**
* 删除接口
* @interface /interface/del
@ -709,24 +750,95 @@ class interfaceController extends baseController {
}
}
sendNotice(projectId, data) {
this.followModel.listByProjectId(projectId).then(list => {
let users = [];
list.forEach(item => {
users.push(item.uid)
})
this.userModel.findByUids(users).then(list => {
list.forEach(item => {
yapi.commons.sendMail({
to: item.email,
contents: data.content,
subject: data.title
});
})
/**
* 获取自定义接口字段数据
* @interface /interface/get_custom_field
* @method GET
* @category interface
* @foldnumber 10
* @param {String} app_code = '111'
* @returns {Object}
*
*/
async getCustomField(ctx) {
let params = ctx.request.query
})
if (Object.keys(params).length !== 1) {
return ctx.body = yapi.commons.resReturn(null, 400, '参数数量错误');
}
let customFieldName = Object.keys(params)[0];
let customFieldValue = params[customFieldName];
});
try {
// 查找有customFieldName的分组group
let groups = await this.groupModel.getcustomFieldName(customFieldName)
if (groups.length === 0) {
return ctx.body = yapi.commons.resReturn(null, 404, '没有找到对应自定义接口');
}
// 在每个分组group下查找对应project的id值
let interfaces = [];
for (let i = 0; i < groups.length; i++) {
let projects = await this.projectModel.list(groups[i]._id);
// 在每个项目project中查找interface下的custom_field_value
for (let j = 0; j < projects.length; j++) {
let data = {}
let inter = await this.Model.getcustomFieldValue(projects[j]._id, customFieldValue)
if (inter.length > 0) {
data.project_name = projects[j].name
inter = inter.map((item, i) => {
item = inter[i] = inter[i].toObject();
item.res_body = yapi.commons.json_parse(item.res_body)
item.req_body_other = yapi.commons.json_parse(item.req_body_other)
return item
})
data.list = inter;
interfaces.push(data);
}
}
}
return ctx.body = yapi.commons.resReturn(interfaces);
} catch (e) {
yapi.commons.resReturn(null, 400, e.message);
}
}
async sendNotice(projectId, data) {
const list = await this.followModel.listByProjectId(projectId);
const starUsers = list.map(item => item.uid);
const projectList = await this.projectModel.get(projectId);
const projectMenbers = projectList.members.map(item => item.uid);
const users = this.arrUnique(projectMenbers, starUsers);
const usersInfo = await this.userModel.findByUids(users)
const emails = usersInfo.map(item => item.email).join(',');
console.log('emails', emails);
try {
yapi.commons.sendMail({
to: emails,
contents: data.content,
subject: data.title
})
} catch (e) {
yapi.commons.log('邮件发送失败:' + e, 'error')
}
}
arrUnique(arr1, arr2) {
let arr = arr1.concat(arr2);
let res = arr.filter(function (item, index, arr) {
return arr.indexOf(item) === index;
})
return res;
}

View File

@ -169,7 +169,7 @@ class interfaceColController extends baseController {
result.method = data.method;
result.req_body_type = data.req_body_type;
result.req_headers = this.handleParamsValue(data.req_headers, result.req_headers);
result.res_body = data.res_body;
result.res_body_type = data.res_body_type;
result.req_body_form = this.handleParamsValue(data.req_body_form, result.req_body_form)
@ -375,7 +375,7 @@ class interfaceColController extends baseController {
}
for (let i = 0; i < params.interface_list.length; i++) {
let interfaceData = await this.interfaceModel.getBaseinfo(params.interface_list[i]);
let interfaceData = await this.interfaceModel.get(params.interface_list[i]);
data.interface_id = params.interface_list[i];
data.casename = interfaceData.title;
data.req_body_other = interfaceData.req_body_other;

View File

@ -365,6 +365,7 @@ class projectController extends baseController {
async get(ctx) {
let params = ctx.params;
let result = await this.Model.getBaseInfo(params.id);
if (!result) {
return ctx.body = yapi.commons.resReturn(null, 400, '不存在的项目');
}
@ -590,6 +591,8 @@ class projectController extends baseController {
pre_script: 'string',
after_script: 'string'
});
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空');
}
@ -600,7 +603,7 @@ class projectController extends baseController {
let projectData = await this.Model.get(id);
if(params.basepath){
if (params.basepath) {
if ((params.basepath = this.handleBasepath(params.basepath)) === false) {
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误');
}
@ -629,6 +632,7 @@ class projectController extends baseController {
if (!_.isUndefined(params.desc)) data.desc = params.desc;
if (!_.isUndefined(params.group_id)) data.group_id = params.group_id;
if (!_.isUndefined(params.basepath)) data.basepath = params.basepath;
if (!_.isUndefined(params.switch_notice)) data.switch_notice = params.switch_notice;
if (!_.isUndefined(params.color)) data.color = params.color;
if (!_.isUndefined(params.icon)) data.icon = params.icon;
if (!_.isUndefined(params.pre_script)) data.pre_script = params.pre_script;
@ -686,7 +690,7 @@ class projectController extends baseController {
data.env = params.env;
let isRepeat = this.arrRepeat(data.env, 'name');
if(isRepeat){
if (isRepeat) {
return ctx.body = yapi.commons.resReturn(null, 405, '环境变量名重复');
}
let result = await this.Model.up(id, data);
@ -704,11 +708,11 @@ class projectController extends baseController {
}
}
arrRepeat(arr, key){
arrRepeat(arr, key) {
const s = new Set();
arr.forEach(item=>s.add(item[key]))
arr.forEach(item => s.add(item[key]))
return s.size !== arr.length
}
}
/**
* 模糊搜索项目名称或者组名称