mirror of
https://github.com/YMFE/yapi.git
synced 2025-04-12 15:10:23 +08:00
docs: opti docs
This commit is contained in:
parent
47ea68206e
commit
25cc70f655
18
README.md
18
README.md
@ -1,13 +1,23 @@
|
||||
## YApi
|
||||
|
||||
### 一、平台介绍
|
||||
<img src="./doc/images/yapi-base-flow.jpg" width = "500" style="margin:0px auto;display:block;" alt="图片名称" align=center />
|
||||
<img src="http://ov2tuszjv.bkt.clouddn.com/yapi-flow-base.png" width = "500" style="margin:0px auto;display:block;" alt="图片名称" align=center />
|
||||
<p style='text-indent:2em;line-height:1.8em'>YApi是<strong>高效</strong>、<strong>易用</strong>、<strong>功能强大</strong>的api管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API,YApi还为用户提供了优秀的交互体验,开发人员只需利用平台提供的接口数据写入工具以及简单的点击操作就可以实现接口的管理。</p>
|
||||
|
||||
### 二、为什么使用 YApi
|
||||
1. 基于 Json5 和 Mockjs 定义接口返回数据的结构和文档,效率提升多倍
|
||||
2. 扁平化权限设计,即保证了企业级项目管理,又保证了易用性
|
||||
3. 不仅有类似postman的接口调试功能,还可将每次测试接口保存成一个测试用例到测试集,在测试集可一次性测试该测试集下所有测试用例返回结果格式
|
||||
4. 免费开源
|
||||
2. 扁平化权限设计,即保证了大型企业级项目的管理,又保证了易用性
|
||||
3. 不仅有类似postman的接口调试,还有强大的测试集功能
|
||||
4. 免费开源,内网部署,信息再也不怕泄露了!
|
||||
|
||||
### 三、部署
|
||||
|
||||
首先在在服务器安装nodejs, mongodb, npm, git
|
||||
|
||||
1. git clone
|
||||
2. npm install
|
||||
3. 初次安装需要执行npm run install-server
|
||||
4. npm run server
|
||||
|
||||
|
||||
|
||||
|
@ -1,3 +1,28 @@
|
||||
export default {
|
||||
PAGE_LIMIT: 10 // 默认每页展示10条数据
|
||||
PAGE_LIMIT: 10, // 默认每页展示10条数据
|
||||
HTTP_METHOD: {
|
||||
'GET': {
|
||||
request_body: false
|
||||
},
|
||||
'POST': {
|
||||
request_body: true
|
||||
},
|
||||
'PUT': {
|
||||
request_body: true
|
||||
},
|
||||
'DELETE': {
|
||||
request_body: true
|
||||
},
|
||||
'HEAD': {
|
||||
request_body: false
|
||||
},
|
||||
'OPTIONS': {
|
||||
request_body: false
|
||||
},
|
||||
'PATCH': {
|
||||
request_body: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,11 +1,18 @@
|
||||
import React,{Component} from 'react'
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Form, Input, Select, Button } from 'antd';
|
||||
|
||||
import constants from '../../../../constants/variable.js'
|
||||
const HTTP_METHOD = constants.HTTP_METHOD;
|
||||
const HTTP_METHOD_KEYS = Object.keys(HTTP_METHOD);
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option;
|
||||
function hasErrors(fieldsError) {
|
||||
return Object.keys(fieldsError).some(field => fieldsError[field]);
|
||||
}
|
||||
|
||||
|
||||
class AddInterfaceForm extends Component {
|
||||
static propTypes = {
|
||||
form: PropTypes.object,
|
||||
@ -23,7 +30,7 @@ class AddInterfaceForm extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { getFieldDecorator, getFieldsError } = this.props.form;
|
||||
@ -31,12 +38,11 @@ class AddInterfaceForm extends Component {
|
||||
initialValue: 'GET'
|
||||
})(
|
||||
<Select style={{ width: 75 }}>
|
||||
<Option value="GET">GET</Option>
|
||||
<Option value="POST">POST</Option>
|
||||
<Option value="PUT">PUT</Option>
|
||||
<Option value="DELETE">DELETE</Option>
|
||||
{HTTP_METHOD_KEYS.map(item => {
|
||||
return <Option key={item} value={item}>{item}</Option>
|
||||
})}
|
||||
</Select>
|
||||
);
|
||||
);
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
@ -47,10 +53,10 @@ class AddInterfaceForm extends Component {
|
||||
sm: { span: 14 }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
|
||||
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
@ -62,7 +68,7 @@ class AddInterfaceForm extends Component {
|
||||
}]
|
||||
})(
|
||||
<Input placeholder="接口名称" />
|
||||
)}
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
@ -75,11 +81,11 @@ class AddInterfaceForm extends Component {
|
||||
}]
|
||||
})(
|
||||
<Input addonBefore={prefixSelector} placeholder="/path" />
|
||||
)}
|
||||
)}
|
||||
</FormItem>
|
||||
<br />
|
||||
<FormItem wrapperCol={{ span: 24, offset: 8 }} >
|
||||
<Button onClick={this.props.onCancel} style={{marginRight: "10px"}} >取消</Button>
|
||||
<Button onClick={this.props.onCancel} style={{ marginRight: "10px" }} >取消</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
@ -88,7 +94,7 @@ class AddInterfaceForm extends Component {
|
||||
提交
|
||||
</Button>
|
||||
</FormItem>
|
||||
|
||||
|
||||
</Form>
|
||||
|
||||
);
|
||||
|
@ -3,8 +3,11 @@
|
||||
.interface-edit-item{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.interface-edit-item-content{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.interface-edit-del-icon{
|
||||
margin-top: 4px;
|
||||
margin-top: 10px;
|
||||
margin-left: 5px;
|
||||
cursor: pointer
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import _ from 'underscore'
|
||||
import constants from '../../../../constants/variable.js'
|
||||
|
||||
import {
|
||||
Form, Select, Input,Tooltip,
|
||||
Form, Select, Input, Tooltip,
|
||||
Button, Row, Col, Radio, Icon
|
||||
} from 'antd';
|
||||
|
||||
@ -14,11 +15,13 @@ const RadioGroup = Radio.Group;
|
||||
const dataTpl = {
|
||||
req_query: { name: "", required: "1", desc: "" },
|
||||
req_headers: { name: "", required: "1", desc: "" },
|
||||
req_params: { name: "", desc: "" }
|
||||
req_params: { name: "", desc: "" },
|
||||
req_body_form: {name: "", type: "text", required: "1", desc: ""}
|
||||
}
|
||||
|
||||
const mockEditor = require('./mockEditor.js');
|
||||
|
||||
const HTTP_METHOD = constants.HTTP_METHOD;
|
||||
const HTTP_METHOD_KEYS = Object.keys(HTTP_METHOD);
|
||||
|
||||
class InterfaceEditForm extends Component {
|
||||
static propTypes = {
|
||||
@ -103,9 +106,14 @@ class InterfaceEditForm extends Component {
|
||||
})
|
||||
}
|
||||
}
|
||||
values.req_headers = values.req_headers.filter((item) => item.name !== '')
|
||||
values.req_body_form = values.req_body_form.filter((item) => item.name !== '')
|
||||
values.req_params = values.req_params.filter(item => item.name !== '')
|
||||
values.req_headers = values.req_headers ?values.req_headers.filter((item) => item.name !== '') : []
|
||||
values.req_body_form = values.req_body_form ? values.req_body_form.filter((item) => item.name !== ''): []
|
||||
values.req_params = values.req_params ? values.req_params.filter(item => item.name !== ''): []
|
||||
values.req_query = values.req_query ? values.req_query.filter(item => item.name !== ''): []
|
||||
|
||||
if(HTTP_METHOD[values.method].request_body !== true){
|
||||
values.req_params = []
|
||||
}
|
||||
this.props.onSubmit(values)
|
||||
}
|
||||
});
|
||||
@ -184,10 +192,9 @@ class InterfaceEditForm extends Component {
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 18 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
const queryTpl = (data, index) => {
|
||||
return <Row key={index}>
|
||||
return <Row key={index} className="interface-edit-item-content">
|
||||
<Col span="4">
|
||||
{getFieldDecorator('req_query[' + index + '].name', {
|
||||
initialValue: data.name
|
||||
@ -220,7 +227,7 @@ class InterfaceEditForm extends Component {
|
||||
}
|
||||
|
||||
const headerTpl = (data, index) => {
|
||||
return <Row key={index}>
|
||||
return <Row key={index} className="interface-edit-item-content">
|
||||
<Col span="4">
|
||||
{getFieldDecorator('req_headers[' + index + '].name', {
|
||||
initialValue: data.name
|
||||
@ -250,7 +257,7 @@ class InterfaceEditForm extends Component {
|
||||
}
|
||||
|
||||
const requestBodyTpl = (data, index) => {
|
||||
return <Row key={index}>
|
||||
return <Row key={index} className="interface-edit-item-content">
|
||||
<Col span="8">
|
||||
{getFieldDecorator('req_body_form[' + index + '].name', {
|
||||
initialValue: data.name
|
||||
@ -282,7 +289,7 @@ class InterfaceEditForm extends Component {
|
||||
}
|
||||
|
||||
const paramsTpl = (data, index) => {
|
||||
return <Row key={index}>
|
||||
return <Row key={index} className="interface-edit-item-content">
|
||||
<Col span="6">
|
||||
{getFieldDecorator('req_params[' + index + '].name', {
|
||||
initialValue: data.name
|
||||
@ -342,7 +349,7 @@ class InterfaceEditForm extends Component {
|
||||
label="选择分类"
|
||||
>
|
||||
{getFieldDecorator('catid', {
|
||||
initialValue: _.find(this.props.cat, item=> item._id === this.state.catid).name,
|
||||
initialValue: _.find(this.props.cat, item => item._id === this.state.catid).name,
|
||||
rules: [
|
||||
{ required: true, message: '请选择一个分类' }
|
||||
]
|
||||
@ -362,10 +369,9 @@ class InterfaceEditForm extends Component {
|
||||
>
|
||||
<InputGroup compact>
|
||||
<Select value={this.state.method} onChange={val => this.setState({ method: val })} style={{ width: "15%" }}>
|
||||
<Option value="GET">GET</Option>
|
||||
<Option value="POST">POST</Option>
|
||||
<Option value="PUT">PUT</Option>
|
||||
<Option value="DELETE">DELETE</Option>
|
||||
{HTTP_METHOD_KEYS.map(item => {
|
||||
return <Option key={item} value={item}>{item}</Option>
|
||||
})}
|
||||
</Select>
|
||||
|
||||
<Tooltip title="接口基本路径,可在项目配置里修改">
|
||||
@ -445,42 +451,44 @@ class InterfaceEditForm extends Component {
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
{HTTP_METHOD[this.state.method].request_body ? <div >
|
||||
<FormItem
|
||||
className="interface-edit-item"
|
||||
{...formItemLayout}
|
||||
label="请求Body"
|
||||
>
|
||||
{getFieldDecorator('req_body_type', {
|
||||
initialValue: this.state.req_body_type
|
||||
})(
|
||||
<RadioGroup>
|
||||
<Radio value="form">form</Radio>
|
||||
<Radio value="json">json</Radio>
|
||||
<Radio value="file">file</Radio>
|
||||
<Radio value="raw">raw</Radio>
|
||||
</RadioGroup>
|
||||
)}
|
||||
|
||||
<FormItem
|
||||
className="interface-edit-item"
|
||||
{...formItemLayout}
|
||||
label="请求Body"
|
||||
>
|
||||
{getFieldDecorator('req_body_type', {
|
||||
initialValue: this.state.req_body_type
|
||||
})(
|
||||
<RadioGroup>
|
||||
<Radio value="form">form</Radio>
|
||||
<Radio value="json">json</Radio>
|
||||
<Radio value="file">file</Radio>
|
||||
<Radio value="raw">raw</Radio>
|
||||
</RadioGroup>
|
||||
)}
|
||||
</FormItem>
|
||||
{this.props.form.getFieldValue('req_body_type') === 'form' ?
|
||||
<Row className="interface-edit-item">
|
||||
<Col span={18} offset={4} style={{ minHeight: "50px" }}>
|
||||
<Row>
|
||||
<Col span="24" className="interface-edit-item">
|
||||
|
||||
</FormItem>
|
||||
{this.props.form.getFieldValue('req_body_type') === 'form' ?
|
||||
<Row className="interface-edit-item">
|
||||
<Col span={18} offset={4} style={{ minHeight: "50px" }}>
|
||||
<Row>
|
||||
<Col span="24" className="interface-edit-item">
|
||||
<Button size="small" type="primary" onClick={() => this.addParams('req_body_form')}>添加form参数</Button>
|
||||
|
||||
<Button size="small" type="primary" onClick={() => this.addParams('req_body_form')}>添加form参数</Button>
|
||||
</Col>
|
||||
|
||||
</Col>
|
||||
</Row>
|
||||
{requestBodyList}
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
{requestBodyList}
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
:
|
||||
null
|
||||
}
|
||||
</Row>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
: null}
|
||||
|
||||
|
||||
<Row className="interface-edit-item" style={{ display: this.props.form.getFieldValue('req_body_type') === 'json' ? 'block' : 'none' }}>
|
||||
|
@ -208,7 +208,7 @@ class InterfaceMenu extends Component {
|
||||
case 'POST': color = "blue"; break;
|
||||
case 'PUT': color = "yellow"; break;
|
||||
case 'DELETE': color = 'red'; break;
|
||||
default: color = "green";
|
||||
default: color = "yellow";
|
||||
}
|
||||
return <TreeNode
|
||||
title={<div onMouseEnter={() => this.enterItem(item._id)} onMouseLeave={this.leaveItem} >
|
||||
|
@ -6,6 +6,7 @@
|
||||
"scripts": {
|
||||
"build-server": "babel server -d server_dist",
|
||||
"dev-server": "nodemon server_dist/app.js dev -L",
|
||||
"server": "node server_dist/app.js",
|
||||
"install-server": "node server_dist/install.js",
|
||||
"dev": "gulp --silent",
|
||||
"build": "gulp build --silent",
|
||||
|
Loading…
x
Reference in New Issue
Block a user