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

This commit is contained in:
wenbo.dong 2017-07-26 15:02:53 +08:00
commit aa59f526d6
26 changed files with 619 additions and 330 deletions

View File

@ -80,4 +80,4 @@ export function fetchInterfaceProject(id) {
type: FETCH_INTERFACE_PROJECT,
payload: axios.get('/project/get', { params: {id}})
}
}
}

View File

@ -174,4 +174,4 @@ export default connect(
checkLoginState,
changeMenuItem
}
)(HeaderCom)
)(HeaderCom)

View File

@ -2,6 +2,7 @@ import './AddInterface.scss'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import axios from 'axios'
import Mock from 'mockjs'
import { connect } from 'react-redux'
import { autobind } from 'core-decorators'
import { Button, Tabs, message } from 'antd'
@ -69,12 +70,18 @@ class AddInterface extends Component {
super(props)
this.state = {
isLoading: '',
isSave: false
isSave: false,
mockJson: ''
}
}
componentDidMount () {
const ifTrue = this.verificationURL()
const initData = [{
id: 0,
name: '',
value: ''
}]
let interfaceId = undefined
if (ifTrue) {
interfaceId = this.getInterfaceId()
@ -85,19 +92,21 @@ class AddInterface extends Component {
props.pushInterfaceName('')
props.getReqParams('')
props.getResParams('')
props.addReqHeader([
{
id: 0,
name: '',
value: ''
}
])
props.addReqHeader(initData)
}
}
getInterfaceId () {
const value = location.hash.match(/\d+/g)
return value ? value[0] : ''
const reg = /AddInterface\/edit\/(\d+)/g
const regTwo = /AddInterface\/(\d+)/g
const url = location.href
if ( url.match(reg) ) {
return RegExp.$1
} else {
url.match(regTwo)
return RegExp.$1
}
}
verificationURL () {
@ -131,6 +140,8 @@ class AddInterface extends Component {
return value
})
this.editState(result)
// 初始化 mock
this.mockData()
})
.catch(e => {
console.log(e)
@ -155,6 +166,21 @@ class AddInterface extends Component {
})
}
@autobind
mockData () { // mock 数据
let resParams = ''
let json = ''
if(this.props.resParams){
resParams = JSON.parse(this.props.resParams)
json = JSON.stringify(Mock.mock(resParams), null, 2)
}
console.log('json', json)
this.setState({
mockJson: json
})
}
@autobind
saveForms () {
let postURL = undefined
@ -166,7 +192,7 @@ class AddInterface extends Component {
path: url,
method: 'POST',
req_headers: seqGroup,
project_id: 558,
project_id: interfaceId,
req_params_type: 'json',
req_params_other: reqParams,
res_body_type: 'json',
@ -187,7 +213,6 @@ class AddInterface extends Component {
this.setLoading()
success()
this.changeState(true)
// this.routerPage()
})
.catch(e => {
console.log(e)
@ -196,22 +221,25 @@ class AddInterface extends Component {
render () {
const TabPane = Tabs.TabPane
const { isLoading, isSave } = this.state
const { isLoading, isSave, mockJson='' } = this.state
console.log('mockJson', mockJson)
return (
<section className="add-interface-box">
<div className="content">
<Tabs defaultActiveKey="1">
<TabPane tab="接口详情" key="1">
<Button type="primary" className="save" onClick={this.saveForms}>保存</Button>
<Button className="mock" onClick={this.mockData}>Mock</Button>
<ReqMethod />
<ReqHeader />
<ReqParams data={this.props} />
<ResParams />
<Result isSave={isSave} />
<Result isSave={isSave} mockJson={mockJson} />
</TabPane>
<TabPane tab="Mock" key="2">mock</TabPane>
<TabPane tab="测试" key="3">
{
// <TabPane tab="Mock" key="2">mock</TabPane>
}
<TabPane tab="请求接口" key="3">
<InterfaceTest />
</TabPane>
</Tabs>

View File

@ -6,7 +6,9 @@
.content {
max-width: 11rem;
margin: 0 auto;
margin: 24px auto;
border-radius: 4px;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
background: #FFF;
padding: 10px 20px 50px 20px;
@ -14,7 +16,12 @@
float: right;
margin: 0 0 10px 0;
}
.mock {
float: right;
margin: 0 15px 0 0;
}
table {
width: 100%;
border-top: 1px #EEE solid;
@ -22,7 +29,7 @@
th {
padding:0 10px;
}
td {
padding: 10px 0;
}
@ -38,7 +45,7 @@
.url {
margin: 0 0 0 15px;
width: 57.8%;
width: 61.2%;
}
}
@ -49,7 +56,7 @@
margin: 0 0 0 10px;
cursor: pointer;
}
/* .req-header.css */
.req-header {
display: -webkit-box;
@ -85,7 +92,7 @@
.req-save, .res-save {
margin: 5px 0 0 107px;
}
/* .req-params.css */
.req-params {
display: -webkit-box;
@ -94,39 +101,46 @@
border-top: 1px #EEE solid;
}
/* .req-save.css */
.res-params {
display: -webkit-box;
line-height: 32px;
padding: 20px 0 0 0;
border-top: 1px #EEE solid;
margin: 20px 0 0 0;
.res-params-box {
display: inline-block;
width: 530px;
float: left;
ul {
-webkit-box-flex: 1;
margin: 0 0 0 24px;
/* .req-save.css */
.res-params {
display: -webkit-box;
line-height: 32px;
padding: 20px 0 0 0;
border-top: 1px #EEE solid;
margin: 20px 0 0 0;
li {
display: -webkit-box;
}
ul {
-webkit-box-flex: 1;
margin: 0 0 0 24px;
.required {
margin: 0 10px 0 20px;
}
li {
display: -webkit-box;
}
.title {
margin: 0 10px;
display: block;
.required {
margin: 0 10px 0 20px;
}
.title {
margin: 0 10px;
display: block;
}
}
}
}
/* Result.css */
.result {
display: -webkit-box;
display: inline-block;
line-height: 32px;
padding: 20px 0 0 0;
border-top: 1px #EEE solid;
margin: 20px 0 0 0;
margin: 0 0 0 20px;
width: 500px;
float: left;
textarea {
width: 100%;
@ -141,10 +155,10 @@
border: 1px #CCC solid;
height: 300px;
overflow-x: hidden;
overflow-y: auto;
overflow-y: auto;
line-height: 1.2;
}
.ant-tabs {
-webkit-box-flex: 1;
}
@ -231,4 +245,4 @@ body {
padding: 0 20px;
background-color: #FFF;
-webkit-box-flex: 1;
}
}

View File

@ -12,6 +12,8 @@ import {
import './InterfaceTest.scss'
const { TextArea } = Input;
@connect(
state => ({
reqParams: state.addInterface.reqParams,
@ -52,9 +54,34 @@ export default class InterfaceTest extends Component {
@autobind
testInterface() {
const { method, url, seqGroup, interfaceProject } = this.props;
const { prd_host, basepath, protocol } = interfaceProject;
const reqParams = JSON.parse(this.props.reqParams);
const headers = {}
let query = {};
if (method === 'GET') {
Object.keys(reqParams).forEach(key => {
const value = typeof reqParams[key] === 'object' ? JSON.stringify(reqParams) : reqParams.toString();
query[key] = value;
})
}
seqGroup.forEach((headerItem) => {
headers[headerItem.name] = headerItem.value;
})
const href = URL.format({
protocol: protocol || 'http',
host: prd_host,
pathname: (basepath + url).replace(/\/+/g, '/'),
query
});
crossRequest({
url: 'http://petstore.swagger.io/v2/swagger.json',
method: 'GET',
url: href,
method,
headers,
data: {
a:1
},
@ -74,7 +101,7 @@ export default class InterfaceTest extends Component {
if (method === 'GET') {
Object.keys(reqParams).forEach(key => {
const value = typeof reqParams[key] === 'object' ? JSON.stringify(reqParams) : reqParams.toString();
const value = typeof reqParams[key] === 'object' ? JSON.stringify(reqParams[key]) : reqParams[key].toString();
query[key] = value;
})
}
@ -82,37 +109,53 @@ export default class InterfaceTest extends Component {
const href = URL.format({
protocol: protocol || 'http',
host: prd_host,
pathname: URL.resolve(basepath, url),
pathname: (basepath + url).replace(/\/+/g, '/'),
query
});
return (
<div>
<div>接口名{interfaceName}</div>
<div>
METHOD: <Input value={method} disabled />
URL: <Input value={href} />
HEADERS: <Input value={JSON.stringify(seqGroup, 2)} />
请求参数
<div>
<div className="interface-test">
<div className="interface-name">{interfaceName}</div>
<div className="req-part">
<div className="req-row method">
METHOD<Input value={method} disabled style={{display: 'inline-block', width: 200}} />
</div>
<div className="req-row url">
URL<Input value={href} style={{display: 'inline-block', width: 800, margin: 10}} />
<Button onClick={this.testInterface} type="primary">发送</Button>
</div>
<div className="req-row headers">
HEADERS
{
Object.keys(reqParams).map((key, index) => {
const value = typeof reqParams[key] === 'object' ? JSON.stringify(reqParams) : reqParams.toString();
seqGroup.map((headerItem, index) => {
return (
<div key={index}>
<Input value={key} style={{display: 'inline-block', width: 200}} />{' = '}
<Input value={value} style={{display: 'inline-block', width: 200}} />
<Input disabled value={headerItem.name} style={{display: 'inline-block', width: 200, margin: 10}} />{' = '}
<Input value={headerItem.value} style={{display: 'inline-block', width: 200, margin: 10}} />
</div>
)
})
}
</div>
<div className="req-row params">
请求参数
{
Object.keys(reqParams).map((key, index) => {
const value = typeof reqParams[key] === 'object' ? JSON.stringify(reqParams[key]) : reqParams[key].toString();
return (
<div key={index}>
<Input disabled value={key} style={{display: 'inline-block', width: 200, margin: 10}} />{' = '}
<Input value={value} style={{display: 'inline-block', width: 200, margin: 10}} />
</div>
)
})
}
</div>
</div>
<Button onClick={this.testInterface}>发送跨域请求</Button>
<div>
<div className="res-part">
返回结果
{JSON.stringify(this.state.res, 2)}
<TextArea value={JSON.stringify(this.state.res, 2)}></TextArea>
</div>
</div>
)

View File

@ -0,0 +1,9 @@
.interface-test {
.interface-name {
font-size: 24px;
margin-bottom: 24px;
}
.req-row {
margin-bottom: 24px;
}
}

View File

@ -77,12 +77,13 @@ class ReqList extends Component {
const propsValue = this.props.value
const Option = Select.Option
const value = propsValue.value
const name = propsValue.name || 'Accept'
const name = propsValue.name || ''
return (
<li>
<em className="title">头部标签</em>
<Select defaultValue={name} style={{ width: 220 }} onChange={this.handleChange} size="large">
<Option value="">选择请求头</Option>
<Option value="Accept">Accept</Option>
<Option value="Accept-Charset">Accept-Charset</Option>
<Option value="Accept-Encoding">Accept-Encoding</Option>

View File

@ -1,63 +1,64 @@
import React, { Component } from 'react'
import { Select, Input } from 'antd'
import PropTypes from 'prop-types'
import { autobind } from 'core-decorators'
import { connect } from 'react-redux'
import { deleteReqParams } from '../../../actions/addInterface.js'
// import React, { Component } from 'react'
// import { Select, Input } from 'antd'
// import PropTypes from 'prop-types'
// import { autobind } from 'core-decorators'
// import { connect } from 'react-redux'
// import { deleteReqParams } from '../../../actions/addInterface.js'
// import json2html from 'json2html'
@connect(
state => {
return {
reqParams: state.addInterface.reqParams
}
},
{
deleteReqParams
}
)
// @connect(
// state => {
// return {
// reqParams: state.addInterface.reqParams
// }
// },
// {
// deleteReqParams
// }
// )
class ParamsList extends Component {
static propTypes = {
reqParams: PropTypes.array,
dataNum: PropTypes.number,
deleteReqParams: PropTypes.func
}
// class ParamsList extends Component {
// static propTypes = {
// reqParams: PropTypes.array,
// dataNum: PropTypes.number,
// deleteReqParams: PropTypes.func
// }
constructor(props) {
super(props)
}
// constructor(props) {
// super(props)
// }
@autobind
deleteReqParams (e) {
let newSeqParams = []
let reqParams = this.props.reqParams
let dataNum = e.target.getAttribute('data-num')
reqParams.map(value => {
if (+dataNum !== value.id) {
newSeqParams.push(value)
}
})
this.props.deleteReqParams(newSeqParams)
}
// @autobind
// deleteReqParams (e) {
// let newSeqParams = []
// let reqParams = this.props.reqParams
// let dataNum = e.target.getAttribute('data-num')
// reqParams.map(value => {
// if (+dataNum !== value.id) {
// newSeqParams.push(value)
// }
// })
// this.props.deleteReqParams(newSeqParams)
// }
render () {
const Option = Select.Option
const dataNum = this.props.dataNum
// render () {
// const Option = Select.Option
// const dataNum = this.props.dataNum
return (
<li>
<Select defaultValue="选填" style={{ width: 'auto' }} onChange={this.handleChange} size="large" className="required">
<Option value="必填">必填</Option>
<Option value="选填">选填</Option>
</Select>
<em className="title">参数名称</em>
<Input placeholder="参数名称" className="name" size="large" />
<em className="title">参数说明</em>
<Input placeholder="参数说明" className="name" size="large" />
<span className="close" onClick={this.deleteReqParams} data-num={dataNum}>×</span>
</li>
)
}
}
// return (
// <li>
// <Select defaultValue="选填" style={{ width: 'auto' }} onChange={this.handleChange} size="large" className="required">
// <Option value="必填">必填</Option>
// <Option value="选填">选填</Option>
// </Select>
// <em className="title">参数名称</em>
// <Input placeholder="参数名称" className="name" size="large" />
// <em className="title">参数说明</em>
// <Input placeholder="参数说明" className="name" size="large" />
// <span className="close" onClick={this.deleteReqParams} data-num={dataNum}>×</span>
// </li>
// )
// }
// }
export default ParamsList
// export default ParamsList

View File

@ -3,7 +3,9 @@ import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import wangEditor from 'wangeditor'
import { getReqParams } from '../../../actions/addInterface.js'
const editor = new wangEditor('#req-cover')
@connect(
state => {
return {
@ -34,20 +36,21 @@ class ReqParams extends Component {
componentDidMount () {
const reg = /(<p>)|(<\/p>)|&nbsp;|(<br>)|\s+/g
let json = ''
editor.customConfig.menus = []
editor.customConfig.onchange = html => {
html = html.replace(reg, '')
this.props.getReqParams(html)
json = html.replace(reg, '')
this.props.getReqParams(json)
}
setTimeout(() => {
this.initParams()
}, 200)
}, 500)
editor.create()
}
render () {
return (
<section>
<section className="req-params-box">
<div className="req-params">
<strong className="req-h3">请求参数 :</strong>
<div id="req-cover"></div>

View File

@ -2,6 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import wangEditor from 'wangeditor'
import { Tabs } from 'antd'
import { getResParams } from '../../../actions/addInterface.js'
const editor = new wangEditor('#res-cover')
@ -38,10 +39,7 @@ class ResParams extends Component {
const reg = /(<p>)|(<\/p>)|&nbsp;|(<br>)|\s+|<div>|<\/div>/g
editor.customConfig.menus = []
editor.customConfig.onchange = html => {
console.log(html)
html = html.match(/{.*}/g)[0]
html = html.replace(reg, '')
console.log(html)
this.props.getResParams(html)
}
setTimeout(() => {
@ -51,12 +49,14 @@ class ResParams extends Component {
}
render () {
const TabPane = Tabs.TabPane
return (
<section>
<div className="res-params">
<strong className="res-h3">返回参数 :</strong>
<div id="res-cover"></div>
</div>
<section className="res-params-box">
<Tabs defaultActiveKey="1">
<TabPane tab="返回参数" key="1">
<div id="res-cover"></div>
</TabPane>
</Tabs>
</section>
)
}

View File

@ -1,6 +1,5 @@
import React, { Component } from 'react'
import { Tabs } from 'antd'
import Mock from 'mockjs'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
@ -17,7 +16,8 @@ class Result extends Component {
static propTypes = {
resParams: PropTypes.string,
reqParams: PropTypes.string,
isSave: PropTypes.bool
isSave: PropTypes.bool,
mockJson: PropTypes.string
}
constructor(props) {
@ -25,21 +25,14 @@ class Result extends Component {
}
render () {
let TabPane = Tabs.TabPane
let resParams = ''
let json = ''
if(this.props.resParams){
resParams = JSON.parse(this.props.resParams)
json = JSON.stringify(Mock.mock(resParams), null, 2)
}
const TabPane = Tabs.TabPane
const { mockJson } = this.props
console.log('mockJson', typeof mockJson, mockJson)
return (
<div className="result">
<strong className="res-h3">返回示例 :</strong>
<Tabs defaultActiveKey="1">
<TabPane tab="成功结果" key="1">
<pre>{json}</pre>
<pre>{mockJson}</pre>
</TabPane>
</Tabs>
</div>

View File

@ -42,10 +42,10 @@ class Interface extends Component {
}
componentWillMount () {
// 558 665 704 743
const interfaceId = this.getInterfaceId()
const params = {
params: {
project_id: 558
project_id: interfaceId
}
}
@ -63,6 +63,13 @@ class Interface extends Component {
})
}
getInterfaceId () {
const reg = /Interface\/(\d+)/g
const url = location.href
url.match(reg)
return RegExp.$1
}
render () {
const { interfaceData, projectMember, modalVisible } = this.props
return (

View File

@ -3,7 +3,9 @@
max-width: 11rem;
display: -webkit-box;
-webkit-box-flex: 1;
margin: 15px auto 0 auto;
margin: 24px auto;
border-radius: 4px;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
font-size: 0.14rem;
background: #FFF;
@ -11,16 +13,16 @@
width: 216px;
line-height: 45px;
background: #f9fafe;
li {
padding: 0 0 0 30px;
color: #344562;
cursor: pointer;
&:hover {
color: #29f;
}
a {
color: #344562;
&:hover {
@ -32,8 +34,8 @@
.interface-table {
-webkit-box-flex: 1;
margin: 0 0 0 20px;
margin: 0 20px;
min-height: 740px;
.ant-table-wrapper table {
font-size: .14rem;
@ -69,4 +71,3 @@
}
}
}

View File

@ -11,16 +11,24 @@ class InterfaceList extends Component {
super(props)
}
getInterfaceId () {
const reg = /Interface\/(\d+)/g
const url = location.href
url.match(reg)
return RegExp.$1
}
render () {
const { projectMember } = this.props
const getInterfaceId = this.getInterfaceId()
console.log(`/AddInterface/${getInterfaceId}`)
return (
<ul className="interface-list">
<li><Link to="/AddInterface">添加接口</Link></li>
<li><Link to={`/AddInterface/${getInterfaceId}`}>添加接口</Link></li>
<li onClick={projectMember}>管理项目成员</li>
</ul>
)
}
}
export default InterfaceList
export default InterfaceList

View File

@ -1,7 +1,8 @@
.group-bar {
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
border-radius: 4px;
.curr-group {
background: #34495E;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
border-radius: 4px 4px 0 0;
padding: 32px 24px;
.curr-group-name {
@ -38,7 +39,7 @@
height: 48px;
min-width: 263px;
padding: 10px 6px;
background: #fff;
background: #eee;
.search {
display: inline-block;
margin-right: 6px;
@ -51,7 +52,7 @@
overflow-x: hidden;
border-bottom: 1px solid #e9e9e9;
padding-bottom: 24px;
border-radius: 0 0 6px 6px;
border-radius: 0 0 4px 4px;
.group-item {
// height: 48px;
// line-height: 48px;

View File

@ -20,8 +20,10 @@
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"copy-webpack-plugin": "^4.0.1",
"core-decorators": "^0.17.0",
"fast-sass-loader": "^1.2.5",
"cross-request": "^1.0.1",
"fs-extra": "^3.0.1",
"json2html": "0.0.8",
"jsoneditor": "^5.9.3",
"jsonwebtoken": "^7.4.1",
"koa": "^2.0.0",

View File

@ -23,6 +23,10 @@ class groupController extends baseController{
*/
async add(ctx) {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
group_name: 'string',
group_desc: 'string'
})
if(this.getRole() !== 'admin'){
return ctx.body = yapi.commons.resReturn(null,401,'没有权限');
}
@ -38,7 +42,7 @@ class groupController extends baseController{
let data = {
group_name: params.group_name,
group_desc: params.group_desc,
uid: '0',
uid: this.getUid(),
add_time: yapi.commons.time(),
up_time: yapi.commons.time()
}
@ -124,6 +128,12 @@ class groupController extends baseController{
return ctx.body = yapi.commons.resReturn(null,401,'没有权限');
}
try{
ctx.request.body = yapi.commons.handleParams(ctx.request.body, {
id: 'number',
group_name: 'string',
group_desc: 'string'
})
var groupInst = yapi.getInst(groupModel);
let id = ctx.request.body.id;
let data = {};

View File

@ -37,6 +37,12 @@ class interfaceController extends baseController{
*/
async add(ctx){
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
title: 'string',
path: 'string',
method: 'string',
desc: 'string'
})
params.method = params.method || 'GET';
params.method = params.method.toUpperCase()
params.res_body_type = params.res_body_type ? params.res_body_type.toLowerCase() : 'json';
@ -159,6 +165,12 @@ class interfaceController extends baseController{
async up(ctx){
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
title: 'string',
path: 'string',
method: 'string',
desc: 'string'
})
params.method = params.method || 'GET';
params.method = params.method.toUpperCase()
let id = ctx.request.body.id;

View File

@ -49,7 +49,14 @@ class projectController extends baseController {
*/
async add(ctx) {
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
name: 'string',
basepath: 'string',
prd_host: 'string',
protocol: 'string',
group_id: 'number',
desc: 'string'
})
if(!params.group_id){
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组id不能为空');
}
@ -322,6 +329,14 @@ class projectController extends baseController {
try{
let id = ctx.request.body.id;
let params = ctx.request.body;
params = yapi.commons.handleParams(params, {
name: 'string',
basepath: 'string',
prd_host: 'string',
protocol: 'string',
group_id: 'number',
desc: 'string'
})
if(!id){
return ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空');
}

View File

@ -241,6 +241,13 @@ class userController extends baseController {
async reg(ctx) { //注册
var 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, '邮箱不能为空');
}
@ -395,6 +402,10 @@ class userController extends baseController {
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,'没有权限');
}

View File

@ -107,14 +107,14 @@ exports.sendMail = (options, cb) => {
}
}
try{
try {
yapi.mail.sendMail({
from: yapi.WEBCONFIG.mail.auth.user,
to: options.to,
subject: 'yapi平台',
html: options.contents
from: yapi.WEBCONFIG.mail.auth.user,
to: options.to,
subject: 'yapi平台',
html: options.contents
}, cb)
}catch(e){
} catch (e) {
console.error(e.message)
}
}
@ -150,4 +150,41 @@ exports.verifyPath = (path) => {
} else {
return false;
}
}
function trim(str) {
if (!str) return str;
str = str + '';
return str.replace(/(^\s*)|(\s*$)/g, "");
}
function ltrim(str) {
if (!str) return str;
str = str + '';
return str.replace(/(^\s*)/g, "");
}
function rtrim(str) {
if (!str) return str;
str = str + '';
return str.replace(/(\s*$)/g, "");
}
exports.trim = trim;
exports.ltrim = ltrim;
exports.rtrim = rtrim;
exports.handleParams = (params, keys) => {
if (!params || typeof params !== 'object' || !keys || typeof keys !== 'object') return false;
for (var key in keys) {
var filter = keys[key];
if (params[key]) {
switch (filter) {
case 'string': params[key] = trim(params[key] + ''); break;
case 'number': params[key] = parseInt(params[key], 10); break;
default: params[key] = trim(params + '');
}
}
}
return params;
}

View File

@ -83,68 +83,73 @@ var groupController = function (_baseController) {
case 0:
params = ctx.request.body;
params = _yapi2.default.commons.handleParams(params, {
group_name: 'string',
group_desc: 'string'
});
if (!(this.getRole() !== 'admin')) {
_context.next = 3;
_context.next = 4;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '没有权限'));
case 3:
case 4:
if (params.group_name) {
_context.next = 5;
_context.next = 6;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目分组名不能为空'));
case 5:
case 6:
groupInst = _yapi2.default.getInst(_group2.default);
_context.next = 8;
_context.next = 9;
return groupInst.checkRepeat(params.group_name);
case 8:
case 9:
checkRepeat = _context.sent;
if (!(checkRepeat > 0)) {
_context.next = 11;
_context.next = 12;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '项目分组名已存在'));
case 11:
case 12:
data = {
group_name: params.group_name,
group_desc: params.group_desc,
uid: '0',
uid: this.getUid(),
add_time: _yapi2.default.commons.time(),
up_time: _yapi2.default.commons.time()
};
_context.prev = 12;
_context.next = 15;
_context.prev = 13;
_context.next = 16;
return groupInst.save(data);
case 15:
case 16:
result = _context.sent;
result = _yapi2.default.commons.fieldSelect(result, ['_id', 'group_name', 'group_desc', 'uid']);
ctx.body = _yapi2.default.commons.resReturn(result);
_context.next = 23;
_context.next = 24;
break;
case 20:
_context.prev = 20;
_context.t0 = _context['catch'](12);
case 21:
_context.prev = 21;
_context.t0 = _context['catch'](13);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context.t0.message);
case 23:
case 24:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[12, 20]]);
}, _callee, this, [[13, 21]]);
}));
function add(_x) {
@ -323,6 +328,13 @@ var groupController = function (_baseController) {
case 2:
_context4.prev = 2;
ctx.request.body = _yapi2.default.commons.handleParams(ctx.request.body, {
id: 'number',
group_name: 'string',
group_desc: 'string'
});
groupInst = _yapi2.default.getInst(_group2.default);
id = ctx.request.body.id;
data = {};
@ -332,28 +344,28 @@ var groupController = function (_baseController) {
if ((0, _keys2.default)(data).length === 0) {
ctx.body = _yapi2.default.commons.resReturn(null, 404, '分组名和分组描述不能为空');
}
_context4.next = 11;
_context4.next = 12;
return groupInst.up(id, data);
case 11:
case 12:
result = _context4.sent;
ctx.body = _yapi2.default.commons.resReturn(result);
_context4.next = 18;
_context4.next = 19;
break;
case 15:
_context4.prev = 15;
case 16:
_context4.prev = 16;
_context4.t0 = _context4['catch'](2);
ctx.body = _yapi2.default.commons.resReturn(null, 402, e.message);
case 18:
case 19:
case 'end':
return _context4.stop();
}
}
}, _callee4, this, [[2, 15]]);
}, _callee4, this, [[2, 16]]);
}));
function up(_x4) {

View File

@ -94,49 +94,55 @@ var interfaceController = function (_baseController) {
case 0:
params = ctx.request.body;
params = _yapi2.default.commons.handleParams(params, {
title: 'string',
path: 'string',
method: 'string',
desc: 'string'
});
params.method = params.method || 'GET';
params.method = params.method.toUpperCase();
params.res_body_type = params.res_body_type ? params.res_body_type.toLowerCase() : 'json';
if (params.project_id) {
_context.next = 6;
_context.next = 7;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目id不能为空'));
case 6:
case 7:
if (params.path) {
_context.next = 8;
_context.next = 9;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '接口请求路径不能为空'));
case 8:
case 9:
if (_yapi2.default.commons.verifyPath(params.path)) {
_context.next = 10;
_context.next = 11;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/'));
case 10:
_context.next = 12;
case 11:
_context.next = 13;
return this.Model.checkRepeat(params.path, params.method);
case 12:
case 13:
checkRepeat = _context.sent;
if (!(checkRepeat > 0)) {
_context.next = 15;
_context.next = 16;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']'));
case 15:
_context.prev = 15;
case 16:
_context.prev = 16;
data = {
project_id: params.project_id,
title: params.title,
@ -156,28 +162,28 @@ var interfaceController = function (_baseController) {
if (params.req_params_form) data.req_params_form = params.req_params_form;
if (params.req_params_other) data.req_params_other = params.req_params_other;
_context.next = 21;
_context.next = 22;
return this.Model.save(data);
case 21:
case 22:
result = _context.sent;
ctx.body = _yapi2.default.commons.resReturn(result);
_context.next = 28;
_context.next = 29;
break;
case 25:
_context.prev = 25;
_context.t0 = _context['catch'](15);
case 26:
_context.prev = 26;
_context.t0 = _context['catch'](16);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context.t0.message);
case 28:
case 29:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[15, 25]]);
}, _callee, this, [[16, 26]]);
}));
function add(_x) {
@ -349,51 +355,57 @@ var interfaceController = function (_baseController) {
case 0:
params = ctx.request.body;
params = _yapi2.default.commons.handleParams(params, {
title: 'string',
path: 'string',
method: 'string',
desc: 'string'
});
params.method = params.method || 'GET';
params.method = params.method.toUpperCase();
id = ctx.request.body.id;
if (id) {
_context4.next = 6;
_context4.next = 7;
break;
}
return _context4.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '接口id不能为空'));
case 6:
_context4.next = 8;
case 7:
_context4.next = 9;
return this.Model.get(id);
case 8:
case 9:
interfaceData = _context4.sent;
if (!(params.path && !_yapi2.default.commons.verifyPath(params.path))) {
_context4.next = 11;
_context4.next = 12;
break;
}
return _context4.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/'));
case 11:
case 12:
if (!(params.path && params.path !== interfaceData.path && params.method !== interfaceData.method)) {
_context4.next = 17;
_context4.next = 18;
break;
}
_context4.next = 14;
_context4.next = 15;
return this.Model.checkRepeat(params.path, params.method);
case 14:
case 15:
checkRepeat = _context4.sent;
if (!(checkRepeat > 0)) {
_context4.next = 17;
_context4.next = 18;
break;
}
return _context4.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']'));
case 17:
case 18:
data = {
up_time: _yapi2.default.commons.time()
};
@ -412,29 +424,29 @@ var interfaceController = function (_baseController) {
if (params.res_body_type) data.res_body_type = params.res_body_type;
if (params.res_body) data.res_body = params.res_body;
_context4.prev = 27;
_context4.next = 30;
_context4.prev = 28;
_context4.next = 31;
return this.Model.up(id, data);
case 30:
case 31:
result = _context4.sent;
ctx.body = _yapi2.default.commons.resReturn(result);
_context4.next = 37;
_context4.next = 38;
break;
case 34:
_context4.prev = 34;
_context4.t0 = _context4['catch'](27);
case 35:
_context4.prev = 35;
_context4.t0 = _context4['catch'](28);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context4.t0.message);
case 37:
case 38:
case 'end':
return _context4.stop();
}
}
}, _callee4, this, [[27, 34]]);
}, _callee4, this, [[28, 35]]);
}));
function up(_x4) {

View File

@ -119,82 +119,91 @@ var projectController = function (_baseController) {
case 0:
params = ctx.request.body;
params = _yapi2.default.commons.handleParams(params, {
name: 'string',
basepath: 'string',
prd_host: 'string',
protocol: 'string',
group_id: 'number',
desc: 'string'
});
if (params.group_id) {
_context.next = 3;
_context.next = 4;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目分组id不能为空'));
case 3:
case 4:
if (params.name) {
_context.next = 5;
_context.next = 6;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目名不能为空'));
case 5:
_context.next = 7;
case 6:
_context.next = 8;
return this.Model.checkNameRepeat(params.name);
case 7:
case 8:
checkRepeat = _context.sent;
if (!(checkRepeat > 0)) {
_context.next = 10;
_context.next = 11;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在的项目名'));
case 10:
case 11:
if (params.basepath) {
_context.next = 12;
_context.next = 13;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目basepath不能为空'));
case 12:
case 13:
if (params.prd_host) {
_context.next = 14;
_context.next = 15;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目domain不能为空'));
case 14:
case 15:
if (!((params.basepath = this.handleBasepath(params.basepath)) === false)) {
_context.next = 16;
_context.next = 17;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, 'basepath格式有误'));
case 16:
case 17:
if (this.verifyDomain(params.prd_host)) {
_context.next = 18;
_context.next = 19;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '线上域名格式有误'));
case 18:
_context.next = 20;
case 19:
_context.next = 21;
return this.Model.checkDomainRepeat(params.prd_host, params.basepath);
case 20:
case 21:
checkRepeatDomain = _context.sent;
if (!(checkRepeatDomain > 0)) {
_context.next = 23;
_context.next = 24;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在domain和basepath'));
case 23:
case 24:
data = {
name: params.name,
desc: params.desc,
@ -207,29 +216,29 @@ var projectController = function (_baseController) {
add_time: _yapi2.default.commons.time(),
up_time: _yapi2.default.commons.time()
};
_context.prev = 24;
_context.next = 27;
_context.prev = 25;
_context.next = 28;
return this.Model.save(data);
case 27:
case 28:
result = _context.sent;
ctx.body = _yapi2.default.commons.resReturn(result);
_context.next = 34;
_context.next = 35;
break;
case 31:
_context.prev = 31;
_context.t0 = _context['catch'](24);
case 32:
_context.prev = 32;
_context.t0 = _context['catch'](25);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context.t0.message);
case 34:
case 35:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[24, 31]]);
}, _callee, this, [[25, 32]]);
}));
function add(_x) {
@ -750,50 +759,59 @@ var projectController = function (_baseController) {
id = ctx.request.body.id;
params = ctx.request.body;
params = _yapi2.default.commons.handleParams(params, {
name: 'string',
basepath: 'string',
prd_host: 'string',
protocol: 'string',
group_id: 'number',
desc: 'string'
});
if (id) {
_context8.next = 5;
_context8.next = 6;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 405, '项目id不能为空'));
case 5:
_context8.next = 7;
case 6:
_context8.next = 8;
return this.jungeMemberAuth(id, this.getUid());
case 7:
case 8:
_context8.t0 = _context8.sent;
if (!(_context8.t0 !== true)) {
_context8.next = 10;
_context8.next = 11;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 405, '没有权限'));
case 10:
_context8.next = 12;
case 11:
_context8.next = 13;
return this.Model.get(id);
case 12:
case 13:
projectData = _context8.sent;
if (!((params.basepath = this.handleBasepath(params.basepath)) === false)) {
_context8.next = 15;
_context8.next = 16;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, 'basepath格式有误'));
case 15:
case 16:
if (this.verifyDomain(params.prd_host)) {
_context8.next = 17;
_context8.next = 18;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '线上域名格式有误'));
case 17:
case 18:
if (projectData.name === params.name) {
delete params.name;
@ -804,43 +822,43 @@ var projectController = function (_baseController) {
}
if (!params.name) {
_context8.next = 25;
_context8.next = 26;
break;
}
_context8.next = 22;
_context8.next = 23;
return this.Model.checkNameRepeat(params.name);
case 22:
case 23:
checkRepeat = _context8.sent;
if (!(checkRepeat > 0)) {
_context8.next = 25;
_context8.next = 26;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在的项目名'));
case 25:
case 26:
if (!(params.basepath && params.prd_host)) {
_context8.next = 31;
_context8.next = 32;
break;
}
_context8.next = 28;
_context8.next = 29;
return this.Model.checkDomainRepeat(params.prd_host, params.basepath);
case 28:
case 29:
checkRepeatDomain = _context8.sent;
if (!(checkRepeatDomain > 0)) {
_context8.next = 31;
_context8.next = 32;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在domain和basepath'));
case 31:
case 32:
data = {
uid: this.getUid(),
up_time: _yapi2.default.commons.time()
@ -856,28 +874,28 @@ var projectController = function (_baseController) {
if (params.protocol) data.protocol = params.protocol;
if (params.env) data.env = params.env;
_context8.next = 39;
_context8.next = 40;
return this.Model.up(id, data);
case 39:
case 40:
result = _context8.sent;
ctx.body = _yapi2.default.commons.resReturn(result);
_context8.next = 46;
_context8.next = 47;
break;
case 43:
_context8.prev = 43;
case 44:
_context8.prev = 44;
_context8.t1 = _context8['catch'](0);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context8.t1.message);
case 46:
case 47:
case 'end':
return _context8.stop();
}
}
}, _callee8, this, [[0, 43]]);
}, _callee8, this, [[0, 44]]);
}));
function up(_x8) {

View File

@ -547,36 +547,42 @@ var userController = function (_baseController) {
userInst = _yapi2.default.getInst(_user2.default);
params = ctx.request.body; //获取请求的参数,检查是否存在用户名和密码
params = _yapi2.default.commons.handleParams(params, {
username: 'string',
password: 'string',
email: 'string'
});
if (params.email) {
_context8.next = 4;
_context8.next = 5;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '邮箱不能为空'));
case 4:
case 5:
if (params.password) {
_context8.next = 6;
_context8.next = 7;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '密码不能为空'));
case 6:
_context8.next = 8;
case 7:
_context8.next = 9;
return userInst.checkRepeat(params.email);
case 8:
case 9:
checkRepeat = _context8.sent;
if (!(checkRepeat > 0)) {
_context8.next = 11;
_context8.next = 12;
break;
}
return _context8.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '该email已经注册'));
case 11:
case 12:
passsalt = _yapi2.default.commons.randStr();
data = {
username: params.username,
@ -591,11 +597,11 @@ var userController = function (_baseController) {
if (!data.username) {
data.username = data.email.substr(0, data.email.indexOf('@'));
}
_context8.prev = 14;
_context8.next = 17;
_context8.prev = 15;
_context8.next = 18;
return userInst.save(data);
case 17:
case 18:
user = _context8.sent;
this.setLoginCookie(user._id, user.passsalt);
@ -612,21 +618,21 @@ var userController = function (_baseController) {
to: user.email,
contents: '<h3>\u4EB2\u7231\u7684\u7528\u6237\uFF1A</h3><p>\u60A8\u597D\uFF0C\u611F\u8C22\u4F7F\u7528YApi,\u60A8\u7684\u8D26\u53F7 ' + params.email + ' \u5DF2\u7ECF\u6CE8\u518C\u6210\u529F</p>'
});
_context8.next = 26;
_context8.next = 27;
break;
case 23:
_context8.prev = 23;
_context8.t0 = _context8['catch'](14);
case 24:
_context8.prev = 24;
_context8.t0 = _context8['catch'](15);
ctx.body = _yapi2.default.commons.resReturn(null, 401, _context8.t0.message);
case 26:
case 27:
case 'end':
return _context8.stop();
}
}
}, _callee8, this, [[14, 23]]);
}, _callee8, this, [[15, 24]]);
}));
function reg(_x9) {
@ -868,25 +874,30 @@ var userController = function (_baseController) {
_context12.prev = 0;
params = ctx.request.body;
params = _yapi2.default.commons.handleParams(params, {
username: 'string',
email: 'string'
});
if (!(this.getRole() !== 'admin' && params.uid != this.getUid())) {
_context12.next = 4;
_context12.next = 5;
break;
}
return _context12.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '没有权限'));
case 4:
case 5:
userInst = _yapi2.default.getInst(_user2.default);
id = params.uid;
if (id) {
_context12.next = 8;
_context12.next = 9;
break;
}
return _context12.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, 'uid不能为空'));
case 8:
case 9:
data = {
up_time: _yapi2.default.commons.time()
@ -899,46 +910,46 @@ var userController = function (_baseController) {
params.email && (data.email = params.email);
if (!data.email) {
_context12.next = 18;
_context12.next = 19;
break;
}
_context12.next = 15;
_context12.next = 16;
return userInst.checkRepeat(data.email);
case 15:
case 16:
checkRepeat = _context12.sent;
if (!(checkRepeat > 0)) {
_context12.next = 18;
_context12.next = 19;
break;
}
return _context12.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '该email已经注册'));
case 18:
_context12.next = 20;
case 19:
_context12.next = 21;
return userInst.update(id, data);
case 20:
case 21:
result = _context12.sent;
ctx.body = _yapi2.default.commons.resReturn(result);
_context12.next = 27;
_context12.next = 28;
break;
case 24:
_context12.prev = 24;
case 25:
_context12.prev = 25;
_context12.t0 = _context12['catch'](0);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context12.t0.message);
case 27:
case 28:
case 'end':
return _context12.stop();
}
}
}, _callee12, this, [[0, 24]]);
}, _callee12, this, [[0, 25]]);
}));
function update(_x13) {

View File

@ -171,4 +171,44 @@ exports.verifyPath = function (path) {
} else {
return false;
}
};
function trim(str) {
if (!str) return str;
str = str + '';
return str.replace(/(^\s*)|(\s*$)/g, "");
}
function ltrim(str) {
if (!str) return str;
str = str + '';
return str.replace(/(^\s*)/g, "");
}
function rtrim(str) {
if (!str) return str;
str = str + '';
return str.replace(/(\s*$)/g, "");
}
exports.trim = trim;
exports.ltrim = ltrim;
exports.rtrim = rtrim;
exports.handleParams = function (params, keys) {
if (!params || (typeof params === 'undefined' ? 'undefined' : (0, _typeof3.default)(params)) !== 'object' || !keys || (typeof keys === 'undefined' ? 'undefined' : (0, _typeof3.default)(keys)) !== 'object') return false;
for (var key in keys) {
var filter = keys[key];
if (params[key]) {
switch (filter) {
case 'string':
params[key] = trim(params[key] + '');break;
case 'number':
params[key] = parseInt(params[key], 10);break;
default:
params[key] = trim(params + '');
}
}
}
return params;
};