Skip to content

Commit

Permalink
1.7.0 多层级支持。
Browse files Browse the repository at this point in the history
  • Loading branch information
herenwei committed Jul 6, 2019
1 parent 7a94eb1 commit 448a648
Show file tree
Hide file tree
Showing 21 changed files with 5,082 additions and 4,911 deletions.
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
yapi二次开发:

多层级 树形结构支持


## YApi 可视化接口管理平台
<p><a target="_blank" href="http://yapi.demo.qunar.com">yapi.demo.qunar.com</a></p>

Expand Down Expand Up @@ -54,7 +49,6 @@ YApi 是<strong>高效</strong>、<strong>易用</strong>、<strong>功能强大
* [rap平台数据导入](https://github.com/wxxcarl/yapi-plugin-import-rap)
* [dingding](https://github.com/zgs225/yapi-plugin-dding) 钉钉机器人推送插件
* [export-docx-data](https://github.com/inceptiongt/Yapi-plugin-export-docx-data) 数据导出docx文档
* [interface-oauth-token](https://github.com/shouldnotappearcalm/yapi-plugin-interface-oauth2-token) 定时自动获取鉴权token的插件

### 代码生成
* [yapi-to-typescript:根据 YApi 的接口定义生成 TypeScript 的请求函数](https://github.com/fjc0k/yapi-to-typescript)
Expand All @@ -63,11 +57,10 @@ YApi 是<strong>高效</strong>、<strong>易用</strong>、<strong>功能强大
### YApi docker部署(非官方)
* [使用 alpine 版 docker 镜像快速部署 yapi](https://www.jianshu.com/p/a97d2efb23c5)
* [docker-yapi](https://github.com/Ryan-Miao/docker-yapi)
* [docker-compose一键部署yapi](https://github.com/jinfeijie/yapi)

### YApi 一些工具
* [mysql服务http工具,可配合做自动化测试](https://github.com/hellosean1025/http-mysql-server)
* [idea 一键上传接口到yapi插件](https://github.com/diwand/YapiIdeaUploadPlugin)
* [idea 一键上传接口到yapi插件](https://github.com/FurionCS/YapiIdeaUploadPlugin)

### YApi 的一些客户
* 去哪儿
Expand Down
2 changes: 1 addition & 1 deletion client/components/Header/Header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
overflow: hidden;
width: 32px;
height: 32px;
line-height: 0;
line-height: 32px;
border-radius: 16px;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { PureComponent as Component } from 'react';
import PropTypes from 'prop-types';
import { Form, Input, Button } from 'antd';
import { Form, Input, TreeSelect, Button, InputNumber } from 'antd';
const FormItem = Form.Item;
function hasErrors(fieldsError) {
return Object.keys(fieldsError).some(field => fieldsError[field]);
Expand All @@ -10,7 +10,8 @@ class AddInterfaceForm extends Component {
form: PropTypes.object,
onSubmit: PropTypes.func,
onCancel: PropTypes.func,
catdata: PropTypes.object
catdata: PropTypes.object,
catlist: PropTypes.array
};
handleSubmit = e => {
e.preventDefault();
Expand All @@ -34,8 +35,40 @@ class AddInterfaceForm extends Component {
}
};

const currentId = this.props.catdata ? this.props.catdata._id + '' || 0 + '' : 0 + ''
const temp = [...this.props.catlist];
temp.forEach(f => {
f.children = temp.filter(g => g.parent_id == f._id);
f.children.forEach(x => {
x.value = x._id + '';
x.title = x.name;
x.selectable = (x._id + '') != currentId
});
});
const treeData = temp.filter(f => f.parent_id == 0);
treeData.forEach(x => {
x.value = x._id + '';
x.title = x.name;
x.selectable = (x._id + '') != currentId
});

treeData.splice(0, 0, {
_id: 0,
value: 0 + '',
title: '空',
selectable: (0 + '') != currentId
});

return (
<Form onSubmit={this.handleSubmit}>
<FormItem {...formItemLayout} label="父级分类">
{getFieldDecorator('parent_id', {
initialValue: this.props.catdata ? this.props.catdata.parent_id + '' || null : 0 + ''
})(
<TreeSelect treeData={treeData}>
</TreeSelect>
)}
</FormItem>
<FormItem {...formItemLayout} label="分类名">
{getFieldDecorator('name', {
rules: [
Expand All @@ -52,6 +85,11 @@ class AddInterfaceForm extends Component {
initialValue: this.props.catdata ? this.props.catdata.desc || null : null
})(<Input placeholder="备注" />)}
</FormItem>
<FormItem {...formItemLayout} label="排序">
{getFieldDecorator('index', {
initialValue: this.props.catdata ? this.props.catdata.index + '' || null : null
})(<InputNumber placeholder="排序(从小到大)" />)}
</FormItem>

<FormItem className="catModalfoot" wrapperCol={{ span: 24, offset: 8 }}>
<Button onClick={this.props.onCancel} style={{ marginRight: '10px' }}>
Expand Down
148 changes: 79 additions & 69 deletions client/containers/Project/Interface/InterfaceList/InterfaceEditForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import constants from '../../../../constants/variable.js';
import { handlePath, nameLengthLimit } from '../../../../common.js';
import { changeEditStatus } from '../../../../reducer/modules/interface.js';
import json5 from 'json5';
import { message, Affix, Tabs, Modal } from 'antd';
import { message, Affix, Tabs, TreeSelect, Modal } from 'antd';
import EasyDragSort from '../../../../components/EasyDragSort/EasyDragSort.js';
import mockEditor from 'client/components/AceEditor/mockEditor';
import AceEditor from 'client/components/AceEditor/AceEditor';
Expand Down Expand Up @@ -289,11 +289,11 @@ class InterfaceEditForm extends Component {
} else if (values.req_body_type === 'json') {
values.req_headers
? values.req_headers.map(item => {
if (item.name === 'Content-Type') {
item.value = 'application/json';
isHavaContentType = true;
}
})
if (item.name === 'Content-Type') {
item.value = 'application/json';
isHavaContentType = true;
}
})
: [];
if (isHavaContentType === false) {
values.req_headers = values.req_headers || [];
Expand Down Expand Up @@ -475,7 +475,7 @@ class InterfaceEditForm extends Component {
}

if (val && val.length > 3) {
val.replace(/\{(.+?)\}/g, function(str, match) {
val.replace(/\{(.+?)\}/g, function (str, match) {
insertParams(match);
});
}
Expand Down Expand Up @@ -787,8 +787,8 @@ class InterfaceEditForm extends Component {

const headerList = this.state.req_headers
? this.state.req_headers.map((item, index) => {
return headerTpl(item, index);
})
return headerTpl(item, index);
})
: [];

const requestBodyList = this.state.req_body_form.map((item, index) => {
Expand All @@ -797,6 +797,26 @@ class InterfaceEditForm extends Component {

const DEMOPATH = '/api/user/{id}';

const temp = [...this.props.cat];
temp.forEach(f => {
f.children = temp.filter(g => g.parent_id == f._id);
f.children.forEach(x => {
x.value = x._id + '';
x.title = x.name;
});
});
const treeData = temp.filter(f => f.parent_id == 0);
treeData.forEach(x => {
x.value = x._id + '';
x.title = x.name;
});

treeData.splice(0, 0, {
_id: 0,
value: 0 + '',
title: '空'
});

return (
<div>
<Modal
Expand Down Expand Up @@ -832,16 +852,8 @@ class InterfaceEditForm extends Component {
{getFieldDecorator('catid', {
initialValue: this.state.catid + '',
rules: [{ required: true, message: '请选择一个分类' }]
})(
<Select placeholder="请选择一个分类">
{this.props.cat.map(item => {
return (
<Option key={item._id} value={item._id + ''}>
{item.name}
</Option>
);
})}
</Select>
})(<TreeSelect treeData={treeData}>
</TreeSelect>
)}
</FormItem>

Expand Down Expand Up @@ -895,7 +907,7 @@ class InterfaceEditForm extends Component {
disabled
value={this.props.basepath}
readOnly
onChange={() => {}}
onChange={() => { }}
style={{ width: '25%' }}
/>
</Tooltip>
Expand Down Expand Up @@ -1106,21 +1118,20 @@ class InterfaceEditForm extends Component {
</Tooltip>
“全局编辑”或 “退出全屏” 请按 F9
</span>
) : (
<ReqBodySchema
onChange={text => {
this.setState({
req_body_other: text
});

if (new Date().getTime() - this.startTime > 1000) {
EditFormContext.props.changeEditStatus(true);
}
}}
isMock={true}
data={req_body_other_use_schema_editor}
/>
)}
) : (<ReqBodySchema
onChange={text => {
this.setState({
req_body_other: text
});

if (new Date().getTime() - this.startTime > 1000) {
EditFormContext.props.changeEditStatus(true);
}
}}
isMock={true}
data={req_body_other_use_schema_editor}
/>
)}
</Col>
<Col>
{!this.props.form.getFieldValue('req_body_is_json_schema') && (
Expand All @@ -1135,25 +1146,25 @@ class InterfaceEditForm extends Component {
</Row>

{this.props.form.getFieldValue('req_body_type') === 'file' &&
this.state.hideTabs.req.body !== 'hide' ? (
<Row className="interface-edit-item">
<Col className="interface-edit-item-other-body">
{getFieldDecorator('req_body_other', {
initialValue: this.state.req_body_other
})(<TextArea placeholder="" autosize={true} />)}
</Col>
</Row>
) : null}
this.state.hideTabs.req.body !== 'hide' ? (
<Row className="interface-edit-item">
<Col className="interface-edit-item-other-body">
{getFieldDecorator('req_body_other', {
initialValue: this.state.req_body_other
})(<TextArea placeholder="" autosize={true} />)}
</Col>
</Row>
) : null}
{this.props.form.getFieldValue('req_body_type') === 'raw' &&
this.state.hideTabs.req.body !== 'hide' ? (
<Row>
<Col>
{getFieldDecorator('req_body_other', {
initialValue: this.state.req_body_other
})(<TextArea placeholder="" autosize={{ minRows: 8 }} />)}
</Col>
</Row>
) : null}
this.state.hideTabs.req.body !== 'hide' ? (
<Row>
<Col>
{getFieldDecorator('req_body_other', {
initialValue: this.state.req_body_other
})(<TextArea placeholder="" autosize={{ minRows: 8 }} />)}
</Col>
</Row>
) : null}
</div>

{/* ----------- Response ------------- */}
Expand Down Expand Up @@ -1219,22 +1230,21 @@ class InterfaceEditForm extends Component {
</span>
,“全局编辑”或 “退出全屏” 请按 <span style={{ fontWeight: '500' }}>F9</span>
</div>
) : (
<div style={{ display: this.state.jsonType === 'tpl' ? 'block' : 'none' }}>
<ResBodySchema
onChange={text => {
this.setState({
res_body: text
});
if (new Date().getTime() - this.startTime > 1000) {
EditFormContext.props.changeEditStatus(true);
}
}}
isMock={true}
data={res_body_use_schema_editor}
/>
</div>
)}
) : (<div style={{ display: this.state.jsonType === 'tpl' ? 'block' : 'none' }}>
<ResBodySchema
onChange={text => {
this.setState({
res_body: text
});
if (new Date().getTime() - this.startTime > 1000) {
EditFormContext.props.changeEditStatus(true);
}
}}
isMock={true}
data={res_body_use_schema_editor}
/>
</div>
)}
{!this.props.form.getFieldValue('res_body_is_json_schema') &&
this.state.jsonType === 'tpl' && (
<AceEditor
Expand Down
40 changes: 26 additions & 14 deletions client/containers/Project/Interface/InterfaceList/InterfaceList.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { PureComponent as Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import axios from 'axios';
import { Table, Button, Modal, message, Tooltip, Select, Icon } from 'antd';
import { Table, Button, Modal, message, Tooltip, TreeSelect, Select, Icon } from 'antd';
import AddInterfaceForm from './AddInterfaceForm';
import {
fetchInterfaceListMenu,
Expand Down Expand Up @@ -239,20 +239,32 @@ class InterfaceList extends Component {
key: 'catid',
width: 28,
render: (item, record) => {
const temp = [...this.props.catList];
temp.forEach(f => {
f.children = temp.filter(g => g.parent_id == f._id);
f.children.forEach(x => {
x.value = x._id + '';
x.title = x.name;
x.selectable = (x._id + '') != item + ''
});
});
const treeData = temp.filter(f => f.parent_id == 0);
treeData.forEach(x => {
x.value = x._id + '';
x.title = x.name;
x.selectable = (x._id + '') != item + ''
});

treeData.splice(0, 0, {
_id: 0,
value: 0 + '',
title: '空',
selectable: (0 + '') != item + ''
});

return (
<Select
value={item + ''}
className="select path"
onChange={catid => this.changeInterfaceCat(record._id, catid)}
>
{this.props.catList.map(cat => {
return (
<Option key={cat.id + ''} value={cat._id + ''}>
<span>{cat.name}</span>
</Option>
);
})}
</Select>
<TreeSelect className="select path" treeData={treeData} onChange={catid => this.changeInterfaceCat(record._id, catid)} value={item + ''}>
</TreeSelect>
);
}
},
Expand Down
Loading

0 comments on commit 448a648

Please sign in to comment.