fix: merge

This commit is contained in:
suxiaoxin 2017-09-06 17:24:27 +08:00
commit 9a353eb756
77 changed files with 8558 additions and 12472 deletions

View File

@ -36,7 +36,7 @@ class FootItem extends Component {
render () {
return (
<Col span={6}>
<h4 className="title"><Icon type={ this.props.iconType } className="icon" />{this.props.title}</h4>
<h4 className="title">{this.props.iconType ? <Icon type={ this.props.iconType } className="icon" /> : ''}{this.props.title}</h4>
{ this.props.linkList.map(function(item,i){
return (<p key={i}><a href={ item.itemLink } className="link">{ item.itemTitle }</a></p>);
}) }
@ -78,7 +78,7 @@ Footer.defaultProps = {
},
{
title: '其他项目',
iconType: 'layout',
iconType: 'appstore-o',
linkList: [
{
itemTitle: 'Yo',
@ -98,7 +98,6 @@ Footer.defaultProps = {
},
{
title: 'Copyright © 2017 YApi',
iconType: 'layout',
linkList: [
{
itemTitle: '版本: '+packageJson.version,

View File

@ -200,7 +200,14 @@ class MemberList extends Component {
</div>
)
} else {
return '';
// 非管理员可以看到权限 但无法修改
if (record.role === 'owner') {
return '组长';
} else if (record.role === 'dev') {
return '开发者';
} else {
return '';
}
}
}
}];

View File

@ -58,17 +58,17 @@ const HomeGuest = () => (
<span className="desc">YApi让接口开发更简单高效让接口的管理更具可读性可维护性让团队协作更合理</span>
<Row key="feat-motion-row">
<Col span={8} className="section-item" key="feat-wrapper-1">
<Icon type="api" className="img" />
<Icon type="appstore-o" className="img" />
<h4 className="title">项目管理</h4>
<span className="desc">提供基本的项目分组项目管理接口管理功能</span>
</Col>
<Col span={8} className="section-item" key="feat-wrapper-2">
<Icon type="code-o" className="img" />
<Icon type="api" className="img" />
<h4 className="title">接口管理</h4>
<span className="desc">友好的接口文档基于websocket的多人协作接口编辑功能和类postman测试工具让多人协作成倍提升开发效率</span>
</Col>
<Col span={8} className="section-item" key="feat-wrapper-3">
<Icon type="team" className="img" />
<Icon type="database" className="img" />
<h4 className="title">MockServer</h4>
<span className="desc">基于Mockjs使用简单功能强大</span>
</Col>

View File

@ -10,7 +10,6 @@ import ErrMsg from '../../../../components/ErrMsg/ErrMsg.js';
// import { getMockUrl } from '../../reducer/modules/news.js'
@connect(state=>{
// console.log(state);
return {
curData: state.inter.curdata,
currProject: state.project.currProject
@ -30,14 +29,10 @@ class View extends Component {
}
req_body_form(req_body_type,req_body_form){
if(req_body_type === 'json'){
let h = this.countEnter(this.props.curData.req_body_other);
return <div style={{display:this.props.curData.req_body_other?"block":"none"}} className="colBody">
<span className="colKey">请求Body</span>
<div id="vreq_body_json" style={{ minHeight: h*16+20 }}></div>
</div>
}else if(req_body_type === 'form'){
if(req_body_type === 'form'){
const columns = [{
title: '参数名称',
@ -149,7 +144,6 @@ class View extends Component {
}
bindAceEditor(){
if(this.props.curData.req_body_type === "json"&&this.props.curData.title){
// console.log(this.props.curData.req_body_other.indexOf("\n"));
mockEditor({
container: 'vreq_body_json',
data: this.props.curData.req_body_other,
@ -167,6 +161,7 @@ class View extends Component {
}
}
componentDidMount(){
if(this.props.curData.title){
this.bindAceEditor.bind(this)();
}
@ -281,7 +276,12 @@ class View extends Component {
}
}
methodColor = methodColor[this.props.curData.method?this.props.curData.method.toLowerCase():"get"];
statusColor = statusColor[this.props.curData.status?this.props.curData.status.toLowerCase():"undone"]
statusColor = statusColor[this.props.curData.status?this.props.curData.status.toLowerCase():"undone"];
let h = this.countEnter(this.props.curData.req_body_other);
const aceEditor = <div style={{display:this.props.curData.req_body_other&&this.props.curData.req_body_type==="json"?"block":"none"}} className="colBody">
<span className="colKey">请求Body</span>
<div id="vreq_body_json" style={{ minHeight: h*16+20 }}></div>
</div>
if(!methodColor) methodColor = "get";
let res = <div className="caseContainer">
<div className="colName">
@ -332,6 +332,7 @@ class View extends Component {
<span className="colKey">请求Body类型</span>
<span className="colValue">{this.props.curData.req_body_type}</span>
</div>*/}
{ aceEditor }
{this.req_body_form(this.props.curData.req_body_type,this.props.curData.req_body_form)}
{/*<div className="colreqBodyType">
<span className="colKey">返回Body类型</span>

View File

@ -21,6 +21,7 @@
margin: 0px;
.colKey{
padding-bottom: 0px;
}
}
.ace_print-margin{
@ -30,11 +31,12 @@
width: 50%;
float: left;
padding: 8px 16px;
height: 40px;
.colKey{
padding-bottom: 0px;
}
}
.colDesc{
margin-bottom: 0px;
padding-bottom: 0px;

View File

@ -277,7 +277,7 @@ class ProjectData extends Component {
<div className="catidSelect">
<Select
showSearch
style={{ width: 200 }}
style={{ width: '100%' }}
placeholder="请选择数据导入的接口分类"
optionFilterProp="children"
onChange={this.selectChange.bind(this)}

View File

@ -189,7 +189,14 @@ class ProjectMember extends Component {
</div>
)
} else {
return '';
// 非管理员可以看到权限 但无法修改
if (record.role === 'owner') {
return '组长';
} else if (record.role === 'dev') {
return '开发者';
} else {
return '';
}
}
}
}];

36
doc/page/usage/manage.md Normal file
View File

@ -0,0 +1,36 @@
接口管理的逻辑较为复杂,操作频率高,层层审批将严重拖慢生产效率,因此传统的金字塔管理模式并不适用。
YAPI 将扁平化管理模式的思想引入到产品的权限管理中,`超级管理员` 拥有最高的权限,并将权限分配给若干 `组长``超级管理员` 只需管理`组长` 即可实际上管理YAPI各大分组与项目的是“`组长`”。`组长`对分组或项目负责一般由BU负责人/项目负责人担任。
## 认识组长
组长分为 `分组组长``项目组长`,组长对分组或项目负责,拥有分组或项目下的所有权限,二者区别如下:
`分组组长` 有权限修改分组、删除分组,可以创建分组下的项目。一般来说,组长只需要对项目负责,将项目的操作任务安排给项目组长处理即可。
`项目组长` 无法操作分组,但拥有项目的全部权限,`项目组长` 是 YApi 的基层管理者,承担了 YApi 绝大部分的日常管理工作。
## 权限列表
### 项目权限
| 操作 | 游客 | 开发者 | 组长 | 超级管理员 |
| :-------------- | :------------: | :------------: | :------------: | :------------: |
| 浏览公开项目与接口 | ✓ | ✓ | ✓ | ✓ |
| 浏览私有项目与接口 | | ✓ | ✓ | ✓ |
| 编辑项目信息 | | ✓ | ✓ | ✓ |
| 新建接口 | | ✓ | ✓ | ✓ |
| 编辑接口 | | ✓ | ✓ | ✓ |
| 编辑项目头像 | | | ✓ | ✓ |
| 删除项目 | | | ✓ | ✓ |
### 分组权限
| 操作 | 游客 | 开发者 | 组长 | 超级管理员 |
| :-------------- | :------------: | :------------: | :------------: | :------------: |
| 浏览分组 | ✓ | ✓ | ✓ | ✓ |
| 在分组中新建项目 | | ✓ | ✓ | ✓ |
| 编辑分组信息 | | | ✓ | ✓ |
| 管理分组成员 | | | ✓ | ✓ |
| 删除分组 | | | ✓ | ✓ |

View File

@ -1,7 +1,3 @@
## 介绍
## 新建项目
## 组长职责
## 安装 crossRequest chrome 插件
## 权限列表
## 修改项目

5456
prd/index.js Normal file

File diff suppressed because one or more lines are too long

3023
prd/lib.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -1,22 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta id="cross-request-sign" charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>YAPI-高效、易用、功能强大的api管理平台</title>
<link rel="icon" type="image/png" sizes="192x192" href="/image/favicon.png">
<link rel="stylesheet" href="http://127.0.0.1:4000/prd/index@dev.css">
</head>
<body>
<div id="yapi" style="height: 100%;"></div>
<script src="http://127.0.0.1:4000/prd/manifest@dev.js"></script>
<script src="http://127.0.0.1:4000/prd/lib2@dev.js"></script>
<script src="http://127.0.0.1:4000/prd/lib@dev.js"></script>
<script src="http://127.0.0.1:4000/prd/index@dev.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

View File

@ -1,201 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 首页</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="active">
<a href="index.html">首页</a>
</li>
<li class="">
<a href="usage.html">使用手册</a>
</li>
<li class="">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ydoc-banner-home">
<div class="ydoc-banner-area">
<h1 class="home-title">YApi</h1>
<p class="desc home-desc">高效、易用、功能强大的api管理平台旨在为开发、产品、测试人员提供更优雅的接口管理服务。</p>
<a class="ydoc-banner-button home-btn" href="./start.html">开始</a>
<a class="ydoc-banner-button home-btn" href="https://github.com/YMFE/yapi">Github</a>
<p class="home-version">当前版本v1.0.0</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ydoc-container-home" id="readme">
<h1 class="home-page-title">为API开发者设计的管理平台</h1>
<p class="home-page-desc">YApi让接口开发更简单高效让接口的管理更具可读性、可维护性让团队协作更合理。</p>
<h1 class="home-page-title">功能</h1>
<div class="home-thumbnail">
<div class="home-item">
<div class="home-thumbnail-img">
<img class="home-thumbnail-src" src=http://ojk406wln.bkt.clouddn.com/intro_muti.png alt="">
</div>
<h3 class="home-thumbnail-name">项目管理</h3>
<p class="home-thumbnail-desc">YApi成熟的团队管理扁平化项目权限配置满足各类企业的需求</p>
</div>
<div class="home-item">
<div class="home-thumbnail-img">
<img class="home-thumbnail-src" src=http://ojk406wln.bkt.clouddn.com/intro_md.png alt="">
</div>
<h3 class="home-thumbnail-name">接口管理</h3>
<p class="home-thumbnail-desc">友好的接口文档基于websocket的多人协作接口编辑功能和类postman测试工具让多人协作成倍提升开发效率</p>
</div>
<div class="home-item">
<div class="home-thumbnail-img">
<img class="home-thumbnail-src" src=http://ojk406wln.bkt.clouddn.com/intro_theme.png alt="">
</div>
<h3 class="home-thumbnail-name">MockServer</h3>
<p class="home-thumbnail-desc">基于Mockjs使用简单功能强大</p>
</div>
</div>
<article class="markdown-body">
<script>
window.onload = function(){
var aList = $('.ydoc-nav').find('a');
$(aList[aList.length-1]).css('display','none');
}
</script>
</article>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,176 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 管理学院</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="">
<a href="usage.html">使用手册</a>
</li>
<li class="active">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >管理学院</h1>
<p class="desc ">超级管理员、分组/项目组长的学院。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<div class="content-left staticsidenav" role="complementary">
<nav class="docs-sidebar hidden-print hidden-xs hidden-sm">
<ul class="nav docs-sidenav">
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="manage-介绍.html">介绍</a>
</li>
<!-- <li > -->
<li >
<a href="manage-部署.html">部署</a>
</li>
<!-- <li > -->
<li >
<a href="manage-超管职责.html">超管职责</a>
</li>
<!-- <li > -->
<li >
<a href="manage-版本升级.html">版本升级</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,177 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 管理学院</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="">
<a href="usage.html">使用手册</a>
</li>
<li class="active">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >管理学院</h1>
<p class="desc ">超级管理员、分组/项目组长的学院。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="manage-介绍.html">介绍</a>
</li>
<!-- <li > -->
<li >
<a href="manage-部署.html">部署</a>
</li>
<!-- <li > -->
<li >
<a href="manage-超管职责.html">超管职责</a>
</li>
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="manage-版本升级.html">版本升级</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<p>版本升级</p>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,192 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 管理学院</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="">
<a href="usage.html">使用手册</a>
</li>
<li class="active">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >管理学院</h1>
<p class="desc ">超级管理员、分组/项目组长的学院。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="manage-介绍.html">介绍</a>
</li>
<!-- <li > -->
<li >
<a href="manage-部署.html">部署</a>
</li>
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="manage-超管职责.html">超管职责</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#用户管理">用户管理</a>
</li>
<li >
<a href="#分配组长">分配组长</a>
</li>
<li >
<a href="#维护数据库">维护数据库</a>
</li>
</ul>
<!-- <li > -->
<li >
<a href="manage-版本升级.html">版本升级</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<h2 class="subject" id="用户管理">用户管理 <a class="hashlink" href="#用户管理">#</a></h2><h2 class="subject" id="分配组长">分配组长 <a class="hashlink" href="#分配组长">#</a></h2><h2 class="subject" id="维护数据库">维护数据库 <a class="hashlink" href="#维护数据库">#</a></h2>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,188 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 管理学院</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="">
<a href="usage.html">使用手册</a>
</li>
<li class="active">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >管理学院</h1>
<p class="desc ">超级管理员、分组/项目组长的学院。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="manage-介绍.html">介绍</a>
</li>
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="manage-部署.html">部署</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#快速部署">快速部署</a>
</li>
<li >
<a href="#配置说明">配置说明</a>
</li>
</ul>
<!-- <li > -->
<li >
<a href="manage-超管职责.html">超管职责</a>
</li>
<!-- <li > -->
<li >
<a href="manage-版本升级.html">版本升级</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<h2 class="subject" id="快速部署">快速部署 <a class="hashlink" href="#快速部署">#</a></h2><h2 class="subject" id="配置说明">配置说明 <a class="hashlink" href="#配置说明">#</a></h2>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,176 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 管理学院</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="">
<a href="usage.html">使用手册</a>
</li>
<li class="active">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >管理学院</h1>
<p class="desc ">超级管理员、分组/项目组长的学院。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="manage-介绍.html">介绍</a>
</li>
<!-- <li > -->
<li >
<a href="manage-部署.html">部署</a>
</li>
<!-- <li > -->
<li >
<a href="manage-超管职责.html">超管职责</a>
</li>
<!-- <li > -->
<li >
<a href="manage-版本升级.html">版本升级</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

Binary file not shown.

View File

@ -1,230 +0,0 @@
var EXAMPLE_MAX_HEIGHT = 98,
DEFAULT_SHOW_PARAMS = 5;
$(document).ready(function() {
// 移动端导航
var $openPanel = $('.open-panel');
var $contentLeft = $('.content-left');
var $contentLeftWidth = $contentLeft.width() - 1;
var $ydoc = $('.ydoc');
var $mask = $('.mask');
var $versionSelector = $('.version-selector');
var $versionMask = $('.m-version-mask');
var isPanelHide = true;
var winWidth = $(window).width();
var h2 = $('.content-right').find('h2');
var h3 = $('.content-right').find('h3');
var a = $('.content-left').find('a');
var lis = $contentLeft.find('li');
var titles = [];
var menus = [];
$ydoc.addClass('hidden');
if (isWechat() && $contentLeft[0]) {
$ydoc.addClass('off-webkit-scroll');
}
for (var i = 0; i < a.length; i++) {
menus.push({
name: $(a[i]).attr('href').split('#')[1],
offsetTop: $(a[i]).offset().top - 77,
parent: $(a[i]).parent()
})
}
for (var i = 0; i < h2.length; i++) {
titles.push({
name: h2[i].id,
jq: $(h2[i]),
offsetTop: $(h2[i]).offset().top
})
}
for (var i = 0; i < h3.length; i++) {
titles.push({
name: h3[i].id,
jq: $(h3[i]),
offsetTop: $(h3[i]).offset().top
})
}
titles.sort(sortAsOffset('offsetTop'));
$openPanel.on('click', function() {
if (isPanelHide) { // 点击弹出panel
isPanelHide = false;
$ydoc.addClass('hidden');
$mask.show();
setTimeout(function() {
$mask.addClass('show');
}, 50)
$openPanel.css({
'transform': 'translateX(-' + $contentLeftWidth + 'px)'
})
$contentLeft.css({
'transform': 'translateX(-' + $contentLeftWidth + 'px)'
})
} else { // 点击隐藏panel
isPanelHide = true;
$ydoc.removeClass('hidden');
$mask.removeClass('show');
setTimeout(function() {
$mask.hide();
}, 400)
$openPanel.css({
'transform': 'translateX(0px)'
})
$contentLeft.css({
'transform': 'translateX(0px)'
})
}
var scrollTop = $ydoc.scrollTop();
// 遍历主页面的标题,找到当前窗口顶部的标题
for (var i = 0; i < titles.length; i++) {
if (titles[i].offsetTop > scrollTop) {
// 遍历侧栏,找到对应的标题
for (var j in menus) {
if (menus[j].name == titles[i].name) {
lis.removeClass('active');
menus[j].parent.addClass('active');
$('.docs-sidenav').scrollTop(menus[j].offsetTop);
return;
}
}
return;
}
}
});
$ydoc.removeClass('hidden');
$ydoc.on('scroll', function() {
sessionStorage.setItem('offsetTop', $ydoc.scrollTop());
})
// 待元素获获取offsetTop值之后再设置ydoc的offsetTop
if (sessionStorage.offsetTop) {
$ydoc.scrollTop(sessionStorage.offsetTop);
}
// $openPanel.trigger('click');
$mask.on('click', function() {
if (!isPanelHide) {
$openPanel.click();
}
});
// PC端导航
$('.navbar-toggle').click(function() {
$(this).next(".ydoc-nav").toggle();
});
$('.docs-sidenav li').click(function(e) {
$('.docs-sidenav li').removeClass('active');
$(this).addClass('active');
if (!isPanelHide) {
$openPanel.trigger('click');
}
});
$ydoc.click(function(e) {
if ($(e.target).data('target') !== 'version') {
$versionMask.hide();
}
})
$versionSelector.click(function(e) {
$versionMask.show();
console.log('e');
});
$('.markdown-body pre').map(function(i, item) {
$(item).addClass('ydoc-example').append('<div class="ui-copy js-copy" data-clipboard-action="copy" data-clipboard-target=".js-code-' + i + '" data-copy-number="' + i + '">copy</div><div class="copy-tip copy-tip-' + i + '">已复制</div>');
$(item).children('code').addClass('js-code-'+i);
});
var winHeight = $(window).height() - 44,
sidebar = $('.docs-sidebar');
var docSideNav = $('.docs-sidenav');
if (winWidth > 767) {
docSideNav.width($contentLeftWidth);
}
if (sidebar.height() > winHeight) {
sidebar.css('max-height', winHeight + 'px');
$('.docs-sidenav').css('max-height', winHeight + 'px');
if (winWidth < 768) {
$('.docs-sidenav').css({
'overflow-x': 'hidden'
});
}
var activeMenu,
barScroll = false;
sidebar.on('mouseover', function() {
barScroll = true;
});
sidebar.on('mouseout', function() {
barScroll = false;
});
};
$(window).on('scroll', function(e) {
if ($(this).scrollTop() > ($('.footer').offset().top - $(window).height())) {
winHeight = $(window).height() - $('.footer').outerHeight() - 44;
sidebar.css('max-height', winHeight + 'px');
$('.docs-sidenav').css('max-height', winHeight + 'px');
} else {
winHeight = $(window).height() - 44;
sidebar.css('max-height', winHeight + 'px');
$('.docs-sidenav').css('max-height', winHeight + 'px');
}
if (!barScroll) {
var activeItem = $('.docs-sidebar li.active a');
if (activeItem.length) {
if (!activeMenu || (activeMenu.attr('href') != activeItem.attr('href'))) {
activeMenu = activeItem;
var top = activeMenu.offset().top - sidebar.offset().top;
if (top < 0) {
//sidebar.scrollTop(sidebar.scrollTop() + top);
$('.docs-sidenav').scrollTop($('.docs-sidenav').scrollTop() + top);
} else if (top > winHeight - 88) {
//sidebar.scrollTop(sidebar.scrollTop() + top - winHeight + 44);
$('.docs-sidenav').scrollTop($('.docs-sidenav').scrollTop() + top - winHeight + 88);
}
}
}
}
});
// 退出全屏浏览器窗口大小改变不触发resize
$(window).on('resize', function(e) {
$contentLeftWidth = $contentLeft.width() - 1;
});
function sortAsOffset(propertyName) {
return function(obj1, obj2) {
var val1 = obj1[propertyName];
var val2 = obj2[propertyName];
if (val1 < val2) {
return -1;
} else if (val1 > val2) {
return 1;
} else {
return 0;
}
}
}
function isWechat() {
var ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
return true;
} else {
return false;
}
}
// 代码复制功能
var clipboard = new Clipboard('.js-copy');
clipboard.on('success', function(e) {
var copyNumber = $(e.trigger).attr('data-copy-number');
$('.copy-tip-'+copyNumber).show();
setTimeout(function() {
$('.copy-tip-'+copyNumber).hide();
}, 1000);
e.clearSelection();
});
});

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -1,51 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<font id="ydoc" horiz-adv-x="1024">
<font-face
font-family="ydoc"
units-per-em="1024"
ascent="1024"
descent="0"
/>
<missing-glyph horiz-adv-x="0"/>
<glyph
glyph-name="qunar-bars"
unicode="&#xf020;"
horiz-adv-x="1024" d=" M192,576 L832,576 L832,448 L192,448 M192,320 L832,320 L832,192 L192,192 M192,832 L832,832 L832,704 L192,704" />
<glyph
glyph-name="qunar-loading_error_o"
unicode="&#xf077;"
horiz-adv-x="1024" d=" M824,245 L557,512 L823,778 Q832,788 832,800 Q832,812 822.5,821.5 Q813,831 800,831.5 Q787,832 778,824 L512,557 L246,824 Q237,832 224,831.5 Q211,831 201.5,821.5 Q192,812 192,800 Q192,788 201,778 L467,512 L200,245 Q192,236 192.5,223.5 Q193,211 202.5,201.5 Q212,192 224,192 Q236,192 245,200 L512,467 L779,200 Q788,192 800,192 Q812,192 821.5,201.5 Q831,211 831.5,223.5 Q832,236 824,245" />
<glyph
glyph-name="qunar-loading_done_o"
unicode="&#xf078;"
horiz-adv-x="1024" d=" M887,758 Q877,767 864.5,768 Q852,769 842,760 L416,331 L182,568 Q173,576 160,575.5 Q147,575 137.5,565.5 Q128,556 128,544 Q128,532 137,522 L395,264 Q404,255 416,255 Q428,255 437,264 L888,715 Q896,724 896,736 Q896,748 887,758" />
<glyph
glyph-name="qunar-back_line"
unicode="&#xf07d;"
horiz-adv-x="1024" d=" M335,511 L759,905 Q768,915 768,928 Q768,941 758.5,950.5 Q749,960 736,960 Q723,960 713,951 L265,533 Q256,523 256,510.5 Q256,498 265,488 L713,73 Q723,64 736,64 Q749,64 758.5,73.5 Q768,83 768,96 Q768,109 759,119" />
<glyph
glyph-name="qunar-next_line"
unicode="&#xf07f;"
horiz-adv-x="1024" d=" M689,511 L265,905 Q256,915 256,928 Q256,941 265.5,950.5 Q275,960 288,960 Q301,960 311,951 L759,533 Q768,523 768,510.5 Q768,498 759,488 L311,73 Q301,64 288,64 Q275,64 265.5,73.5 Q256,83 256,96 Q256,109 265,119" />
<glyph
glyph-name="qunar-dot_medium"
unicode="&#xf083;"
horiz-adv-x="1024" d=" M512,704 Q430,702 376,648 Q322,594 320,512 Q322,431 376,376.5 Q430,322 512,320 Q594,322 648,376.5 Q702,431 704,512 Q702,594 648,648 Q594,702 512,704" />
<glyph
glyph-name="mob-fangxingyigouxuan-o"
unicode="&#xf35e;"
horiz-adv-x="1024" d=" M752,896 L272,896 Q211,894 170.5,853.5 Q130,813 128,752 L128,272 Q130,211 170.5,170.5 Q211,130 272,128 L752,128 Q813,130 853.5,170.5 Q894,211 896,272 L896,752 Q894,813 853.5,853.5 Q813,894 752,896 M759,617 L471,329 Q461,320 448,320 Q435,320 425,329 L265,489 Q256,499 256,512 Q256,525 265.5,534.5 Q275,544 288,544 Q301,544 311,535 L448,397 L713,663 Q723,672 736,672 Q749,672 758.5,662.5 Q768,653 768,640 Q768,627 759,617" />
<glyph
glyph-name="mob-fangxingweigouxuan-f"
unicode="&#xf35f;"
horiz-adv-x="1024" d=" M752,896 L272,896 Q211,894 170.5,853.5 Q130,813 128,752 L128,272 Q130,211 170.5,170.5 Q211,130 272,128 L752,128 Q813,130 853.5,170.5 Q894,211 896,272 L896,752 Q894,813 853.5,853.5 Q813,894 752,896 M864,272 Q863,224 831.5,192.5 Q800,161 752,160 L272,160 Q224,161 192.5,192.5 Q161,224 160,272 L160,752 Q161,800 192.5,831.5 Q224,863 272,864 L752,864 Q800,863 831.5,831.5 Q863,800 864,752" />
<glyph
glyph-name="mob-sanjiaoxia-o"
unicode="&#xf3ff;"
horiz-adv-x="1024" d=" M768,640 L512,384 L256,640" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,75 +0,0 @@
;(function()
{
// CommonJS
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
function Brush()
{
function getKeywordsCSS(str)
{
return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
};
function getValuesCSS(str)
{
return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
};
var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' +
'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';
var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+
'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';
this.regexList = [
{ regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
{ regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
{ regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
{ regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors
{ regex: /(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)/g, css: 'value' }, // sizes
{ regex: /!important/g, css: 'color3' }, // !important
{ regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords
{ regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values
{ regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts
];
this.forHtmlScript({
left: /(&lt;|<)\s*style.*?(&gt;|>)/gi,
right: /(&lt;|<)\/\s*style\s*(&gt;|>)/gi
});
};
Brush.prototype = new SyntaxHighlighter.Highlighter();
Brush.aliases = ['css'];
SyntaxHighlighter.brushes.CSS = Brush;
// CommonJS
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();

View File

@ -1,36 +0,0 @@
;(function()
{
// CommonJS
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
function Brush()
{
var keywords = 'break case catch class continue ' +
'default delete do else enum export extends false ' +
'for function if implements import in instanceof ' +
'interface let new null package private protected ' +
'static return super switch ' +
'this throw true try typeof var while with yield';
var r = SyntaxHighlighter.regexLib;
this.regexList = [
{ regex: r.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings
{ regex: r.multiLineSingleQuotedString, css: 'string' }, // single quoted strings
{ regex: r.singleLineCComments, css: 'comments' }, // one line comments
{ regex: r.multiLineCComments, css: 'comments' }, // multiline comments
{ regex: /\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion
{ regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keywords
];
this.forHtmlScript(r.scriptScriptTags);
};
Brush.prototype = new SyntaxHighlighter.Highlighter();
Brush.aliases = ['js', 'jscript', 'javascript', 'json'];
SyntaxHighlighter.brushes.JScript = Brush;
// CommonJS
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();

View File

@ -1,94 +0,0 @@
/**
* SyntaxHighlighter
* http://alexgorbatchev.com/SyntaxHighlighter
*
* SyntaxHighlighter is donationware. If you are using it, please donate.
* http://alexgorbatchev.com/SyntaxHighlighter/donate.html
*
* @version
* 3.0.83 (July 02 2010)
*
* @copyright
* Copyright (C) 2004-2010 Alex Gorbatchev.
*
* @license
* Dual licensed under the MIT and GPL licenses.
*/
;(function()
{
// CommonJS
typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
function Brush()
{
function getKeywordsCSS(str)
{
return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
};
function getValuesCSS(str)
{
return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
};
var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' +
'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';
var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero digits disc dotted double '+
'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';
var statements = '!important !default';
var preprocessor = '@import @extend @debug @warn @if @for @while @mixin @include';
var r = SyntaxHighlighter.regexLib;
this.regexList = [
{ regex: r.multiLineCComments, css: 'comments' }, // multiline comments
{ regex: r.singleLineCComments, css: 'comments' }, // singleline comments
{ regex: r.doubleQuotedString, css: 'string' }, // double quoted strings
{ regex: r.singleQuotedString, css: 'string' }, // single quoted strings
{ regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors
{ regex: /\b(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)\b/g, css: 'value' }, // sizes
{ regex: /\$\w+/g, css: 'variable' }, // variables
{ regex: new RegExp(this.getKeywords(statements), 'g'), css: 'color3' }, // statements
{ regex: new RegExp(this.getKeywords(preprocessor), 'g'), css: 'preprocessor' }, // preprocessor
{ regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords
{ regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values
{ regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts
];
};
Brush.prototype = new SyntaxHighlighter.Highlighter();
Brush.aliases = ['sass', 'scss'];
SyntaxHighlighter.brushes.Sass = Brush;
// CommonJS
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();

File diff suppressed because one or more lines are too long

View File

@ -1,235 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>YApi : ./server/controllers/base.js</title>
<link type="text/css" rel="stylesheet" href="../../../source/code.css"/>
<script type="text/javascript" src="../../../source/shCore.js"></script>
<script type="text/javascript" src="../../../source/shBrush-js.js"></script>
<style>
.syntaxhighlighter .number1 .spaces,.syntaxhighlighter .toolbar{ display: none;}
.syntaxhighlighter table td.gutter .line.highlight { background-color: #6ce26c !important; color: white; }
</style>
</head>
<body>
<div class="ydoc">
<div class="ydoc-banner-bg">
<div class="ydoc-banner" id="content" tabindex="-1">
<div class="ydoc-banner-area">
<h1>YApi : ./server/controllers/base.js</h1>
<p>源代码</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content">
<div class="static-code-content" role="main">
<pre class="brush: js;">
const yapi = require('../yapi.js');
const projectModel = require('../models/project.js');
const userModel = require('../models/user.js');
const interfaceModel = require('../models/interface.js');
const groupModel = require('../models/group.js');
const _ = require('underscore');
const jwt = require('jsonwebtoken');
class baseController {
constructor(ctx) {
this.ctx = ctx;
//网站上线后role对象key是不能修改的value可以修改
this.roles = {
admin: 'Admin',
member: '网站会员'
};
}
async init(ctx) {
this.$user = null;
let ignoreRouter = [
'/api/user/login_by_token',
'/api/user/login',
'/api/user/reg',
'/api/user/status',
'/api/user/logout'
];
if (ignoreRouter.indexOf(ctx.path) > -1) {
this.$auth = true;
} else {
await this.checkLogin(ctx);
}
}
getUid() {
return parseInt(this.$uid, 10);
}
async checkLogin(ctx) {
let token = ctx.cookies.get('_yapi_token');
let uid = ctx.cookies.get('_yapi_uid');
try {
if (!token || !uid) return false;
let userInst = yapi.getInst(userModel); //创建user实体
let result = await userInst.findById(uid);
let decoded = jwt.verify(token, result.passsalt);
if (decoded.uid == uid) {
this.$uid = uid;
this.$auth = true;
this.$user = result;
return true;
}
return false;
} catch (e) {
return false;
}
}
/**
*
* @param {*} ctx
*/
async getLoginStatus(ctx) {
if (await this.checkLogin(ctx) === true) {
let result = yapi.commons.fieldSelect(this.$user, ['_id', 'username', 'email', 'up_time', 'add_time', 'role', 'type']);
result.server_ip = yapi.WEBCONFIG.server_ip;
return ctx.body = yapi.commons.resReturn(result);
}
return ctx.body = yapi.commons.resReturn(null, 40011, '请登录...');
}
getRole() {
return this.$user.role;
}
getUsername() {
return this.$user.username;
}
async getProjectRole(id, type) {
let result = {};
try {
if (this.getRole() === 'admin') {
return 'admin';
}
if (type === 'interface') {
let interfaceInst = yapi.getInst(interfaceModel);
let interfaceData = await interfaceInst.get(id)
result.interfaceData = interfaceData;
if (interfaceData.uid === this.getUid()) {
return 'owner';
}
type = 'project';
id = interfaceData.project_id;
}
if (type === 'project') {
let projectInst = yapi.getInst(projectModel);
let projectData = await projectInst.get(id);
if (projectData.uid === this.getUid()) {
return 'owner';
}
let memberData = _.find(projectData.members, (m) => {
if (m.uid === this.getUid()) {
return true;
}
})
if (memberData && memberData.role) {
if (memberData.role === 'owner') {
return 'owner';
} else {
return 'dev';
}
}
type = 'group';
id = projectData.group_id
}
if (type === 'group') {
let groupInst = yapi.getInst(groupModel);
let groupData = await groupInst.get(id);
let groupMemberData = _.find(groupData.members, (m) => {
if (m.uid === this.getUid()) {
return true;
}
})
if (groupMemberData && groupMemberData.role) {
if (groupMemberData.role === 'owner') {
return 'owner';
} else {
return 'dev'
}
}
}
return 'member';
}
catch (e) {
yapi.commons.log(e.message, 'error')
return false;
}
}
/**
*
* @param {*} id type对应的id
* @param {*} type enum[interface, project, group]
* @param {*} action enum[ danger , edit ] danger只有owner或管理员才能操作,edit只要是dev或以上就能执行
*/
async checkAuth(id, type, action) {
let role = await this.getProjectRole(id, type);
if (action === 'danger') {
if (role === 'admin' || role === 'owner') {
return true;
}
} else if (action === 'edit') {
if (role === 'admin' || role === 'owner' || role === 'dev') {
return true;
}
}
return false;
}
}
module.exports = baseController;
</pre>
</div>
</div>
</div>
</div>
<!-- <div class="docs-header" id="content" tabindex="-1">
<div class="container">
<h1>YApi : ./server/controllers/base.js</h1>
<p>源代码</p>
</div>
</div> -->
<footer class="docs-footer" role="contentinfo">
<div class="container">
<p></p>
</div>
</footer>
</div>
<script type="text/javascript">
SyntaxHighlighter.all();
function getTop(node){
return node.offsetTop + (node.offsetParent ? getTop(node.offsetParent) : 0);
}
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
try {
var lineNum = (parseInt(location.hash.replace(/#/g, '')) - 1) || 0,
node = document.querySelectorAll('div.line')[lineNum];
document.body.scrollTop = getTop(node);
node.className += ' highlight';
} catch(e) {}
}, 500);
}, false);
</script>
</body>
</html>

View File

@ -1,194 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>YApi : ./server/controllers/follow.js</title>
<link type="text/css" rel="stylesheet" href="../../../source/code.css"/>
<script type="text/javascript" src="../../../source/shCore.js"></script>
<script type="text/javascript" src="../../../source/shBrush-js.js"></script>
<style>
.syntaxhighlighter .number1 .spaces,.syntaxhighlighter .toolbar{ display: none;}
.syntaxhighlighter table td.gutter .line.highlight { background-color: #6ce26c !important; color: white; }
</style>
</head>
<body>
<div class="ydoc">
<div class="ydoc-banner-bg">
<div class="ydoc-banner" id="content" tabindex="-1">
<div class="ydoc-banner-area">
<h1>YApi : ./server/controllers/follow.js</h1>
<p>源代码</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content">
<div class="static-code-content" role="main">
<pre class="brush: js;">
const yapi = require('../yapi.js');
const baseController = require('./base.js');
const followModel = require('../models/follow');
const projectModel = require('../models/project');
class followController extends baseController {
constructor(ctx) {
super(ctx);
this.Model = yapi.getInst(followModel);
this.projectModel = yapi.getInst(projectModel);
}
/**
* 获取关注项目列表
* @interface /follow/list
* @method GET
* @category follow
* @foldnumber 10
* @param {Number} [page] 分页页码
* @param {Number} [limit] 分页大小
* @returns {Object}
* @example /follow/list
*/
async list(ctx) {
let uid = this.getUid(),
page = ctx.request.query.page || 1,
limit = ctx.request.query.limit || 10;
if (!uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '用户id不能为空');
}
try {
let result = await this.Model.list(uid);
ctx.body = yapi.commons.resReturn({
list: result
});
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
/**
* 取消关注
* @interface /follow/del
* @method POST
* @category follow
* @foldnumber 10
* @param {Number} projectid
* @returns {Object}
* @example /follow/del
*/
async del(ctx) {
let params = ctx.request.body, uid = this.getUid();
if(!params.projectid){
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
let checkRepeat = await this.Model.checkProjectRepeat(uid,params.projectid);
if (checkRepeat == 0) {
return ctx.body = yapi.commons.resReturn(null, 401, '项目未关注');
}
try {
let result = await this.Model.del(params.projectid, this.getUid());
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 添加关注
* @interface /follow/add
* @method GET
* @category follow
* @foldnumber 10
* @param {Number} projectid 项目id
* @param {String} projectname 项目名
* @param {String} icon 项目icon
* @returns {Object}
* @example /follow/add
*/
async add(ctx) {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
projectid: 'number'
});
let uid = this.getUid();
if (!params.projectid) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
let checkRepeat = await this.Model.checkProjectRepeat(uid,params.projectid);
if (checkRepeat) {
return ctx.body = yapi.commons.resReturn(null, 401, '项目已关注');
}
try {
let project = await this.projectModel.get(params.projectid);
let data = {
uid: uid,
projectid: params.projectid,
projectname: project.name,
icon: project.icon,
color: project.color
};
let result = await this.Model.save(data);
result = yapi.commons.fieldSelect(result, ['_id', 'uid', 'projectid', 'projectname', 'icon', 'color']);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
}
module.exports = followController;
</pre>
</div>
</div>
</div>
</div>
<!-- <div class="docs-header" id="content" tabindex="-1">
<div class="container">
<h1>YApi : ./server/controllers/follow.js</h1>
<p>源代码</p>
</div>
</div> -->
<footer class="docs-footer" role="contentinfo">
<div class="container">
<p></p>
</div>
</footer>
</div>
<script type="text/javascript">
SyntaxHighlighter.all();
function getTop(node){
return node.offsetTop + (node.offsetParent ? getTop(node.offsetParent) : 0);
}
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
try {
var lineNum = (parseInt(location.hash.replace(/#/g, '')) - 1) || 0,
node = document.querySelectorAll('div.line')[lineNum];
document.body.scrollTop = getTop(node);
node.className += ' highlight';
} catch(e) {}
}, 500);
}, false);
</script>
</body>
</html>

View File

@ -1,438 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>YApi : ./server/controllers/group.js</title>
<link type="text/css" rel="stylesheet" href="../../../source/code.css"/>
<script type="text/javascript" src="../../../source/shCore.js"></script>
<script type="text/javascript" src="../../../source/shBrush-js.js"></script>
<style>
.syntaxhighlighter .number1 .spaces,.syntaxhighlighter .toolbar{ display: none;}
.syntaxhighlighter table td.gutter .line.highlight { background-color: #6ce26c !important; color: white; }
</style>
</head>
<body>
<div class="ydoc">
<div class="ydoc-banner-bg">
<div class="ydoc-banner" id="content" tabindex="-1">
<div class="ydoc-banner-area">
<h1>YApi : ./server/controllers/group.js</h1>
<p>源代码</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content">
<div class="static-code-content" role="main">
<pre class="brush: js;">
const groupModel = require('../models/group.js');
const yapi = require('../yapi.js');
const baseController = require('./base.js');
const projectModel = require('../models/project.js');
const userModel = require('../models/user.js');
const interfaceModel = require('../models/interface.js');
const interfaceColModel = require('../models/interfaceCol.js');
const interfaceCaseModel = require('../models/interfaceCase.js');
class groupController extends baseController {
constructor(ctx) {
super(ctx);
}
/**
* 添加项目分组
* @interface /group/get
* @method GET
* @category group
* @foldnumber 10
* @param {String} id 项目分组ID
* @returns {Object}
* @example
*/
async get(ctx) {
try {
let params = ctx.request.query;
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组id不能为空');
}
let groupInst = yapi.getInst(groupModel);
let result = await groupInst.getGroupById(params.id);
result = result.toObject();
result.role = await this.getProjectRole(params.id, 'group');
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 400, e.message)
}
}
/**
* 添加项目分组
* @interface /group/add
* @method POST
* @category group
* @foldnumber 10
* @param {String} group_name 项目分组名称,不能为空
* @param {String} [group_desc] 项目分组描述
* @param {String} owner_uid 组长uid
* @returns {Object}
* @example ./api/group/add.json
*/
async add(ctx) {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
group_name: 'string',
group_desc: 'string',
owner_uid: 'number'
});
if (this.getRole() !== 'admin') {
return ctx.body = yapi.commons.resReturn(null, 401, '没有权限');
}
if (!params.group_name) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组名不能为空');
}
if (!params.owner_uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组必须添加一个组长');
}
let groupUserdata = await this.getUserdata(params.owner_uid, 'owner');
if (groupUserdata === null) {
return ctx.body = yapi.commons.resReturn(null, 400, '组长uid不存在')
}
let groupInst = yapi.getInst(groupModel);
let checkRepeat = await groupInst.checkRepeat(params.group_name);
if (checkRepeat > 0) {
return ctx.body = yapi.commons.resReturn(null, 401, '项目分组名已存在');
}
let data = {
group_name: params.group_name,
group_desc: params.group_desc,
uid: this.getUid(),
add_time: yapi.commons.time(),
up_time: yapi.commons.time(),
members: [groupUserdata]
};
try {
let result = await groupInst.save(data);
result = yapi.commons.fieldSelect(result, ['_id', 'group_name', 'group_desc', 'uid', 'members']);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
async getUserdata(uid, role) {
role = role || 'dev';
let userInst = yapi.getInst(userModel);
let userData = await userInst.findById(uid);
if (!userData) {
return null;
}
return {
_role: userData.role,
role: role,
uid: userData._id,
username: userData.username,
email: userData.email
}
}
/**
* 添加项目分组成员
* @interface /group/add_member
* @method POST
* @category group
* @foldnumber 10
* @param {String} id 项目分组id
* @param {String} member_uid 项目分组成员uid
* @param {String} role 成员角色owner or dev
* @returns {Object}
* @example
*/
async addMember(ctx) {
let params = ctx.request.body;
let groupInst = yapi.getInst(groupModel);
if (!params.member_uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组成员uid不能为空');
}
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组id不能为空');
}
params.role = params.role === 'owner' ? 'owner' : 'dev';
var check = await groupInst.checkMemberRepeat(params.id, params.member_uid);
if (check > 0) {
return ctx.body = yapi.commons.resReturn(null, 400, '成员已存在');
}
let groupUserdata = await this.getUserdata(params.member_uid, params.role);
if (groupUserdata === null) {
return ctx.body = yapi.commons.resReturn(null, 400, '组长uid不存在')
}
if (groupUserdata._role === 'admin') {
return ctx.body = yapi.commons.resReturn(null, 400, '不能邀请管理员')
}
delete groupUserdata._role;
try {
let result = await groupInst.addMember(params.id, groupUserdata);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 修改项目分组成员角色
* @interface /group/change_member_role
* @method POST
* @category group
* @foldnumber 10
* @param {String} id 项目分组id
* @param {String} member_uid 项目分组成员uid
* @param {String} role 权限 ['owner'|'dev']
* @returns {Object}
* @example
*/
async changeMemberRole(ctx) {
let params = ctx.request.body;
let groupInst = yapi.getInst(groupModel);
if (!params.member_uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组成员uid不能为空');
}
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组id不能为空');
}
var check = await groupInst.checkMemberRepeat(params.id, params.member_uid);
if (check === 0) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组成员不存在');
}
if (await this.checkAuth(params.id, 'group', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
params.role = params.role === 'owner' ? 'owner' : 'dev';
try {
let result = await groupInst.changeMemberRole(params.id, params.member_uid, params.role);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 获取所有项目成员
* @interface /group/get_member_list
* @method GET
* @category group
* @foldnumber 10
* @param {String} id 项目分组id
* @returns {Object}
* @example
*/
async getMemberList(ctx) {
let params = ctx.request.query;
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
try {
let groupInst = yapi.getInst(groupModel);
let group = await groupInst.get(params.id);
ctx.body = yapi.commons.resReturn(group.members);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 删除项目成员
* @interface /group/del_member
* @method POST
* @category group
* @foldnumber 10
* @param {String} id 项目分组id
* @param {String} member_uid 项目分组成员uid
* @returns {Object}
* @example
*/
async delMember(ctx) {
let params = ctx.request.body;
let groupInst = yapi.getInst(groupModel);
if (!params.member_uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组成员uid不能为空');
}
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组id不能为空');
}
var check = await groupInst.checkMemberRepeat(params.id, params.member_uid);
if (check === 0) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组成员不存在');
}
if (await this.checkAuth(params.id, 'group', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
try {
let result = await groupInst.delMember(params.id, params.member_uid);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 获取项目分组列表
* @interface /group/list
* @method get
* @category group
* @foldnumber 10
* @returns {Object}
* @example ./api/group/list.json
*/
async list(ctx) {
try {
var groupInst = yapi.getInst(groupModel);
let result = await groupInst.list();
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 删除项目分组
* @interface /group/del
* @method post
* @param {String} id 项目分组id
* @category group
* @foldnumber 10
* @returns {Object}
* @example ./api/group/del.json
*/
async del(ctx) {
if (this.getRole() !== 'admin') {
return ctx.body = yapi.commons.resReturn(null, 401, '没有权限');
}
try {
let groupInst = yapi.getInst(groupModel);
let projectInst = yapi.getInst(projectModel);
let interfaceInst = yapi.getInst(interfaceModel);
let interfaceColInst = yapi.getInst(interfaceColModel);
let interfaceCaseInst = yapi.getInst(interfaceCaseModel);
let id = ctx.request.body.id;
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 402, 'id不能为空');
}
let projectList = await projectInst.list(id, true);
projectList.forEach(async (p) => {
await interfaceInst.delByProjectId(p._id)
await interfaceCaseInst.delByProjectId(p._id)
await interfaceColInst.delByProjectId(p._id)
})
await projectInst.delByGroupid(id);
let result = await groupInst.del(id);
ctx.body = yapi.commons.resReturn(result);
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
/**
* 更新项目分组
* @interface /group/up
* @method post
* @param {String} id 项目分组id
* @param {String} group_name 项目分组名称
* @param {String} group_desc 项目分组描述
* @category group
* @foldnumber 10
* @returns {Object}
* @example ./api/group/up.json
*/
async up(ctx) {
let groupInst = yapi.getInst(groupModel);
let id = ctx.request.body.id;
let data = {};
if (await this.checkAuth(id, 'group', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
try {
ctx.request.body = yapi.commons.handleParams(ctx.request.body, {
id: 'number',
group_name: 'string',
group_desc: 'string'
});
ctx.request.body.group_name && (data.group_name = ctx.request.body.group_name);
ctx.request.body.group_desc && (data.group_desc = ctx.request.body.group_desc);
if (Object.keys(data).length === 0) {
ctx.body = yapi.commons.resReturn(null, 404, '分组名和分组描述不能为空');
}
let result = await groupInst.up(id, data);
ctx.body = yapi.commons.resReturn(result);
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
}
module.exports = groupController;
</pre>
</div>
</div>
</div>
</div>
<!-- <div class="docs-header" id="content" tabindex="-1">
<div class="container">
<h1>YApi : ./server/controllers/group.js</h1>
<p>源代码</p>
</div>
</div> -->
<footer class="docs-footer" role="contentinfo">
<div class="container">
<p></p>
</div>
</footer>
</div>
<script type="text/javascript">
SyntaxHighlighter.all();
function getTop(node){
return node.offsetTop + (node.offsetParent ? getTop(node.offsetParent) : 0);
}
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
try {
var lineNum = (parseInt(location.hash.replace(/#/g, '')) - 1) || 0,
node = document.querySelectorAll('div.line')[lineNum];
document.body.scrollTop = getTop(node);
node.className += ' highlight';
} catch(e) {}
}, 500);
}, false);
</script>
</body>
</html>

View File

@ -1,727 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>YApi : ./server/controllers/interface.js</title>
<link type="text/css" rel="stylesheet" href="../../../source/code.css"/>
<script type="text/javascript" src="../../../source/shCore.js"></script>
<script type="text/javascript" src="../../../source/shBrush-js.js"></script>
<style>
.syntaxhighlighter .number1 .spaces,.syntaxhighlighter .toolbar{ display: none;}
.syntaxhighlighter table td.gutter .line.highlight { background-color: #6ce26c !important; color: white; }
</style>
</head>
<body>
<div class="ydoc">
<div class="ydoc-banner-bg">
<div class="ydoc-banner" id="content" tabindex="-1">
<div class="ydoc-banner-area">
<h1>YApi : ./server/controllers/interface.js</h1>
<p>源代码</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content">
<div class="static-code-content" role="main">
<pre class="brush: js;">
const interfaceModel = require('../models/interface.js');
const interfaceCatModel = require('../models/interfaceCat.js');
const interfaceCaseModel = require('../models/interfaceCase.js');
const followModel = require('../models/follow.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');
class interfaceController extends baseController {
constructor(ctx) {
super(ctx);
this.Model = yapi.getInst(interfaceModel);
this.catModel = yapi.getInst(interfaceCatModel);
this.projectModel = yapi.getInst(projectModel);
this.caseModel = yapi.getInst(interfaceCaseModel);
this.followModel = yapi.getInst(followModel);
this.userModel = yapi.getInst(userModel);
}
/**
* 添加项目分组
* @interface /interface/add
* @method POST
* @category interface
* @foldnumber 10
* @param {Number} project_id 项目id不能为空
* @param {String} title 接口标题,不能为空
* @param {String} path 接口请求路径,不能为空
* @param {String} method 请求方式
* @param {Array} [req_headers] 请求的header信息
* @param {String} [req_headers[].name] 请求的header信息名
* @param {String} [req_headers[].value] 请求的header信息值
* @param {Boolean} [req_headers[].required] 是否是必须,默认为否
* @param {String} [req_headers[].desc] header描述
* @param {String} [req_body_type] 请求参数方式,有["form", "json", "text", "xml"]四种
* @param {Array} [req_params] name, desc两个参数
* @param {Mixed} [req_body_form] 请求参数,如果请求方式是form参数是Array数组其他格式请求参数是字符串
* @param {String} [req_body_form[].name] 请求参数名
* @param {String} [req_body_form[].value] 请求参数值可填写生成规则mock。如@email随机生成一条email
* @param {String} [req_body_form[].type] 请求参数类型,有["text", "file"]两种
* @param {String} [req_body_other] 非form类型的请求参数可保存到此字段
* @param {String} [res_body_type] 相应信息的数据格式,有["json", "text", "xml"]三种
* @param {String} [res_body] 响应信息可填写任意字符串如果res_body_type是json,则会调用mock功能
* @param {String} [desc] 接口描述
* @returns {Object}
* @example ./api/interface/add.json
*/
async add(ctx) {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
project_id: 'number',
title: 'string',
path: 'string',
method: 'string',
desc: 'string',
catid: 'number'
});
let auth = await this.checkAuth(params.project_id, 'project', 'edit')
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
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) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
if (!params.path) {
return ctx.body = yapi.commons.resReturn(null, 400, '接口请求路径不能为空');
}
if (!yapi.commons.verifyPath(params.path)) {
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/');
}
let checkRepeat = await this.Model.checkRepeat(params.project_id, params.path, params.method);
if (checkRepeat > 0) {
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']');
}
try {
let data = {
project_id: params.project_id,
catid: params.catid,
title: params.title,
path: params.path,
desc: params.desc,
method: params.method,
req_headers: params.req_headers,
req_body_type: params.req_body_type,
res_body: params.res_body,
res_body_type: params.res_body_type,
uid: this.getUid(),
add_time: yapi.commons.time(),
up_time: yapi.commons.time()
};
if (params.req_query) {
data.req_query = params.req_query;
}
if (params.req_body_form) {
data.req_body_form = params.req_body_form;
}
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 {
data.type = 'static'
}
if (params.req_body_other) {
data.req_body_other = params.req_body_other;
}
let result = await this.Model.save(data);
this.catModel.get(params.catid).then((cate) => {
let username = this.getUsername();
let title = `用户 "${username}" 为分类 "${cate.name}" 添加了接口 "${data.title}"`
yapi.commons.saveLog({
content: title,
type: 'project',
uid: this.getUid(),
username: username,
typeid: params.project_id
});
//let project = await this.projectModel.getBaseInfo(params.project_id);
// let interfaceUrl = `http://${ctx.request.host}/project/${params.project_id}/interface/api/${result._id}`
// this.sendNotice(params.project_id, {
// title: `${username} 新增了接口 ${data.title}`,
// 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></div>`
// })
});
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 添加项目分组
* @interface /interface/get
* @method GET
* @category interface
* @foldnumber 10
* @param {Number} id 接口id不能为空
* @returns {Object}
* @example ./api/interface/get.json
*/
async get(ctx) {
let params = ctx.request.query;
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
}
try {
let result = await this.Model.get(params.id);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 接口列表
* @interface /interface/list
* @method GET
* @category interface
* @foldnumber 10
* @param {Number} project_id 项目id不能为空
* @returns {Object}
* @example ./api/interface/list.json
*/
async list(ctx) {
let project_id = ctx.request.query.project_id;
if (!project_id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
try {
let result = await this.Model.list(project_id);
ctx.body = yapi.commons.resReturn(result);
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
async listByCat(ctx) {
let catid = ctx.request.query.catid;
if (!catid) {
return ctx.body = yapi.commons.resReturn(null, 400, 'catid不能为空');
}
try {
let result = await this.Model.listByCatid(catid)
ctx.body = yapi.commons.resReturn(result);
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
async listByMenu(ctx) {
let project_id = ctx.request.query.project_id;
if (!project_id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
try {
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')
for (let j = 0; j < list.length; j++) {
list[j] = list[j].toObject()
}
item.list = list;
newResult[i] = item
}
ctx.body = yapi.commons.resReturn(newResult);
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
/**
* 编辑接口
* @interface /interface/up
* @method POST
* @category interface
* @foldnumber 10
* @param {Number} id 接口id不能为空
* @param {String} [path] 接口请求路径
* @param {String} [method] 请求方式
* @param {Array} [req_headers] 请求的header信息
* @param {String} [req_headers[].name] 请求的header信息名
* @param {String} [req_headers[].value] 请求的header信息值
* @param {Boolean} [req_headers[].required] 是否是必须,默认为否
* @param {String} [req_headers[].desc] header描述
* @param {String} [req_body_type] 请求参数方式,有["form", "json", "text", "xml"]四种
* @param {Mixed} [req_body_form] 请求参数,如果请求方式是form参数是Array数组其他格式请求参数是字符串
* @param {String} [req_body_form[].name] 请求参数名
* @param {String} [req_body_form[].value] 请求参数值可填写生成规则mock。如@email随机生成一条email
* @param {String} [req_body_form[].type] 请求参数类型,有["text", "file"]两种
* @param {String} [req_body_other] 非form类型的请求参数可保存到此字段
* @param {String} [res_body_type] 相应信息的数据格式,有["json", "text", "xml"]三种
* @param {String} [res_body] 响应信息可填写任意字符串如果res_body_type是json,则会调用mock功能
* @param {String} [desc] 接口描述
* @returns {Object}
* @example ./api/interface/up.json
*/
async up(ctx) {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
title: 'string',
path: 'string',
method: 'string',
desc: 'string',
catid: 'number'
});
params.method = params.method || 'GET';
params.method = params.method.toUpperCase();
let id = ctx.request.body.id;
params.message = params.message || '';
params.message = params.message.replace(/\n/g, "<br>")
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
}
let interfaceData = await this.Model.get(id);
let auth = await this.checkAuth(interfaceData.project_id, 'project', 'edit')
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
if (params.path && !yapi.commons.verifyPath(params.path)) {
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/');
}
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 + ']');
}
}
let data = {
up_time: yapi.commons.time()
};
if (!_.isUndefined(params.path)) {
data.path = params.path;
}
if (!_.isUndefined(params.title)) {
data.title = params.title;
}
if (!_.isUndefined(params.desc)) {
data.desc = params.desc;
}
if (!_.isUndefined(params.method)) {
data.method = params.method;
}
if (!_.isUndefined(params.catid)) {
data.catid = params.catid;
}
if (!_.isUndefined(params.req_headers)) {
data.req_headers = params.req_headers;
}
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) {
data.type = 'var'
data.req_params = params.req_params;
} else {
data.type = 'static'
data.req_params = [];
}
if (!_.isUndefined(params.req_query)) {
data.req_query = params.req_query;
}
if (!_.isUndefined(params.req_body_other)) {
data.req_body_other = params.req_body_other;
}
if (!_.isUndefined(params.req_body_type)) {
data.req_body_type = params.req_body_type;
}
if (!_.isUndefined(params.res_body_type)) {
data.res_body_type = params.res_body_type;
}
if (!_.isUndefined(params.res_body)) {
data.res_body = params.res_body;
}
if (!_.isUndefined(params.status)) {
data.status = params.status;
}
try {
let result = await this.Model.up(id, data);
let username = this.getUsername();
if (params.catid) {
this.catModel.get(+params.catid).then((cate) => {
yapi.commons.saveLog({
content: `用户 "${username}" 更新了分类 "${cate.name}" 下的接口 "${data.title}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: cate.project_id
});
});
} else {
let cateid = interfaceData.catid;
this.catModel.get(cateid).then((cate) => {
yapi.commons.saveLog({
content: `用户 "${username}" 更新了分类 "${cate.name}" 下的接口 "${data.title}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: cate.project_id
});
});
}
if (params.switch_notice === true) {
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>`
})
}
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 删除接口
* @interface /interface/del
* @method GET
* @category interface
* @foldnumber 10
* @param {Number} id 接口id不能为空
* @returns {Object}
* @example ./api/interface/del.json
*/
async del(ctx) {
try {
let id = ctx.request.body.id;
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
}
let data = await this.Model.get(ctx.request.body.id);
if (data.uid != this.getUid()) {
let auth = await this.checkAuth(data.project_id, 'project', 'danger')
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
}
let inter = await this.Model.get(id);
let result = await this.Model.del(id);
await this.caseModel.delByInterfaceId(id);
let username = this.getUsername();
this.catModel.get(inter.catid).then((cate) => {
yapi.commons.saveLog({
content: `用户 "${username}" 删除了分类 "${cate.name}" 下的接口 "${inter.title}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: cate.project_id
});
})
ctx.body = yapi.commons.resReturn(result);
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
async solveConflict(ctx) {
try {
let id = parseInt(ctx.query.id, 10), result, userInst, userinfo, data;
if (!id) return ctx.websocket.send("id 参数有误");
result = await this.Model.get(id), userinfo;
if (result.edit_uid !== 0 && result.edit_uid !== this.getUid()) {
userInst = yapi.getInst(userModel);
userinfo = await userInst.findById(result.edit_uid);
data = {
errno: result.edit_uid,
data: { uid: result.edit_uid, username: userinfo.username }
}
} else {
this.Model.upEditUid(id, this.getUid()).then()
data = {
errno: 0,
data: result
}
}
ctx.websocket.send(JSON.stringify(data));
ctx.websocket.on('close', () => {
this.Model.upEditUid(id, 0).then()
})
} catch (err) {
yapi.commons.log(err, 'error')
}
}
async addCat(ctx) {
try {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
name: 'string',
project_id: 'number',
desc: 'string'
});
if (!params.project_id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
let auth = await this.checkAuth(params.project_id, 'project', 'edit')
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
if (!params.name) {
return ctx.body = yapi.commons.resReturn(null, 400, '名称不能为空');
}
let result = await this.catModel.save({
name: params.name,
project_id: params.project_id,
desc: params.desc,
uid: this.getUid(),
add_time: yapi.commons.time(),
up_time: yapi.commons.time()
})
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 添加了分类 "${params.name}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: params.project_id
});
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
async upCat(ctx) {
try {
let params = ctx.request.body;
let result = await this.catModel.up(params.catid, {
name: params.name,
desc: params.desc,
up_time: yapi.commons.time()
});
let username = this.getUsername();
let cate = await this.catModel.get(params.catid);
let auth = await this.checkAuth(cate.project_id, 'project', 'edit')
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
yapi.commons.saveLog({
content: `用户 "${username}" 更新了分类 "${cate.name}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: cate.project_id
});
ctx.body = yapi.commons.resReturn(result)
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 400, e.message)
}
}
async delCat(ctx) {
try {
let id = ctx.request.body.catid;
let catData = await this.catModel.get(id);
if (!catData) {
ctx.body = yapi.commons.resReturn(null, 400, "不存在的分类")
}
if (catData.uid !== this.getUid()) {
let auth = await this.checkAuth(catData.project_id, 'project', 'danger')
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
}
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 删除了分类 "${catData.name}" 及该分类下的接口`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: catData.project_id
});
let result = await this.catModel.del(id);
let r = await this.Model.delByCatid(id);
return ctx.body = yapi.commons.resReturn(r);
} catch (e) {
yapi.commons.resReturn(null, 400, e.message)
}
}
/**
* 获取分类列表
* @interface /interface/getCatMenu
* @method GET
* @category interface
* @foldnumber 10
* @param {Number} project_id 项目id不能为空
* @returns {Object}
* @example ./api/interface/getCatMenu
*/
async getCatMenu(ctx) {
let project_id = ctx.request.query.project_id;
if(!project_id){
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
try{
let res = await this.catModel.list(project_id);
return ctx.body = yapi.commons.resReturn(res);
}catch(e){
yapi.commons.resReturn(null, 400, e.message);
}
}
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
});
})
})
});
}
}
module.exports = interfaceController;
</pre>
</div>
</div>
</div>
</div>
<!-- <div class="docs-header" id="content" tabindex="-1">
<div class="container">
<h1>YApi : ./server/controllers/interface.js</h1>
<p>源代码</p>
</div>
</div> -->
<footer class="docs-footer" role="contentinfo">
<div class="container">
<p></p>
</div>
</footer>
</div>
<script type="text/javascript">
SyntaxHighlighter.all();
function getTop(node){
return node.offsetTop + (node.offsetParent ? getTop(node.offsetParent) : 0);
}
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
try {
var lineNum = (parseInt(location.hash.replace(/#/g, '')) - 1) || 0,
node = document.querySelectorAll('div.line')[lineNum];
document.body.scrollTop = getTop(node);
node.className += ' highlight';
} catch(e) {}
}, 500);
}, false);
</script>
</body>
</html>

View File

@ -1,566 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>YApi : ./server/controllers/interfaceCol.js</title>
<link type="text/css" rel="stylesheet" href="../../../source/code.css"/>
<script type="text/javascript" src="../../../source/shCore.js"></script>
<script type="text/javascript" src="../../../source/shBrush-js.js"></script>
<style>
.syntaxhighlighter .number1 .spaces,.syntaxhighlighter .toolbar{ display: none;}
.syntaxhighlighter table td.gutter .line.highlight { background-color: #6ce26c !important; color: white; }
</style>
</head>
<body>
<div class="ydoc">
<div class="ydoc-banner-bg">
<div class="ydoc-banner" id="content" tabindex="-1">
<div class="ydoc-banner-area">
<h1>YApi : ./server/controllers/interfaceCol.js</h1>
<p>源代码</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content">
<div class="static-code-content" role="main">
<pre class="brush: js;">
const interfaceColModel = require('../models/interfaceCol.js');
const interfaceCaseModel = require('../models/interfaceCase.js');
const interfaceModel = require('../models/interface.js');
const projectModel = require('../models/project.js');
const baseController = require('./base.js');
const yapi = require('../yapi.js');
class interfaceColController extends baseController{
constructor(ctx) {
super(ctx);
this.colModel = yapi.getInst(interfaceColModel);
this.caseModel = yapi.getInst(interfaceCaseModel);
this.interfaceModel = yapi.getInst(interfaceModel);
this.projectModel = yapi.getInst(projectModel);
}
/**
* 获取所有接口集
* @interface /col/list
* @method GET
* @category col
* @foldnumber 10
* @param {String} project_id email名称不能为空
* @returns {Object}
* @example
*/
async list(ctx){
try {
let id = ctx.query.project_id;
let result = await this.colModel.list(id);
for(let i=0; i< result.length;i++){
result[i] = result[i].toObject();
result[i].caseList = await this.caseModel.list(result[i]._id)
}
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 增加接口集
* @interface /col/add_col
* @method POST
* @category col
* @foldnumber 10
* @param {Number} project_id
* @param {String} name
* @param {String} desc
* @returns {Object}
* @example
*/
async addCol(ctx){
try{
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
name: 'string',
project_id: 'number',
desc: 'string'
});
if (!params.project_id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
if(!params.name){
return ctx.body = yapi.commons.resReturn(null, 400, '名称不能为空');
}
let auth = await this.checkAuth(params.project_id, 'project', 'edit')
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
let result = await this.colModel.save({
name: params.name,
project_id: params.project_id,
desc: params.desc,
uid: this.getUid(),
add_time: yapi.commons.time(),
up_time: yapi.commons.time()
});
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 添加了接口集 "${params.name}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: params.project_id
});
ctx.body = yapi.commons.resReturn(result);
}catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 获取一个接口集下的所有的接口用例
* @interface /col/case_list
* @method GET
* @category col
* @foldnumber 10
* @param {String} col_id 接口集id
* @returns {Object}
* @example
*/
async getCaseList(ctx){
try {
let id = ctx.query.col_id;
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);
result[index].path = projectData.basepath + interfaceData.path;
result[index].method = interfaceData.method;
}
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 增加一个接口用例
* @interface /col/add_case
* @method POST
* @category col
* @foldnumber 10
* @param {String} casename
* @param {Number} col_id
* @param {Number} project_id
* @param {String} domain
* @param {String} path
* @param {String} method
* @param {Object} req_query
* @param {Object} req_headers
* @param {String} req_body_type
* @param {Array} req_body_form
* @param {String} req_body_other
* @returns {Object}
* @example
*/
async addCase(ctx){
try{
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
casename: 'string',
project_id: 'number',
col_id: 'number',
interface_id: 'number',
case_env: 'string'
});
if (!params.project_id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
if(!params.interface_id){
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
}
let auth = await this.checkAuth(params.project_id, 'project', 'edit');
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
if (!params.col_id) {
return ctx.body = yapi.commons.resReturn(null, 400, '接口集id不能为空');
}
if(!params.casename){
return ctx.body = yapi.commons.resReturn(null, 400, '用例名称不能为空');
}
params.uid = this.getUid();
params.index = 0;
params.add_time = yapi.commons.time();
params.up_time = yapi.commons.time();
let result = await this.caseModel.save(params);
let username = this.getUsername();
this.colModel.get(params.col_id).then((col)=>{
yapi.commons.saveLog({
content: `用户 "${username}" 在接口集 "${col.name}" 下添加了接口用例 "${params.casename}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: params.project_id
});
});
ctx.body = yapi.commons.resReturn(result);
}catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 更新一个接口用例
* @interface /col/up_case
* @method POST
* @category col
* @foldnumber 10
* @param {number} id
* @param {String} casename
* @param {String} domain
* @param {String} path
* @param {String} method
* @param {Object} req_query
* @param {Object} req_headers
* @param {String} req_body_type
* @param {Array} req_body_form
* @param {String} req_body_other
* @returns {Object}
* @example
*/
async upCase(ctx){
try{
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
id: 'number',
casename: 'string'
});
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '用例id不能为空');
}
if(!params.casename){
return ctx.body = yapi.commons.resReturn(null, 400, '用例名称不能为空');
}
let caseData = await this.caseModel.get(params.id);
let auth = await this.checkAuth(caseData.project_id, 'project', 'edit');
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
params.uid = this.getUid();
delete params.interface_id;
delete params.project_id;
delete params.col_id;
let result = await this.caseModel.up(params.id, params);
let username = this.getUsername();
this.colModel.get(caseData.col_id).then((col)=>{
yapi.commons.saveLog({
content: `用户 "${username}" 在接口集 "${col.name}" 更新了接口用例 "${params.casename}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: caseData.project_id
});
});
ctx.body = yapi.commons.resReturn(result);
}catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 获取一个接口用例详情
* @interface /col/case
* @method GET
* @category col
* @foldnumber 10
* @param {String} caseid
* @returns {Object}
* @example
*/
async getCase(ctx){
try{
let id = ctx.query.caseid;
let result = await this.caseModel.get(id);
if(!result){
return ctx.body = yapi.commons.resReturn(null, 400, '不存在的case');
}
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.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)
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)
}
}
handleParamsValue(params, val){
let value = {};
if(params.length === 0 || val.length === 0){
return params;
}
val.forEach((item, index)=>{
value[item.name] = item;
})
params.forEach((item, index)=>{
params[index].value = value[item.name].value;
})
return params;
}
/**
* 更新一个接口集name或描述
* @interface /col/up_col
* @method POST
* @category col
* @foldnumber 10
* @param {String} name
* @param {String} desc
* @returns {Object}
* @example
*/
async upCol(ctx){
try{
let params = ctx.request.body;
let id = params.col_id;
let colData = await this.colModel.get(id);
let auth = await this.checkAuth(colData.project_id, 'project', 'edit')
if (!auth) {
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
let result = await this.colModel.up(params.col_id, {
name: params.name,
desc: params.desc,
up_time: yapi.commons.time()
});
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 更新了接口集 "${params.name}" 的信息`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: colData.project_id
});
ctx.body = yapi.commons.resReturn(result)
}catch(e){
ctx.body = yapi.commons.resReturn(null, 400, e.message)
}
}
/**
* 更新多个接口case index
* @interface /col/up_col_index
* @method POST
* @category col
* @foldnumber 10
* @param {Array} [id, index]
* @returns {Object}
* @example
*/
async upCaseIndex(ctx){
try{
let params = ctx.request.body;
if(!params || !Array.isArray(params)){
ctx.body = yapi.commons.resReturn(null, 400, "请求参数必须是数组")
}
// let caseName = "";
params.forEach((item) => {
if(item.id && item.index){
this.caseModel.upCaseIndex(item.id, item.index).then((res) => {}, (err) => {
yapi.commons.log(err.message, 'error')
})
}
});
// let username = this.getUsername();
// yapi.commons.saveLog({
// content: `用户 "${username}" 更新了接口集 "${params.col_name}"`,
// type: 'project',
// uid: this.getUid(),
// username: username,
// typeid: params.project_id
// });
return ctx.body = yapi.commons.resReturn('成功!')
}catch(e){
ctx.body = yapi.commons.resReturn(null, 400, e.message)
}
}
/**
* 删除一个接口集
* @interface /col/del_col
* @method GET
* @category col
* @foldnumber 10
* @param {String}
* @returns {Object}
* @example
*/
async delCol(ctx){
try{
let id = ctx.query.col_id;
let colData = await this.colModel.get(id);
if(!colData){
ctx.body = yapi.commons.resReturn(null, 400, "不存在的id")
}
if(colData.uid !== this.getUid()){
let auth = await this.checkAuth(colData.project_id, 'project', 'danger')
if(!auth){
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
}
let result = await this.colModel.del(id);
await this.caseModel.delByCol(id);
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 删除了接口集 "${colData.name}" 及其下面的接口`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: colData.project_id
});
return ctx.body = yapi.commons.resReturn(result);
}catch(e){
yapi.commons.resReturn(null, 400, e.message)
}
}
/**
*
* @param {*} ctx
*/
async delCase(ctx){
try{
let caseid = ctx.query.caseid;
let caseData = await this.caseModel.get(caseid);
if(!caseData){
ctx.body = yapi.commons.resReturn(null, 400, "不存在的caseid")
}
if(caseData.uid !== this.getUid()){
let auth = await this.checkAuth(caseData.project_id, 'project', 'danger')
if(!auth){
return ctx.body = yapi.commons.resReturn(null, 400, '没有权限');
}
}
let result = await this.caseModel.del(caseid);
let username = this.getUsername();
this.colModel.get(caseData.col_id).then((col)=>{
yapi.commons.saveLog({
content: `用户 "${username}" 删除了接口集 "${col.name}" 下的接口 "${caseData.casename}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: caseData.project_id
});
});
return ctx.body = yapi.commons.resReturn(result);
}catch(e){
yapi.commons.resReturn(null, 400, e.message)
}
}
}
module.exports = interfaceColController
</pre>
</div>
</div>
</div>
</div>
<!-- <div class="docs-header" id="content" tabindex="-1">
<div class="container">
<h1>YApi : ./server/controllers/interfaceCol.js</h1>
<p>源代码</p>
</div>
</div> -->
<footer class="docs-footer" role="contentinfo">
<div class="container">
<p></p>
</div>
</footer>
</div>
<script type="text/javascript">
SyntaxHighlighter.all();
function getTop(node){
return node.offsetTop + (node.offsetParent ? getTop(node.offsetParent) : 0);
}
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
try {
var lineNum = (parseInt(location.hash.replace(/#/g, '')) - 1) || 0,
node = document.querySelectorAll('div.line')[lineNum];
document.body.scrollTop = getTop(node);
node.className += ' highlight';
} catch(e) {}
}, 500);
}, false);
</script>
</body>
</html>

View File

@ -1,117 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>YApi : ./server/controllers/log.js</title>
<link type="text/css" rel="stylesheet" href="../../../source/code.css"/>
<script type="text/javascript" src="../../../source/shCore.js"></script>
<script type="text/javascript" src="../../../source/shBrush-js.js"></script>
<style>
.syntaxhighlighter .number1 .spaces,.syntaxhighlighter .toolbar{ display: none;}
.syntaxhighlighter table td.gutter .line.highlight { background-color: #6ce26c !important; color: white; }
</style>
</head>
<body>
<div class="ydoc">
<div class="ydoc-banner-bg">
<div class="ydoc-banner" id="content" tabindex="-1">
<div class="ydoc-banner-area">
<h1>YApi : ./server/controllers/log.js</h1>
<p>源代码</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content">
<div class="static-code-content" role="main">
<pre class="brush: js;">
const logModel = require('../models/log.js');
const yapi = require('../yapi.js');
const baseController = require('./base.js');
const groupModel = require('../models/group');
class logController extends baseController {
constructor(ctx) {
super(ctx);
this.Model = yapi.getInst(logModel);
this.groupModel = yapi.getInst(groupModel);
}
/**
* 获取动态列表
* @interface /log/list
* @method GET
* @category log
* @foldnumber 10
* @param {Number} typeid 动态类型id 不能为空
* @param {Number} [page] 分页页码
* @param {Number} [limit] 分页大小
* @returns {Object}
* @example /log/list
*/
async list(ctx) {
let typeid = ctx.request.query.typeid,
page = ctx.request.query.page || 1,
limit = ctx.request.query.limit || 10,
type = ctx.request.query.type;
if (!typeid) {
return ctx.body = yapi.commons.resReturn(null, 400, 'typeid不能为空');
}
if(!type) {
return ctx.body = yapi.commons.resReturn(null, 400, 'type不能为空');
}
try {
let result = await this.Model.listWithPaging(typeid,type, page, limit);
let count = await this.Model.listCount(typeid,type);
ctx.body = yapi.commons.resReturn({
total: Math.ceil(count / limit),
list: result
});
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
}
module.exports = logController;
</pre>
</div>
</div>
</div>
</div>
<!-- <div class="docs-header" id="content" tabindex="-1">
<div class="container">
<h1>YApi : ./server/controllers/log.js</h1>
<p>源代码</p>
</div>
</div> -->
<footer class="docs-footer" role="contentinfo">
<div class="container">
<p></p>
</div>
</footer>
</div>
<script type="text/javascript">
SyntaxHighlighter.all();
function getTop(node){
return node.offsetTop + (node.offsetParent ? getTop(node.offsetParent) : 0);
}
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
try {
var lineNum = (parseInt(location.hash.replace(/#/g, '')) - 1) || 0,
node = document.querySelectorAll('div.line')[lineNum];
document.body.scrollTop = getTop(node);
node.className += ' highlight';
} catch(e) {}
}, 500);
}, false);
</script>
</body>
</html>

View File

@ -1,774 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>YApi : ./server/controllers/project.js</title>
<link type="text/css" rel="stylesheet" href="../../../source/code.css"/>
<script type="text/javascript" src="../../../source/shCore.js"></script>
<script type="text/javascript" src="../../../source/shBrush-js.js"></script>
<style>
.syntaxhighlighter .number1 .spaces,.syntaxhighlighter .toolbar{ display: none;}
.syntaxhighlighter table td.gutter .line.highlight { background-color: #6ce26c !important; color: white; }
</style>
</head>
<body>
<div class="ydoc">
<div class="ydoc-banner-bg">
<div class="ydoc-banner" id="content" tabindex="-1">
<div class="ydoc-banner-area">
<h1>YApi : ./server/controllers/project.js</h1>
<p>源代码</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content">
<div class="static-code-content" role="main">
<pre class="brush: js;">
const projectModel = require('../models/project.js');
const yapi = require('../yapi.js');
const _ = require("underscore");
const baseController = require('./base.js');
const interfaceModel = require('../models/interface.js');
const interfaceColModel = require('../models/interfaceCol.js');
const interfaceCaseModel = require('../models/interfaceCase.js');
const interfaceCatModel = require('../models/interfaceCat.js');
const groupModel = require('../models/group');
const commons = require('../utils/commons.js');
const userModel = require('../models/user.js');
const logModel = require('../models/log.js');
const followModel = require('../models/follow.js');
const Mock = require('mockjs');
const send = require('koa-send');
class projectController extends baseController {
constructor(ctx) {
super(ctx);
this.Model = yapi.getInst(projectModel);
this.groupModel = yapi.getInst(groupModel);
this.logModel = yapi.getInst(logModel);
this.followModel = yapi.getInst(followModel);
}
handleBasepath(basepath) {
if (!basepath) return "";
if (basepath === '/') return "";
if (basepath[0] !== '/') basepath = '/' + basepath;
if (basepath[basepath.length - 1] === '/') basepath = basepath.substr(0, basepath.length - 1);
if (!yapi.commons.verifyPath(basepath)) {
return false;
}
return basepath;
}
verifyDomain(domain) {
if (!domain) return false;
if (/^[a-zA-Z0-9\-_\.]+?\.[a-zA-Z0-9\-_\.]*?[a-zA-Z]{2,6}$/.test(domain)) {
return true;
}
return false;
}
/**
* 添加项目分组
* @interface /project/add
* @method POST
* @category project
* @foldnumber 10
* @param {String} name 项目名称,不能为空
* @param {String} basepath 项目基本路径,不能为空
* @param {Number} group_id 项目分组id不能为空
* @param {Number} group_name 项目分组名称,不能为空
* @param {String} project_type private public
* @param {String} [desc] 项目描述
* @returns {Object}
* @example ./api/project/add.json
*/
async add(ctx) {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
name: 'string',
basepath: 'string',
group_id: 'number',
group_name: 'string',
desc: 'string',
color: 'string',
icon: 'string'
});
if (await this.checkAuth(params.group_id, 'group', 'edit') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
if (!params.group_id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组id不能为空');
}
if (!params.name) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目名不能为空');
}
let checkRepeat = await this.Model.checkNameRepeat(params.name);
if (checkRepeat > 0) {
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名');
}
params.basepath = params.basepath || '';
if ((params.basepath = this.handleBasepath(params.basepath)) === false) {
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误');
}
let data = {
name: params.name,
desc: params.desc,
basepath: params.basepath,
members: [],
project_type: params.project_type || 'private',
uid: this.getUid(),
group_id: params.group_id,
group_name: params.group_name,
icon: params.icon,
color: params.color,
add_time: yapi.commons.time(),
up_time: yapi.commons.time(),
env: [{ name: 'local', domain: 'http://127.0.0.1' }]
};
try {
let result = await this.Model.save(data);
let colInst = yapi.getInst(interfaceColModel);
let catInst = yapi.getInst(interfaceCatModel);
if (result._id) {
await colInst.save({
name: '公共测试集',
project_id: result._id,
desc: '公共测试集',
uid: this.getUid(),
add_time: yapi.commons.time(),
up_time: yapi.commons.time()
})
await catInst.save({
name: '公共分类',
project_id: result._id,
desc: '公共分类',
uid: this.getUid(),
add_time: yapi.commons.time(),
up_time: yapi.commons.time()
})
}
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 添加了项目 "${params.name}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: params.group_id
});
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 添加项目成员
* @interface /project/add_member
* @method POST
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @param {String} member_uid 项目成员uid,不能为空
* @returns {Object}
* @example ./api/project/add_member.json
*/
async addMember(ctx) {
let params = ctx.request.body;
if (!params.member_uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员uid不能为空');
}
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
if (await this.checkAuth(params.id, 'project', 'edit') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
var check = await this.Model.checkMemberRepeat(params.id, params.member_uid);
if (check > 0) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员已存在');
}
params.role = params.role === 'owner' ? 'owner' : 'dev';
let userdata = await this.getUserdata(params.member_uid, params.role);
if (userdata === null) {
return ctx.body = yapi.commons.resReturn(null, 400, '成员uid不存在')
}
try {
let result = await this.Model.addMember(params.id, userdata);
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 添加了项目成员 "${userdata.username}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: params.id
});
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 删除项目成员
* @interface /project/del_member
* @method POST
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @param {member_uid} uid 项目成员uid,不能为空
* @returns {Object}
* @example ./api/project/del_member.json
*/
async delMember(ctx) {
let params = ctx.request.body;
if (!params.member_uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员uid不能为空');
}
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
var check = await this.Model.checkMemberRepeat(params.id, params.member_uid);
if (check === 0) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在');
}
if (await this.checkAuth(params.id, 'project', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
try {
let result = await this.Model.delMember(params.id, params.member_uid);
let username = this.getUsername();
yapi.getInst(userModel).findById(params.member_uid).then((member)=>{
yapi.commons.saveLog({
content: `用户 "${username}" 删除了项目中的成员 "${member.username}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: params.id
});
});
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
async getUserdata(uid, role) {
role = role || 'dev';
let userInst = yapi.getInst(userModel);
let userData = await userInst.findById(uid);
if (!userData) {
return null;
}
return {
role: role,
uid: userData._id,
username: userData.username,
email: userData.email
}
}
/**
* 获取项目成员列表
* @interface /project/get_member_list
* @method GET
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @return {Object}
* @example ./api/project/get_member_list.json
*/
async getMemberList(ctx) {
let params = ctx.request.query;
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
try {
let project = await this.Model.get(params.id);
ctx.body = yapi.commons.resReturn(project.members);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 获取项目信息
* @interface /project/get
* @method GET
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @returns {Object}
* @example ./api/project/get.json
*/
async get(ctx) {
let params = ctx.request.query;
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
try {
let result = await this.Model.getBaseInfo(params.id);
if (!result) {
return ctx.body = yapi.commons.resReturn(null, 400, '不存在的项目');
}
result = result.toObject();
let catInst = yapi.getInst(interfaceCatModel);
let cat = await catInst.list(params.id);
result.cat = cat;
result.role = await this.getProjectRole(params.id, 'project');
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 获取项目列表
* @interface /project/list
* @method GET
* @category project
* @foldnumber 10
* @param {Number} group_id 项目group_id不能为空
* @returns {Object}
* @example ./api/project/list.json
*/
async list(ctx) {
let group_id = ctx.request.query.group_id, project_list = [];
if (!group_id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组id不能为空');
}
let auth = await this.checkAuth(group_id, 'group', 'edit')
try {
let result = await this.Model.list(group_id);
let follow = await this.followModel.list(this.getUid());
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(item._id, this.getUid());
if(r === 0){
continue;
}
}
let f = _.find(follow, (fol) => {
return fol.projectid === item._id
})
if (f) {
item.follow = true;
} else {
item.follow = false;
}
project_list.push(item);
};
ctx.body = yapi.commons.resReturn({
list: project_list
});
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 删除项目
* @interface /project/del
* @method POST
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @returns {Object}
* @example ./api/project/del.json
*/
async del(ctx) {
try {
let id = ctx.request.body.id;
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
if (await this.checkAuth(id, 'project', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
let interfaceInst = yapi.getInst(interfaceModel);
let interfaceColInst = yapi.getInst(interfaceColModel);
let interfaceCaseInst = yapi.getInst(interfaceCaseModel);
await interfaceInst.delByProjectId(id)
await interfaceCaseInst.delByProjectId(id)
await interfaceColInst.delByProjectId(id)
let result = await this.Model.del(id);
ctx.body = yapi.commons.resReturn(result);
} catch (err) {
ctx.body = yapi.commons.resReturn(null, 402, err.message);
}
}
/**
* 修改项目成员角色
* @interface /project/change_member_role
* @method POST
* @category project
* @foldnumber 10
* @param {String} id 项目id
* @param {String} member_uid 项目成员uid
* @param {String} role 权限 ['owner'|'dev']
* @returns {Object}
* @example
*/
async changeMemberRole(ctx) {
let params = ctx.request.body;
let projectInst = yapi.getInst(projectModel);
if (!params.member_uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员uid不能为空');
}
if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
var check = await projectInst.checkMemberRepeat(params.id, params.member_uid);
if (check === 0) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在');
}
if (await this.checkAuth(params.id, 'project', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
params.role = params.role === 'owner' ? 'owner' : 'dev';
try {
let result = await projectInst.changeMemberRole(params.id, params.member_uid, params.role);
let username = this.getUsername();
yapi.getInst(userModel).findById(params.member_uid).then((member)=>{
yapi.commons.saveLog({
content: `用户 "${username}" 修改了项目中的成员 "${member.username}" 的角色为 "${params.role}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: params.id
});
})
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 项目设置
* @interface /project/upset
* @method POST
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @param {String} icon 项目icon
* @param {Array} color 项目color
* @returns {Object}
* @example ./api/project/upset
*/
async upSet(ctx) {
let id = ctx.request.body.id;
let data = {};
if (await this.checkAuth(id, 'project', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
data.color = ctx.request.body.color;
data.icon = ctx.request.body.icon;
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空');
}
try {
let result = await this.Model.up(id, data);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
try {
this.followModel.updateById(this.getUid(), id, data).then(()=>{
let username = this.getUsername();
yapi.commons.saveLog({
content: `用户 "${username}" 修改了项目图标、颜色`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: id
});
});
} catch (e) {
yapi.commons.log(e, 'error'); // eslint-disable-line
}
}
/**
* 编辑项目
* @interface /project/up
* @method POST
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @param {String} name 项目名称,不能为空
* @param {String} basepath 项目基本路径,不能为空
* @param {String} [desc] 项目描述
* @param {Array} [env] 项目环境配置
* @param {String} [env[].name] 环境名称
* @param {String} [env[].domain] 环境域名
* @returns {Object}
* @example ./api/project/up.json
*/
async up(ctx) {
try {
let id = ctx.request.body.id;
let params = ctx.request.body;
params.basepath = params.basepath || '';
params = yapi.commons.handleParams(params, {
name: 'string',
basepath: 'string',
group_id: 'number',
desc: 'string',
icon: 'string',
color: 'string'
});
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空');
}
if (await this.checkAuth(id, 'project', 'edit') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
let projectData = await this.Model.get(id);
if ((params.basepath = this.handleBasepath(params.basepath)) === false) {
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误');
}
if (projectData.name === params.name) {
delete params.name;
}
if (params.name) {
let checkRepeat = await this.Model.checkNameRepeat(params.name);
if (checkRepeat > 0) {
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名');
}
}
let data = {
up_time: yapi.commons.time()
};
if(params.project_type){
data.project_type = params.project_type
}
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({
content: `用户 "${username}" 更新了项目 "${projectData.name}"`,
type: 'project',
uid: this.getUid(),
username: username,
typeid: id
});
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 模糊搜索项目名称或者组名称
* @interface /project/search
* @method GET
* @category project
* @foldnumber 10
* @param {String} q
* @return {Object}
* @example ./api/project/search.json
*/
async search(ctx) {
const { q } = ctx.request.query;
if (!q) {
return ctx.body = yapi.commons.resReturn(void 0, 400, 'No keyword.');
}
if (!yapi.commons.validateSearchKeyword(q)) {
return ctx.body = yapi.commons.resReturn(void 0, 400, 'Bad query.');
}
let projectList = await this.Model.search(q);
let groupList = await this.groupModel.search(q);
let projectRules = [
'_id',
'name',
'basepath',
'uid',
'env',
'members',
{ key: 'group_id', alias: 'groupId' },
{ key: 'up_time', alias: 'upTime' },
{ key: 'add_time', alias: 'addTime' }
];
let groupRules = [
'_id',
'uid',
{ key: 'group_name', alias: 'groupName' },
{ key: 'group_desc', alias: 'groupDesc' },
{ key: 'add_time', alias: 'addTime' },
{ key: 'up_time', alias: 'upTime' }
];
projectList = commons.filterRes(projectList, projectRules);
groupList = commons.filterRes(groupList, groupRules);
let queryList = {
project: projectList,
group: groupList
};
return ctx.body = yapi.commons.resReturn(queryList, 0, 'ok');
}
/**
* 下载项目的 Mock 数据
* @interface /project/download
* @method GET
* @category project
* @foldnumber 10
* @author wenbo.dong
* @param {String} project_id
*/
async download(ctx) {
const project_id = ctx.request.query.project_id;
let interfaceInst = yapi.getInst(interfaceModel);
// 根据 project_id 获取接口数据
let count = await interfaceInst.list(project_id);
if (!project_id) {
return ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空');
} else if (!count) {
return ctx.body = yapi.commons.resReturn(null, 401, '项目id不存在');
}
const arr = JSON.stringify(count.map(function (item) {
// 返回的json模板数据: item.res_body
const mockData = Mock.mock(
yapi.commons.json_parse(item.res_body)
);
return {
path: item.path,
mock: mockData
}
}));
const fileName = 'mock.js';
ctx.attachment(fileName);
await send(ctx, fileName, { root: __dirname + '/public' });
const res = `
var Mock = require('mockjs');
var xhook = require('xhook');
var data = ${arr};
function run() {
xhook.before(function(request, callback) {
setTimeout(function() {
var res;
data.forEach((item) => {
// 请求的接口在 data 中存在
if(request.url === item.path) {
res = {
status: 200,
text: Mock.mock(item.mock)
}
}
});
if (res) {
callback(res);
}else {
callback({ status: 405, text: '接口不存在' });
}
}, 500);
});
}
module.exports = run;`
.trim();
return ctx.body = res;
}
}
module.exports = projectController;
</pre>
</div>
</div>
</div>
</div>
<!-- <div class="docs-header" id="content" tabindex="-1">
<div class="container">
<h1>YApi : ./server/controllers/project.js</h1>
<p>源代码</p>
</div>
</div> -->
<footer class="docs-footer" role="contentinfo">
<div class="container">
<p></p>
</div>
</footer>
</div>
<script type="text/javascript">
SyntaxHighlighter.all();
function getTop(node){
return node.offsetTop + (node.offsetParent ? getTop(node.offsetParent) : 0);
}
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
try {
var lineNum = (parseInt(location.hash.replace(/#/g, '')) - 1) || 0,
node = document.querySelectorAll('div.line')[lineNum];
document.body.scrollTop = getTop(node);
node.className += ' highlight';
} catch(e) {}
}, 500);
}, false);
</script>
</body>
</html>

View File

@ -1,707 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>YApi : ./server/controllers/user.js</title>
<link type="text/css" rel="stylesheet" href="../../../source/code.css"/>
<script type="text/javascript" src="../../../source/shCore.js"></script>
<script type="text/javascript" src="../../../source/shBrush-js.js"></script>
<style>
.syntaxhighlighter .number1 .spaces,.syntaxhighlighter .toolbar{ display: none;}
.syntaxhighlighter table td.gutter .line.highlight { background-color: #6ce26c !important; color: white; }
</style>
</head>
<body>
<div class="ydoc">
<div class="ydoc-banner-bg">
<div class="ydoc-banner" id="content" tabindex="-1">
<div class="ydoc-banner-area">
<h1>YApi : ./server/controllers/user.js</h1>
<p>源代码</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content">
<div class="static-code-content" role="main">
<pre class="brush: js;">
const userModel = require('../models/user.js');
const yapi = require('../yapi.js');
const baseController = require('./base.js');
const request = require('request');
const common = require('../utils/commons.js');
const interfaceModel = require('../models/interface.js');
const groupModel = require('../models/group.js');
const projectModel = require('../models/project.js');
const avatarModel = require('../models/avatar.js');
const jwt = require('jsonwebtoken');
class userController extends baseController {
constructor(ctx) {
super(ctx);
this.Model = yapi.getInst(userModel);
}
/**
* 用户登录接口
* @interface /user/login
* @method POST
* @category user
* @foldnumber 10
* @param {String} email email名称不能为空
* @param {String} password 密码,不能为空
* @returns {Object}
* @example ./api/user/login.json
*/
async login(ctx) { //登录
let userInst = yapi.getInst(userModel); //创建user实体
let email = ctx.request.body.email;
let password = ctx.request.body.password;
if (!email) {
return ctx.body = yapi.commons.resReturn(null, 400, 'email不能为空');
}
if (!password) {
return ctx.body = yapi.commons.resReturn(null, 400, '密码不能为空');
}
let result = await userInst.findByEmail(email);
if (!result) {
return ctx.body = yapi.commons.resReturn(null, 404, '该用户不存在');
} else if (yapi.commons.generatePassword(password, result.passsalt) === result.password) {
this.setLoginCookie(result._id, result.passsalt);
return ctx.body = yapi.commons.resReturn({
username: result.username,
role: result.role,
uid: result._id,
email: result.email,
add_time: result.add_time,
up_time: result.up_time,
server_ip: yapi.WEBCONFIG.server_ip,
type: 'site'
}, 0, 'logout success...');
} else {
return ctx.body = yapi.commons.resReturn(null, 405, '密码错误');
}
}
/**
* 退出登录接口
* @interface /user/logout
* @method GET
* @category user
* @foldnumber 10
* @returns {Object}
* @example ./api/user/logout.json
*/
async logout(ctx) {
ctx.cookies.set('_yapi_token', null);
ctx.cookies.set('_yapi_uid', null);
ctx.body = yapi.commons.resReturn('ok');
}
/**
* 第三方登录需要提供一个request方法和 token字段暂时只支持qunar第三方
* @return {email: String, username: String}
*/
thirdQunarLogin() {
return {
request: (token) => {
return new Promise((resolve, reject) => {
request('http://qsso.corp.qunar.com/api/verifytoken.php?token=' + token, function (error, response, body) {
if (!error && response.statusCode == 200) {
let result = JSON.parse(body);
if (result && result.ret === true) {
let ret = {
email: result.userId + '@qunar.com',
username: result.data.userInfo.name
};
resolve(ret);
} else {
reject(result);
}
}
reject(error);
});
});
},
tokenField: 'token'
};
}
async loginByToken(ctx) {
//let config = this.thirdQunarLogin();
try {
let ret = await yapi.emitHook('third_login', ctx);
let login = await this.handleThirdLogin(ret.email, ret.username);
if (login === true) {
yapi.commons.log('login success');
ctx.redirect('/group');
}
} catch (e) {
yapi.commons.log(e.message, 'error');
ctx.redirect('/');
}
}
async handleThirdLogin(email, username) {
let user, data, passsalt;
let userInst = yapi.getInst(userModel);
try {
user = await userInst.findByEmail(email);
if (!user || !user._id) {
passsalt = yapi.commons.randStr();
data = {
username: username,
password: yapi.commons.generatePassword(passsalt, passsalt),
email: email,
passsalt: passsalt,
role: 'member',
add_time: yapi.commons.time(),
up_time: yapi.commons.time(),
type: 'third'
};
user = await userInst.save(data);
yapi.commons.sendMail({
to: email,
contents: `<h3>亲爱的用户:</h3><p>您好感谢使用YApi平台你的邮箱账号是${email}</p>`
});
}
this.setLoginCookie(user._id, user.passsalt);
return true;
} catch (e) {
console.error('third_login:', e.message); // eslint-disable-line
return false;
}
}
/**
* 修改用户密码
* @interface /user/change_password
* @method POST
* @category user
* @param {Number} uid 用户ID
* @param {Number} [old_password] 旧密码, 非admin用户必须传
* @param {Number} password 新密码
* @return {Object}
* @example ./api/user/change_password.json
*/
async changePassword(ctx) {
let params = ctx.request.body;
let userInst = yapi.getInst(userModel);
if (!params.uid) {
return ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空');
}
if (!params.password) {
return ctx.body = yapi.commons.resReturn(null, 400, '密码不能为空');
}
if (this.getRole() !== 'admin' && params.uid != this.getUid()) {
return ctx.body = yapi.commons.resReturn(null, 402, '没有权限');
}
if (this.getRole() !== 'admin') {
if (!params.old_password) {
return ctx.body = yapi.commons.resReturn(null, 400, '旧密码不能为空');
}
let user = await userInst.findById(params.uid);
if (yapi.commons.generatePassword(params.old_password, user.passsalt) !== user.password) {
return ctx.body = yapi.commons.resReturn(null, 402, '旧密码错误');
}
}
let passsalt = yapi.commons.randStr();
let data = {
up_time: yapi.commons.time(),
password: yapi.commons.generatePassword(params.password, passsalt),
passsalt: passsalt
};
try {
let result = await userInst.update(params.uid, data);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 401, e.message);
}
}
setLoginCookie(uid, passsalt) {
let token = jwt.sign({ uid: uid }, passsalt, { expiresIn: '7 days' });
this.ctx.cookies.set('_yapi_token', token, {
expires: yapi.commons.expireDate(7),
httpOnly: true
});
this.ctx.cookies.set('_yapi_uid', uid, {
expires: yapi.commons.expireDate(7),
httpOnly: true
});
}
/**
* 用户注册接口
* @interface /user/reg
* @method POST
* @category user
* @foldnumber 10
* @param {String} email email名称不能为空
* @param {String} password 密码,不能为空
* @param {String} [username] 用户名
* @returns {Object}
* @example ./api/user/login.json
*/
async reg(ctx) { //注册
let userInst = yapi.getInst(userModel);
let params = ctx.request.body; //获取请求的参数,检查是否存在用户名和密码
params = yapi.commons.handleParams(params, {
username: 'string',
password: 'string',
email: 'string'
});
if (!params.email) {
return ctx.body = yapi.commons.resReturn(null, 400, '邮箱不能为空');
}
if (!params.password) {
return ctx.body = yapi.commons.resReturn(null, 400, '密码不能为空');
}
let checkRepeat = await userInst.checkRepeat(params.email);//然后检查是否已经存在该用户
if (checkRepeat > 0) {
return ctx.body = yapi.commons.resReturn(null, 401, '该email已经注册');
}
let passsalt = yapi.commons.randStr();
let data = {
username: params.username,
password: yapi.commons.generatePassword(params.password, passsalt),//加密
email: params.email,
passsalt: passsalt,
role: 'member',
add_time: yapi.commons.time(),
up_time: yapi.commons.time(),
type: "site"
};
if (!data.username) {
data.username = data.email.substr(0, data.email.indexOf('@'));
}
try {
let user = await userInst.save(data);
this.setLoginCookie(user._id, user.passsalt);
ctx.body = yapi.commons.resReturn({
uid: user._id,
email: user.email,
username: user.username,
add_time: user.add_time,
up_time: user.up_time,
role: 'member',
type: user.type
});
yapi.commons.sendMail({
to: user.email,
contents: `<h3>亲爱的用户:</h3><p>您好感谢使用YApi,您的账号 ${params.email} 已经注册成功</p>`
});
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 401, e.message);
}
}
/**
* 获取用户列表
* @interface /user/list
* @method GET
* @category user
* @foldnumber 10
* @param {Number} [page] 分页页码
* @param {Number} [limit] 分页大小,默认为10条
* @returns {Object}
* @example
*/
async list(ctx) {
let page = ctx.request.query.page || 1,
limit = ctx.request.query.limit || 10;
const userInst = yapi.getInst(userModel);
try {
let user = await userInst.listWithPaging(page, limit);
let count = await userInst.listCount();
return ctx.body = yapi.commons.resReturn({
total: Math.ceil(count / limit),
list: user
});
} catch (e) {
return ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 获取用户个人信息
* @interface /user/find
* @method GET
* @param id 用户uid
* @category user
* @foldnumber 10
* @returns {Object}
* @example
*/
async findById(ctx) { //根据id获取用户信息
try {
let userInst = yapi.getInst(userModel);
let id = ctx.request.query.id;
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空');
}
let result = await userInst.findById(id);
if (!result) {
return ctx.body = yapi.commons.resReturn(null, 402, '不存在的用户');
}
return ctx.body = yapi.commons.resReturn({
uid: result._id,
username: result.username,
email: result.email,
role: result.role,
type: result.type,
add_time: result.add_time,
up_time: result.up_time
});
} catch (e) {
return ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 删除用户,只有admin用户才有此权限
* @interface /user/del
* @method POST
* @param id 用户uid
* @category user
* @foldnumber 10
* @returns {Object}
* @example
*/
async del(ctx) { //根据id删除一个用户
try {
if (this.getRole() !== 'admin') {
return ctx.body = yapi.commons.resReturn(null, 402, 'Without permission.');
}
let userInst = yapi.getInst(userModel);
let id = ctx.request.body.id;
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空');
}
let result = await userInst.del(id);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 更新用户个人信息
* @interface /user/update
* @method POST
* @param uid 用户uid
* @param [role] 用户角色,只有管理员有权限修改
* @param [username] String
* @param [email] String
* @category user
* @foldnumber 10
* @returns {Object}
* @example
*/
async update(ctx) { //更新用户信息
try {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
username: 'string',
email: 'string'
});
if (this.getRole() !== 'admin' && params.uid != this.getUid()) {
return ctx.body = yapi.commons.resReturn(null, 401, '没有权限');
}
let userInst = yapi.getInst(userModel);
let id = params.uid;
if (!id) {
return ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空');
}
let data = {
up_time: yapi.commons.time()
};
params.username && (data.username = params.username);
params.email && (data.email = params.email);
if (data.email) {
var checkRepeat = await userInst.checkRepeat(data.email);//然后检查是否已经存在该用户
if (checkRepeat > 0) {
return ctx.body = yapi.commons.resReturn(null, 401, '该email已经注册');
}
}
let result = await userInst.update(id, data);
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
/**
* 上传用户头像
* @interface /user/upload_avatar
* @method POST
* @param {*} basecode base64编码通过h5 api传给后端
* @category user
* @returns {Object}
* @example
*/
async uploadAvatar(ctx) {
try {
let basecode = ctx.request.body.basecode;
if(!basecode){
return ctx.body = yapi.commons.resReturn(null, 400, 'basecode不能为空')
}
let pngPrefix = 'data:image/png;base64,';
let jpegPrefix = 'data:image/jpeg;base64,';
let type;
if(basecode.substr(0, pngPrefix.length ) === pngPrefix){
basecode = basecode.substr(pngPrefix.length);
type = 'image/png';
}else if(basecode.substr(0, jpegPrefix.length ) === jpegPrefix){
basecode = basecode.substr(jpegPrefix.length);
type = 'image/jpeg';
}else{
return ctx.body = yapi.commons.resReturn(null, 400, '仅支持jpeg和png格式的图片')
}
let strLength = basecode.length;
if(parseInt(strLength-(strLength/8)*2) > 200000){
return ctx.body = yapi.commons.resReturn(null, 400, '图片大小不能超过200kb');
}
let avatarInst = yapi.getInst(avatarModel);
let result = await avatarInst.up(this.getUid(), basecode, type)
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 401, e.message);
}
}
/**
* 根据用户uid头像
* @interface /user/avatar
* @method GET
* @param {*} uid
* @category user
* @returns {Object}
* @example
*/
async avatar(ctx) {
try{
let uid = ctx.query.uid ? ctx.query.uid: this.getUid();
let avatarInst = yapi.getInst(avatarModel);
let data = await avatarInst.get(uid);
let dataBuffer, type;
if(!data || !data.basecode){
dataBuffer = yapi.fs.readFileSync(yapi.path.join(yapi.WEBROOT, 'static/image/avatar.png'));
type = 'image/png'
}else{
type = data.type;
dataBuffer = new Buffer(data.basecode, 'base64');
}
ctx.set('Content-type', type);
ctx.body = dataBuffer;
}catch(err){
ctx.body = 'error:' + err.message
}
}
/**
* 模糊搜索用户名或者email
* @interface /user/search
* @method GET
* @category user
* @foldnumber 10
* @param {String} q
* @return {Object}
* @example ./api/user/search.json
*/
async search(ctx) {
const { q } = ctx.request.query;
if (!q) {
return ctx.body = yapi.commons.resReturn(void 0, 400, 'No keyword.');
}
if (!yapi.commons.validateSearchKeyword(q)) {
return ctx.body = yapi.commons.resReturn(void 0, 400, 'Bad query.');
}
let queryList = await this.Model.search(q);
let rules = [
{
key: '_id',
alias: 'uid'
},
'username',
'email',
'role',
{
key: 'add_time',
alias: 'addTime'
},
{
key: 'up_time',
alias: 'upTime'
}
];
let filteredRes = common.filterRes(queryList, rules);
return ctx.body = yapi.commons.resReturn(filteredRes, 0, 'ok');
}
/**
* 根据路由id初始化项目数据
* @interface /user/project
* @method GET
* @category user
* @foldnumber 10
* @param {String} type 可选group|interface|project
* @param {Number} id
* @return {Object}
* @example
*/
async project(ctx) {
let { id, type } = ctx.request.query;
let result = {};
try {
if (type === 'interface') {
let interfaceInst = yapi.getInst(interfaceModel);
let interfaceData = await interfaceInst.get(id)
result.interface = interfaceData;
type = 'project';
id = interfaceData.project_id;
}
if (type === 'project') {
let projectInst = yapi.getInst(projectModel);
let projectData = await projectInst.get(id);
result.project = projectData.toObject();
let ownerAuth = await this.checkAuth(id, 'project', 'danger'), devAuth;
if(ownerAuth){
result.project.role = 'owner'
}else{
devAuth = await this.checkAuth(id, 'project', 'site');
if(devAuth){
result.project.role = 'dev'
}else{
result.project.role = 'member'
}
}
type = 'group';
id = projectData.group_id;
}
if (type === 'group') {
let groupInst = yapi.getInst(groupModel);
let groupData = await groupInst.get(id);
result.group = groupData.toObject();
let ownerAuth = await this.checkAuth(id, 'group', 'danger'), devAuth;
if(ownerAuth){
result.group.role = 'owner'
}else{
devAuth = await this.checkAuth(id, 'group', 'site');
if(devAuth){
result.group.role = 'dev'
}else{
result.group.role = 'member'
}
}
}
return ctx.body = yapi.commons.resReturn(result)
}
catch (e) {
return ctx.body = yapi.commons.resReturn(result, 422, e.message)
}
}
}
module.exports = userController;
</pre>
</div>
</div>
</div>
</div>
<!-- <div class="docs-header" id="content" tabindex="-1">
<div class="container">
<h1>YApi : ./server/controllers/user.js</h1>
<p>源代码</p>
</div>
</div> -->
<footer class="docs-footer" role="contentinfo">
<div class="container">
<p></p>
</div>
</footer>
</div>
<script type="text/javascript">
SyntaxHighlighter.all();
function getTop(node){
return node.offsetTop + (node.offsetParent ? getTop(node.offsetParent) : 0);
}
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
try {
var lineNum = (parseInt(location.hash.replace(/#/g, '')) - 1) || 0,
node = document.querySelectorAll('div.line')[lineNum];
document.body.scrollTop = getTop(node);
node.className += ' highlight';
} catch(e) {}
}, 500);
}, false);
</script>
</body>
</html>

View File

@ -1,61 +0,0 @@
body, h1, h2, h3, h4, h5, h6 {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
SimSun, sans-serif;
}
.markdown-body h1, .markdown-body h2 {
padding-bottom: .75em;
margin-top: 3em;
}
.doc-img {
width: 50%;
display: block;
margin: 24px 0;
}
.list-index {
padding: 6px;
background-color: #ff561b;
color: #fff;
font:italic bold 18px arial,sans-serif;
border-radius: 50%;
display: inline-block;
width: 2.2em;
height: 2.2em;
line-height: 1.6em;
margin-right: .6em;
text-align: center;
vertical-align: middle;
}
/* 覆盖掉 Interface 下的标题样式 */
.markdown-body blockquote.api {
background-color: transparent;
}
.markdown-body blockquote.api:before {
content: '';
display: none;
}
/* markdown 的注释样式 */
.markdown-body blockquote {
border-left: 4px solid #ff561b;
background-color: #f8f8f8;
padding: .12rem .24rem;
position: relative;
}
.markdown-body blockquote:before {
content: '!';
display: block;
position: absolute;
left: -.12rem;
top: .12rem;
width: 20px;
height: 20px;
background-color: #ff561b;
color: #fff;
border-radius: 50%;
text-align: center;
font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
}

View File

@ -1,364 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 使用手册</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="active">
<a href="usage.html">使用手册</a>
</li>
<li class="">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >YApi</h1>
<p class="desc ">高效、易用、功能强大的api管理平台旨在为开发、产品、测试人员提供更优雅的接口管理服务。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="usage-认识 YApi.html">认识 YApi</a>
</li>
<!-- <li > -->
<li >
<a href="usage-创建第一个API.html">创建第一个API</a>
</li>
<!-- <li > -->
<li >
<a href="usage-项目管理.html">项目管理</a>
</li>
<!-- <li > -->
<li >
<a href="usage-接口配置与调试.html">接口配置与调试</a>
</li>
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="usage-使用mock功能.html">使用mock功能</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#Mock介绍">Mock介绍</a>
</li>
<li >
<a href="#定义mock数据示例">定义mock数据示例</a>
</li>
<li >
<a href="#yapiMock跟mockjs区别">yapiMock跟mockjs区别</a>
</li>
<li >
<a href="#如何使用Mock?">如何使用Mock?</a>
</li>
<li >
<a href="#Mock语法规范">Mock语法规范</a>
</li>
</ul>
<!-- <li > -->
<li >
<a href="usage-使用测试集.html">使用测试集</a>
</li>
</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 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>
<pre><code>mockd地址 http<span class="token operator">:</span>//yapi.corp.qunar.com/mock/<span class="token number">29</span>/api/hackathon/login
</code></pre><p>项目id可以在项目设置里查看到</p>
<h2 class="subject" id="定义mock数据示例">定义mock数据示例 <a class="hashlink" href="#定义mock数据示例">#</a></h2><pre><code><span class="token punctuation">{</span>
"status|<span class="token number">0</span>-<span class="token number">1</span>"<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> //接口状态
<span class="token property">"message"</span><span class="token operator">:</span> <span class="token string">"请求完成"</span><span class="token punctuation">,</span> //消息提示
<span class="token property">"data"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token property">"counts"</span><span class="token operator">:</span><span class="token string">"@integer"</span><span class="token punctuation">,</span> //统计数量
"totalSubjectType|<span class="token number">4</span>-<span class="token number">10</span>"<span class="token operator">:</span> <span class="token punctuation">[</span>
<span class="token punctuation">{</span>
"subjectName|regexp"<span class="token operator">:</span> "大数据|机器学习|工具<span class="token string">", //主题名
"</span>subjectType|+<span class="token number">1</span>"<span class="token operator">:</span> <span class="token number">1</span> //类型
<span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token property">"data"</span><span class="token operator">:</span><span class="token punctuation">[</span>
<span class="token punctuation">{</span>
<span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"@name"</span><span class="token punctuation">,</span> //用户名
<span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"@email"</span><span class="token punctuation">,</span> //email
<span class="token property">"time"</span><span class="token operator">:</span> <span class="token string">"@datetime"</span> //时间
<span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><h2 class="subject" id="yapiMock跟mockjs区别">yapiMock跟mockjs区别 <a class="hashlink" href="#yapiMock跟mockjs区别">#</a></h2><p>因为yapi基于json定义mock无法使用mockjs原有的函数功能正则表达式需要基于rule书写示例如下</p>
<pre><code><span class="token punctuation">{</span>
"name|regexp"<span class="token operator">:</span> <span class="token string">"[a-z0-9_]+?"</span><span class="token punctuation">,</span>
"type|regexp"<span class="token operator">:</span> "json|text|xml" //枚举数据类型可这样实现
<span class="token punctuation">}</span>
</code></pre><h2 class="subject" id="如何使用Mock?">如何使用Mock? <a class="hashlink" href="#如何使用Mock?">#</a></h2><h3 class="subject" id="1_最简单的方式">1 最简单的方式 <a class="hashlink" href="#1_最简单的方式">#</a></h3><p>在代码直接请求yapi提供的mock地址以jQuery为例</p>
<pre><code class="lang-javascript"><span class="token keyword">let</span> prefix <span class="token operator">=</span> <span class="token string">'http://yapi.local.qunar.com:3000/mock/2817'</span>
$<span class="token punctuation">.</span><span class="token function">post</span><span class="token punctuation">(</span>prefix<span class="token operator">+</span><span class="token string">'/baseapi/path'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>username<span class="token punctuation">:</span> <span class="token string">'xxx'</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//返回上图预览部分的数据</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre>
<h3 class="subject" id="2_基于本地服务器反向代理">2 基于本地服务器反向代理 <a class="hashlink" href="#2_基于本地服务器反向代理">#</a></h3><p>优点:不用修改项目代码</p>
<h4 class="subject" id="2.1_基于nginx反向代理">2.1 基于nginx反向代理 <a class="hashlink" href="#2.1_基于nginx反向代理">#</a></h4><pre><code class="lang-nginx"><span class="token keyword">location</span> <span class="token operator">/</span>baseapi
<span class="token punctuation">{</span>
<span class="token keyword">proxy_pass</span> <span class="token keyword">http</span><span class="token punctuation">:</span><span class="token operator">/</span><span class="token operator">/</span>yapi<span class="token punctuation">.</span>corp<span class="token punctuation">.</span>qunar<span class="token punctuation">.</span>com<span class="token operator">/</span>mock<span class="token operator">/</span><span class="token number">2817</span><span class="token operator">/</span>baseapi<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">#baseapi后面没有"/"</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 class="subject" id="2.2_基于ykit_Jerry代理">2.2 基于ykit Jerry代理 <a class="hashlink" href="#2.2_基于ykit_Jerry代理">#</a></h4><p>假设您本地服务器访问地址是: <a href="http://xxx.com">http://xxx.com</a></p>
<p><img src="./images/ykit.jpg" /></p>
<h2 class="subject" id="Mock语法规范">Mock语法规范 <a class="hashlink" href="#Mock语法规范">#</a></h2><blockquote>
<p>了解更多Mock详情<a href="https://github.com/nuysoft/Mock/wiki/Syntax-Specification">Mock.js 官方文档</a></p>
</blockquote>
<p>Mock.js 的语法规范包括两部分:</p>
<p><a href="#DTD">1. 数据模板定义规范Data Template DefinitionDTD</a></p>
<p><a href="#DPD">2. 数据占位符定义规范Data Placeholder DefinitionDPD</a></p>
<p><span id = "DTD"></span></p>
<h3 class="subject" id="数据模板定义规范Data_Template_DefinitionDTD">数据模板定义规范Data Template DefinitionDTD <a class="hashlink" href="#数据模板定义规范Data_Template_DefinitionDTD">#</a></h3><p>数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值:</p>
<pre><code>// 属性名 name (与生成规则之间用 "|<span class="token string">" 隔开)
// 生成规则 rule生成规则有7种详见下面的生成规则
// 属性值 value可以含有 "</span>@占位符" 同时也指定了最终值的初始值和类型)
'name|rule'<span class="token operator">:</span> value
生成规则:
'name|min-max'<span class="token operator">:</span> value
'name|count'<span class="token operator">:</span> value
'name|min-max.dmin-dmax'<span class="token operator">:</span> value
'name|min-max.dcount'<span class="token operator">:</span> value
'name|count.dmin-dmax'<span class="token operator">:</span> value
'name|count.dcount'<span class="token operator">:</span> value
'name|+step'<span class="token operator">:</span> value
</code></pre><p>下面提供了6种生成规则以及示例包括 String、Number、Boolean、Object、Array</p>
<h3 class="subject" id="1._属性值是字符串_String">1. 属性值是字符串 String <a class="hashlink" href="#1._属性值是字符串_String">#</a></h3><pre><code><span class="token number">1</span>. 'name|min-max'<span class="token operator">:</span> string
通过重复 string 生成一个字符串,重复次数大于等于 min小于等于 max。
<span class="token number">2</span>. 'name|count'<span class="token operator">:</span> string
通过重复 string 生成一个字符串,重复次数等于 count。
</code></pre><h3 class="subject" id="2._属性值是数字_Number">2. 属性值是数字 Number <a class="hashlink" href="#2._属性值是数字_Number">#</a></h3><pre><code><span class="token number">1</span>. 'name|+<span class="token number">1</span>'<span class="token operator">:</span> number
属性值自动加 <span class="token number">1</span>,初始值为 number。
<span class="token number">2</span>. 'name|min-max'<span class="token operator">:</span> number
生成一个大于等于 min、小于等于 max 的整数,属性值 number 只是用来确定类型。
<span class="token number">3</span>. 'name|min-max.dmin-dmax'<span class="token operator">:</span> number
生成一个浮点数,整数部分大于等于 min、小于等于 max小数部分保留 dmin 到 dmax 位。
例如:
Mock.mock(<span class="token punctuation">{</span>
'number1|<span class="token number">1</span>-<span class="token number">100.1</span>-<span class="token number">10</span>'<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
'number2|<span class="token number">123.1</span>-<span class="token number">10</span>'<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
'number3|<span class="token number">123.3</span>'<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
'number4|<span class="token number">123.10</span>'<span class="token operator">:</span> <span class="token number">1.123</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
// =>
<span class="token punctuation">{</span>
<span class="token property">"number1"</span><span class="token operator">:</span> <span class="token number">12.92</span><span class="token punctuation">,</span>
<span class="token property">"number2"</span><span class="token operator">:</span> <span class="token number">123.51</span><span class="token punctuation">,</span>
<span class="token property">"number3"</span><span class="token operator">:</span> <span class="token number">123.777</span><span class="token punctuation">,</span>
<span class="token property">"number4"</span><span class="token operator">:</span> <span class="token number">123.1231091814</span>
<span class="token punctuation">}</span>
</code></pre><h3 class="subject" id="3._属性值是布尔型_Boolean">3. 属性值是布尔型 Boolean <a class="hashlink" href="#3._属性值是布尔型_Boolean">#</a></h3><pre><code><span class="token number">1</span>. 'name|<span class="token number">1</span>'<span class="token operator">:</span> boolean
随机生成一个布尔值,值为 <span class="token boolean">true</span> 的概率是 <span class="token number">1</span>/<span class="token number">2</span>,值为 <span class="token boolean">false</span> 的概率同样是 <span class="token number">1</span>/<span class="token number">2</span>
<span class="token number">2</span>. 'name|min-max'<span class="token operator">:</span> value
随机生成一个布尔值,值为 value 的概率是 min / (min + max<span class="token punctuation">)</span>,值为 !value 的概率是 max / (min + max<span class="token punctuation">)</span>
</code></pre><h3 class="subject" id="4._属性值是对象_Object">4. 属性值是对象 Object <a class="hashlink" href="#4._属性值是对象_Object">#</a></h3><pre><code><span class="token number">1</span>. 'name|count'<span class="token operator">:</span> object
从属性值 object 中随机选取 count 个属性。
<span class="token number">2</span>. 'name|min-max'<span class="token operator">:</span> object
从属性值 object 中随机选取 min 到 max 个属性。
</code></pre><h3 class="subject" id="5._属性值是数组_Array">5. 属性值是数组 Array <a class="hashlink" href="#5._属性值是数组_Array">#</a></h3><pre><code><span class="token number">1</span>. 'name|<span class="token number">1</span>'<span class="token operator">:</span> array
从属性值 array 中随机选取 <span class="token number">1</span> 个元素,作为最终值。
<span class="token number">2</span>. 'name|+<span class="token number">1</span>'<span class="token operator">:</span> array
从属性值 array 中顺序选取 <span class="token number">1</span> 个元素,作为最终值。
<span class="token number">3</span>. 'name|min-max'<span class="token operator">:</span> array
通过重复属性值 array 生成一个新数组,重复次数大于等于 min小于等于 max。
<span class="token number">4</span>. 'name|count'<span class="token operator">:</span> array
通过重复属性值 array 生成一个新数组,重复次数为 count。
</code></pre><p><span id = "DPD"></span></p>
<h3 class="subject" id="数据占位符定义规范Data_Placeholder_DefinitionDPD">数据占位符定义规范Data Placeholder DefinitionDPD <a class="hashlink" href="#数据占位符定义规范Data_Placeholder_DefinitionDPD">#</a></h3><pre><code>占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中。
占位符 的格式为:
@占位符
说明:
<span class="token number">1</span>. 用 @ 来标识其后的字符串是 占位符在YApi提供的Mock输入框在输入“@”后会自动提示占位符。
例如:
name<span class="token operator">:</span> <span class="token punctuation">{</span>
first<span class="token operator">:</span> '@FIRST'<span class="token punctuation">,</span>
middle<span class="token operator">:</span> '@FIRST'<span class="token punctuation">,</span>
last<span class="token operator">:</span> '@LAST'<span class="token punctuation">,</span>
full<span class="token operator">:</span> '@first @middle @last'
<span class="token punctuation">}</span>
// 上面的示例可以得到如下结果:
<span class="token property">"name"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token property">"first"</span><span class="token operator">:</span> <span class="token string">"Charles"</span><span class="token punctuation">,</span>
<span class="token property">"middle"</span><span class="token operator">:</span> <span class="token string">"Brenda"</span><span class="token punctuation">,</span>
<span class="token property">"last"</span><span class="token operator">:</span> <span class="token string">"Lopez"</span><span class="token punctuation">,</span>
<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>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,200 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 使用手册</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="active">
<a href="usage.html">使用手册</a>
</li>
<li class="">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >YApi</h1>
<p class="desc ">高效、易用、功能强大的api管理平台旨在为开发、产品、测试人员提供更优雅的接口管理服务。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="usage-认识 YApi.html">认识 YApi</a>
</li>
<!-- <li > -->
<li >
<a href="usage-创建第一个API.html">创建第一个API</a>
</li>
<!-- <li > -->
<li >
<a href="usage-项目管理.html">项目管理</a>
</li>
<!-- <li > -->
<li >
<a href="usage-接口配置与调试.html">接口配置与调试</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用mock功能.html">使用mock功能</a>
</li>
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="usage-使用测试集.html">使用测试集</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#介绍">介绍</a>
</li>
<li >
<a href="#使用说明">使用说明</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><h2 class="subject" id="使用说明">使用说明 <a class="hashlink" href="#使用说明">#</a></h2>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,231 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 使用手册</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="active">
<a href="usage.html">使用手册</a>
</li>
<li class="">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >YApi</h1>
<p class="desc ">高效、易用、功能强大的api管理平台旨在为开发、产品、测试人员提供更优雅的接口管理服务。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="usage-认识 YApi.html">认识 YApi</a>
</li>
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="usage-创建第一个API.html">创建第一个API</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#获取权限">获取权限</a>
</li>
<li >
<a href="#选择项目">选择项目</a>
</li>
<li >
<a href="#新建接口">新建接口</a>
</li>
</ul>
<!-- <li > -->
<li >
<a href="usage-项目管理.html">项目管理</a>
</li>
<!-- <li > -->
<li >
<a href="usage-接口配置与调试.html">接口配置与调试</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用mock功能.html">使用mock功能</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用测试集.html">使用测试集</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<h3 class="subject" id="如何创建项目?">如何创建项目? <a class="hashlink" href="#如何创建项目?">#</a></h3><p>把大象装进冰箱分几步?三步:把冰箱门打开,把大象装进去,关门,搞定~</p>
<p>新建接口分几步?也是三步:</p>
<ul>
<li><a href="#获取权限">获取权限</a></li><li><a href="#选择项目">找到一个项目</a></li><li><a href="#新建_编辑接口">新建接口</a></li></ul>
<p>搞定~</p>
<h2 class="subject" id="获取权限">获取权限 <a class="hashlink" href="#获取权限">#</a></h2><ul>
<li>登录后查看项目,如果找不到对应分组或项目,需要联系组长获取项目权限。</li></ul>
<h2 class="subject" id="选择项目">选择项目 <a class="hashlink" href="#选择项目">#</a></h2><ul>
<li><p>如果你已经登录,会在首页右侧看到一些项目 (可以在左侧的分组列表切换分组来查看不同分组下的项目)。</p>
</li><li><p>点击一个项目,进入该项目的详情页。</p>
</li></ul>
<blockquote>
<p>如果没有找到项目,请联系组长</p>
</blockquote>
<p><img src="./images/project_list.png" width = "800" style="margin:0px auto;display:block;" alt="图片名称" align=center /></p>
<h2 class="subject" id="新建接口">新建接口 <a class="hashlink" href="#新建接口">#</a></h2><ul>
<li>点击左侧接口分组右侧的菜单按钮,选择 <code>添加接口</code>,或者点击接口列表右上角的 <code>添加接口</code></li></ul>
<p><img src="./images/usage/api_add_btn.png" /></p>
<ul>
<li>选择接口分类,输入接口名称和接口路径,点击 <code>提交</code></li></ul>
<p><img src="./images/usage/api_add_panel.png" /></p>
<blockquote>
<p>如果没有新建项目权限,请联系组长</p>
</blockquote>
<ul>
<li>恭喜你创建了第一个YApi的接口你可以看到在左侧看到接口名称右侧有该接口的信息预览。</li></ul>
<p><img src="./images/usage/api_res.png" /></p>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,208 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 使用手册</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="active">
<a href="usage.html">使用手册</a>
</li>
<li class="">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >YApi</h1>
<p class="desc ">高效、易用、功能强大的api管理平台旨在为开发、产品、测试人员提供更优雅的接口管理服务。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="usage-认识 YApi.html">认识 YApi</a>
</li>
<!-- <li > -->
<li >
<a href="usage-创建第一个API.html">创建第一个API</a>
</li>
<!-- <li > -->
<li >
<a href="usage-项目管理.html">项目管理</a>
</li>
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="usage-接口配置与调试.html">接口配置与调试</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#介绍">介绍</a>
</li>
<li >
<a href="#接口配置">接口配置</a>
</li>
<li >
<a href="#接口调试">接口调试</a>
</li>
</ul>
<!-- <li > -->
<li >
<a href="usage-使用mock功能.html">使用mock功能</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用测试集.html">使用测试集</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<h2 class="subject" id="介绍">介绍 <a class="hashlink" href="#介绍">#</a></h2><h2 class="subject" id="接口配置">接口配置 <a class="hashlink" href="#接口配置">#</a></h2><h4 class="subject" id="4.3_接口编辑">4.3 接口编辑 <a class="hashlink" href="#4.3_接口编辑">#</a></h4><p>添加完接口点击新添加的接口,跳转到接口预览页面,可看到刚才填写的信息。接口的详细信息点击编辑功能进行添加</p>
<h4 class="subject" id="4.4_测试接口">4.4 测试接口 <a class="hashlink" href="#4.4_测试接口">#</a></h4><p>点击运行tab,可进入到接口测试页面,首先安装chrome crossRequest扩展才可正常使用此功能
<img src="./images/interface_run.png" width="800" style="margin:0px auto;display:block;" alt="图片名称" align=center />
点击保存按钮可把当前测试保存到测试集,方便下次调试</p>
<h2 class="subject" id="接口调试">接口调试 <a class="hashlink" href="#接口调试">#</a></h2>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,232 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 使用手册</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="active">
<a href="usage.html">使用手册</a>
</li>
<li class="">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >YApi</h1>
<p class="desc ">高效、易用、功能强大的api管理平台旨在为开发、产品、测试人员提供更优雅的接口管理服务。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<div class="content-left staticsidenav" role="complementary">
<nav class="docs-sidebar hidden-print hidden-xs hidden-sm">
<ul class="nav docs-sidenav">
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="usage-认识 YApi.html">认识 YApi</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#登录与注册">登录与注册</a>
</li>
<li >
<a href="#首页">首页</a>
</li>
<li >
<a href="#项目页">项目页</a>
</li>
<li >
<a href="#个人中心">个人中心</a>
</li>
</ul>
<!-- <li > -->
<li >
<a href="usage-创建第一个API.html">创建第一个API</a>
</li>
<!-- <li > -->
<li >
<a href="usage-项目管理.html">项目管理</a>
</li>
<!-- <li > -->
<li >
<a href="usage-接口配置与调试.html">接口配置与调试</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用mock功能.html">使用mock功能</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用测试集.html">使用测试集</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<p>YApi 是高效、易用、功能强大的api管理平台。
<!-- 它有扁平化的管理结构(`超管`-`组长`-`组员`),有清晰的接口组织方式(`分组`-`项目`-`接口`)有更方便的mock方案。 --></p>
<p>在开始使用 YApi 之前,我们先来熟悉一下 YApi 的网站结构这将让你快速了解YApi。</p>
<h2 class="subject" id="登录与注册">登录与注册 <a class="hashlink" href="#登录与注册">#</a></h2><p>想要使用 YApi 首先要拥有账号目前支持注册账号登录与QSSO登录两种方式。</p>
<p><img src="./images/usage/login.png" /></p>
<h2 class="subject" id="首页">首页 <a class="hashlink" href="#首页">#</a></h2><p>登录后进入首页,首页展示了分组与项目。</p>
<p>此时你作为新用户,没有任何分组与项目的权限,因此只能搜索、浏览 “公开项目” 的接口,如果在首页找不到任何项目,请联系管理员将你加入对应项目。</p>
<p><span class="list-index">1</span>首页头部展示了当前所在的位置、搜索框、新建项目、查看文档和用户信息。</p>
<p><span class="list-index">2</span>首页左侧展示分组信息,“分组”是“项目”的集合,只有超级管理员可以管理分组。</p>
<p><span class="list-index">3</span>首页右侧是分组下的项目和成员列表,点击左侧的某个分组,右侧会出现该分组下的项目和成员信息。</p>
<p><span class="list-index">4</span>点击项目右上角的星星即可关注项目,关注的项目可以在“我的关注”页面查看。</p>
<p><img src="./images/usage/index.png" /></p>
<h2 class="subject" id="项目页">项目页 <a class="hashlink" href="#项目页">#</a></h2><p>点击一个项目,进入项目页,项目页展示了属于该项目的全部接口,并提供项目、接口的全部操作。</p>
<p>此时你作为新用户,只能浏览接口信息,不可以编辑项目或接口,如果需要编辑,请联系管理员将你加入该项目。</p>
<p><span class="list-index">1</span>项目页左侧的 “接口列表” 展示了该项目下的所有接口,右侧默认显示该项目下所有接口的列表。</p>
<p><span class="list-index">2</span>点击左侧的某个接口,右侧会出现“预览”、“编辑”和“运行”。</p>
<p><span class="list-index">3</span>点击左侧的 “测试集合” 使用<a href="./case.html">测试集</a>功能。</p>
<p><span class="list-index">4</span>点击二级导航的“设置”,项目组长即可编辑项目信息和管理成员列表。</p>
<p><span class="list-index">5</span>点击二级导航的“动态”,即可查看项目的操作日志。</p>
<p><img src="./images/usage/project.png" /></p>
<h2 class="subject" id="个人中心">个人中心 <a class="hashlink" href="#个人中心">#</a></h2><p>鼠标移动到右上角的用户头像或用户名上,即可点击“个人中心”查看个人信息。</p>
<p><img src="./images/usage/hover.png" /></p>
<p>在个人信息页面可以查看并修改自己的用户名、密码等信息。</p>
<p><img src="./images/usage/user.png" /></p>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,208 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 使用手册</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="active">
<a href="usage.html">使用手册</a>
</li>
<li class="">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >YApi</h1>
<p class="desc ">高效、易用、功能强大的api管理平台旨在为开发、产品、测试人员提供更优雅的接口管理服务。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="usage-认识 YApi.html">认识 YApi</a>
</li>
<!-- <li > -->
<li >
<a href="usage-创建第一个API.html">创建第一个API</a>
</li>
<!-- <li class="active" class="active" > -->
<li class="active" >
<a href="usage-项目管理.html">项目管理</a>
</li>
<ul class="nav docs-sidenav-extend" >
<li >
<a href="#介绍">介绍</a>
</li>
<li >
<a href="#组长职责">组长职责</a>
</li>
<li >
<a href="#安装_crossRequest_chrome_插件">安装 crossRequest chrome 插件</a>
</li>
<li >
<a href="#权限列表">权限列表</a>
</li>
</ul>
<!-- <li > -->
<li >
<a href="usage-接口配置与调试.html">接口配置与调试</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用mock功能.html">使用mock功能</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用测试集.html">使用测试集</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<h2 class="subject" id="介绍">介绍 <a class="hashlink" href="#介绍">#</a></h2><h2 class="subject" id="组长职责">组长职责 <a class="hashlink" href="#组长职责">#</a></h2><h2 class="subject" id="安装_crossRequest_chrome_插件">安装 crossRequest chrome 插件 <a class="hashlink" href="#安装_crossRequest_chrome_插件">#</a></h2><h2 class="subject" id="权限列表">权限列表 <a class="hashlink" href="#权限列表">#</a></h2>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

View File

@ -1,212 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="description" content="description of your site">
<meta name="author" content="author of the site">
<title>YApi 使用手册</title>
<link rel="stylesheet" href="source/main.css" />
<link rel="stylesheet" href="styles/theme.css" />
</head>
<body>
<div class="ydoc">
<header class="ydoc-header">
<div class="ydoc-header-area">
<a href="http://ued.qunar.com/ymfe/" class="navbar-brand">YMFE</a>
<button class="ydocIcon navbar-toggle">&#xf020;</button>
<nav class="ydoc-nav">
<ul class="navbar-left">
<li class="">
<a href="index.html">首页</a>
</li>
<li class="active">
<a href="usage.html">使用手册</a>
</li>
<li class="">
<a href="manage.html">管理学院</a>
</li>
<li class="">
<a href="api.html"></a>
</li>
</ul>
</nav>
</div>
</header>
<!-- <header style="height:20px"></header> -->
<!-- Docs page layout -->
<div class="ydoc-banner-bg">
<div class="ydoc-banner ">
<div class="ydoc-banner-area">
<h1 >YApi</h1>
<p class="desc ">高效、易用、功能强大的api管理平台旨在为开发、产品、测试人员提供更优雅的接口管理服务。</p>
</div>
</div>
<div class="ydoc-container">
<div class="ydoc-container-content ">
<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="usage-认识 YApi.html">认识 YApi</a>
</li>
<!-- <li > -->
<li >
<a href="usage-创建第一个API.html">创建第一个API</a>
</li>
<!-- <li > -->
<li >
<a href="usage-项目管理.html">项目管理</a>
</li>
<!-- <li > -->
<li >
<a href="usage-接口配置与调试.html">接口配置与调试</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用mock功能.html">使用mock功能</a>
</li>
<!-- <li > -->
<li >
<a href="usage-使用测试集.html">使用测试集</a>
</li>
</ul>
</nav>
</div>
<div class="content-right markdown-body use-sidebar" role="main">
<p>YApi 是高效、易用、功能强大的api管理平台。
<!-- 它有扁平化的管理结构(`超管`-`组长`-`组员`),有清晰的接口组织方式(`分组`-`项目`-`接口`)有更方便的mock方案。 --></p>
<p>在开始使用 YApi 之前,我们先来熟悉一下 YApi 的网站结构这将让你快速了解YApi。</p>
<h2 class="subject" id="登录与注册">登录与注册 <a class="hashlink" href="#登录与注册">#</a></h2><p>想要使用 YApi 首先要拥有账号目前支持注册账号登录与QSSO登录两种方式。</p>
<p><img src="./images/usage/login.png" /></p>
<h2 class="subject" id="首页">首页 <a class="hashlink" href="#首页">#</a></h2><p>登录后进入首页,首页展示了分组与项目。</p>
<p>此时你作为新用户,没有任何分组与项目的权限,因此只能搜索、浏览 “公开项目” 的接口,如果在首页找不到任何项目,请联系管理员将你加入对应项目。</p>
<p><span class="list-index">1</span>首页头部展示了当前所在的位置、搜索框、新建项目、查看文档和用户信息。</p>
<p><span class="list-index">2</span>首页左侧展示分组信息,“分组”是“项目”的集合,只有超级管理员可以管理分组。</p>
<p><span class="list-index">3</span>首页右侧是分组下的项目和成员列表,点击左侧的某个分组,右侧会出现该分组下的项目和成员信息。</p>
<p><span class="list-index">4</span>点击项目右上角的星星即可关注项目,关注的项目可以在“我的关注”页面查看。</p>
<p><img src="./images/usage/index.png" /></p>
<h2 class="subject" id="项目页">项目页 <a class="hashlink" href="#项目页">#</a></h2><p>点击一个项目,进入项目页,项目页展示了属于该项目的全部接口,并提供项目、接口的全部操作。</p>
<p>此时你作为新用户,只能浏览接口信息,不可以编辑项目或接口,如果需要编辑,请联系管理员将你加入该项目。</p>
<p><span class="list-index">1</span>项目页左侧的 “接口列表” 展示了该项目下的所有接口,右侧默认显示该项目下所有接口的列表。</p>
<p><span class="list-index">2</span>点击左侧的某个接口,右侧会出现“预览”、“编辑”和“运行”。</p>
<p><span class="list-index">3</span>点击左侧的 “测试集合” 使用<a href="./case.html">测试集</a>功能。</p>
<p><span class="list-index">4</span>点击二级导航的“设置”,项目组长即可编辑项目信息和管理成员列表。</p>
<p><span class="list-index">5</span>点击二级导航的“动态”,即可查看项目的操作日志。</p>
<p><img src="./images/usage/project.png" /></p>
<h2 class="subject" id="个人中心">个人中心 <a class="hashlink" href="#个人中心">#</a></h2><p>鼠标移动到右上角的用户头像或用户名上,即可点击“个人中心”查看个人信息。</p>
<p><img src="./images/usage/hover.png" /></p>
<p>在个人信息页面可以查看并修改自己的用户名、密码等信息。</p>
<p><img src="./images/usage/user.png" /></p>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="copyright">
&copy; 2016 <a href="http://ued.qunar.com/ymfe/">YMFE</a> Team. Build by <a href="http://ued.qunar.com/ydoc/">ydoc</a>.
</div>
</footer>
</div>
<div class="open-panel"></div>
<div class="mask"></div>
<script src="source/main.js"></script>
<script src="source/app.js"></script>
<script>
var lineHeight = 18;
var EXAMPLE_MAX_HEIGHT;
function fold() {
// 折叠code
$('.markdown-body pre').css({
"line-height": lineHeight + "px"
});
$('.markdown-body pre').map(function(i, item) {
var $item = $(item);
var foldnumber = $item.data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
if ($item.height() > EXAMPLE_MAX_HEIGHT) {
$item.css({
"padding-bottom": 30
});
$item.find('code').height(EXAMPLE_MAX_HEIGHT);
$item.append('<span class="extend">展开更多……</span>');
};
});
$('.ydoc-example').delegate('.extend', 'click', function() {
var $this = $(this);
$this.removeClass('extend').addClass('fold');
$this.html('折叠代码');
$this.parent().children('.js-code').height('auto');
$this.parent().height('auto');
});
$('.ydoc-example').delegate('.fold', 'click', function() {
var $this = $(this);
var foldnumber = $this.parent().data('foldnumber');
EXAMPLE_MAX_HEIGHT = lineHeight * (foldnumber || 6);
$this.removeClass('fold').addClass('extend');
$this.parent().height(EXAMPLE_MAX_HEIGHT); // pre
$this.parent().children('.js-code').height(EXAMPLE_MAX_HEIGHT); // code
$this.html("展开更多……");
});
}
$(document).ready(fold);
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta id="cross-request-sign" charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>YAPI-高效、易用、功能强大的api管理平台</title>
<link rel="icon" type="image/png" sizes="192x192" href="/image/favicon.png">
<script>
document.write('<script src="/prd/assets.js?v=' + Math.random() + '"><\/script>');
</script>
<script>
document.write('<link rel="stylesheet" href="/prd/' + window.WEBPACK_ASSETS['index.js'].css + '" />');
</script>
</head>
<body>
<div id="yapi" style="height: 100%;"></div>
<script>
document.write('<script src="/prd/' + window.WEBPACK_ASSETS['manifest'].js + '"><\/script>');
</script>
<script>
document.write('<script src="/prd/' + window.WEBPACK_ASSETS['lib2'].js + '"><\/script>');
</script>
<script>
document.write('<script src="/prd/' + window.WEBPACK_ASSETS['lib'].js + '"><\/script>');
</script>
<script>
document.write('<script src="/prd/' + window.WEBPACK_ASSETS['index.js'].js + '"><\/script>');
</script>
</body>
</html>

View File

@ -1,73 +0,0 @@
// file_id:2D7ABF69-3BC0-4175-98C9-5C3D5CB00158 -- nerver change this !!
/*
* file: qsso-auth.js
* URL: https://qsso.corp.qunar.com/lib/qsso-auth.js
* written by zhibin.ning
* version: 0.1
*
*/
if (!window['QSSO']) {
var QSSO = (function () {
var AUTH_SERVER = 'https://qsso.corp.qunar.com',
LOGIN_PAGE = '/login.php',
SORRY_PAGE = '/sorry.html';
if (location.hostname.match(/qunar\.ctripgroup\.com$/i)) {
AUTH_SERVER = 'https://qunar.ctripgroup.com/sec/qsso/api';
}
var qualifyURL = function (url, encode) {
var url = url || '';
var ret = location.protocol + '//' + location.host + (url.substr(0,1) === '/' ? '' : location.pathname.match(/.*\//)) + url;
if (encode) {
ret = encodeURIComponent(ret);
}
return ret;
};
var URLStringify = function (o) {
var ret = [];
for (var i in o) {
// ret.push( encodeURIComponent(i) + '=' + encodeURIComponent(o[i]) );
ret.push(i + '=' + o[i]);
}
return ret.join('&');
};
return {
'auth': function (loginURI, opt_ext) {
if (!location.hostname.match(/\.qunar(man|ops)?\.com$|\.qunarman\.com$|qunar\.it$|\.928383\.com$|^928383\.com$|qunar\.ctripgroup\.c(om|n)$|\.ctrip(corp)?\.com$|^opsdata\.me$|\.mofun\.com$/i)) {
location = AUTH_SERVER + SORRY_PAGE + '?host=' + qualifyURL('', true);
return;
}
var ret = qualifyURL(loginURI, true);
var redirectURL = AUTH_SERVER + LOGIN_PAGE + '?ret=' + ret + (opt_ext ? '&ext=' + encodeURIComponent(URLStringify(opt_ext)) : '');
// console.log(redirectURL);
location = redirectURL;
},
'attach': function (eid, loginURI, opt_ext) {
QSSO.login = function() {
QSSO.auth(loginURI, opt_ext);
};
document.getElementById(eid).onclick = QSSO.login;
if (location.hash.match('qsso-auto-login')) {
QSSO.login();
}
}
};
})();
/* todo add QSSO login UI, frame login, etc */
}

View File

@ -1 +0,0 @@
window.WEBPACK_ASSETS = {"index.js":{"js":"index@7c9ffb76697681e3e8c5.js","css":"index@7c9ffb76697681e3e8c5.css"},"lib":{"js":"lib@c8e7cfed4754343d78aa.js"},"lib2":{"js":"lib2@a4c16bcac95ab9006475.js"},"manifest":{"js":"manifest@b67af9f8b578904e66c5.js"}}

View File

@ -1 +0,0 @@
(function(e){function i(t){if(n[t])return n[t].exports;var r=n[t]={exports:{},id:t,loaded:false};e[t].call(r.exports,r,r.exports,i);r.loaded=true;return r.exports}var t=window["webpackJsonp"];window["webpackJsonp"]=function(o,u){var a,f,l=0,c=[];for(;l<o.length;l++){f=o[l];if(r[f])c.push.apply(c,r[f]);r[f]=0}for(a in u){e[a]=u[a]}if(t)t(o,u);while(c.length)c.shift().call(null,i);if(u[0]){n[0]=0;return i(0)}};var n={};var r={3:0};i.e=function(t,n){if(r[t]===0)return n.call(null,i);if(r[t]!==undefined){r[t].push(n)}else{r[t]=[n];var s=document.getElementsByTagName("head")[0];var o=document.createElement("script");o.type="text/javascript";o.charset="utf-8";o.async=true;o.src=i.p+""+t+".chunk.min.js";s.appendChild(o)}};i.m=e;i.c=n;i.p=""})([])

View File

@ -75,10 +75,13 @@
"name": "创建第一个API",
"content": "./doc/page/usage/quickstart.md"
},{
"name": "项目管理",
"name": "管理分组与项目",
"content": "./doc/page/usage/manage.md"
},{
"name": "项目操作",
"content": "./doc/page/usage/project.md"
},{
"name": "接口配置与调试",
"name": "接口操作",
"content": "./doc/page/usage/api.md"
},{
"name": "使用mock功能",