mirror of
https://github.com/YMFE/yapi.git
synced 2024-12-15 05:10:47 +08:00
Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev
This commit is contained in:
commit
9bbec027ce
@ -2,6 +2,7 @@ import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Row, Col, Tabs } from 'antd';
|
||||
import { Route, Switch, matchPath } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import './interface.scss'
|
||||
|
||||
@ -40,12 +41,19 @@ InterfaceRoute.propTypes = {
|
||||
match: PropTypes.object
|
||||
}
|
||||
|
||||
|
||||
@connect(
|
||||
state => {
|
||||
return {
|
||||
isShowCol: state.interfaceCol.isShowCol
|
||||
}
|
||||
}
|
||||
)
|
||||
class Interface extends Component {
|
||||
static propTypes = {
|
||||
match: PropTypes.object,
|
||||
history: PropTypes.object,
|
||||
location: PropTypes.object
|
||||
location: PropTypes.object,
|
||||
isShowCol: PropTypes.bool
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
@ -57,6 +65,9 @@ class Interface extends Component {
|
||||
|
||||
onChange = (action) => {
|
||||
let params = this.props.match.params;
|
||||
if(action === 'colOrCase') {
|
||||
action = this.props.isShowCol ? 'col' : 'case';
|
||||
}
|
||||
this.props.history.push('/project/' + params.id + '/interface/' + action)
|
||||
}
|
||||
|
||||
@ -67,7 +78,7 @@ class Interface extends Component {
|
||||
<Row gutter={16} >
|
||||
<Col span={6}>
|
||||
<div className="left-menu">
|
||||
<Tabs type="card" activeKey={activeKey} onChange={() => this.onChange(action)}>
|
||||
<Tabs type="card" activeKey={activeKey} onChange={this.onChange}>
|
||||
<Tabs.TabPane tab="接口列表" key="api">
|
||||
<InterfaceMenu router={matchPath(this.props.location.pathname, contentRouter)} projectId={this.props.match.params.id} />
|
||||
</Tabs.TabPane>
|
||||
|
@ -24,7 +24,8 @@ class InterfaceEdit extends Component {
|
||||
curdata: PropTypes.object,
|
||||
currProject: PropTypes.object,
|
||||
updateInterfaceData: PropTypes.func,
|
||||
match: PropTypes.object
|
||||
match: PropTypes.object,
|
||||
switchToView: PropTypes.func
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
@ -43,6 +44,7 @@ class InterfaceEdit extends Component {
|
||||
if (result.data.errcode === 0) {
|
||||
this.props.updateInterfaceData(params);
|
||||
message.success('保存成功');
|
||||
this.props.switchToView()
|
||||
} else {
|
||||
message.success(result.data.errmsg)
|
||||
}
|
||||
@ -85,7 +87,7 @@ class InterfaceEdit extends Component {
|
||||
render() {
|
||||
return <div className="interface-edit">
|
||||
{this.state.status === 1 ?
|
||||
<InterfaceEditForm mockUrl={this.state.mockUrl} basepath={this.props.currProject.basepath} onSubmit={this.onSubmit} curdata={this.state.curdata} />
|
||||
<InterfaceEditForm cat={this.props.currProject.cat} mockUrl={this.state.mockUrl} basepath={this.props.currProject.basepath} onSubmit={this.onSubmit} curdata={this.state.curdata} />
|
||||
:
|
||||
null}
|
||||
{
|
||||
|
@ -59,6 +59,12 @@ class Content extends Component {
|
||||
})
|
||||
}
|
||||
|
||||
switchToView = ()=>{
|
||||
this.setState({
|
||||
curtab: 'view'
|
||||
})
|
||||
}
|
||||
|
||||
onChange = (key) => {
|
||||
this.setState({
|
||||
curtab: key
|
||||
@ -81,7 +87,7 @@ class Content extends Component {
|
||||
if (this.state.curtab === 'view') {
|
||||
tabContent = <View />;
|
||||
} else if (this.state.curtab === 'edit') {
|
||||
tabContent = <Edit />
|
||||
tabContent = <Edit switchToView={this.switchToView} />
|
||||
} else if (this.state.curtab === 'run') {
|
||||
tabContent = <Run />
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ class InterfaceEditForm extends Component {
|
||||
curdata: PropTypes.object,
|
||||
mockUrl: PropTypes.string,
|
||||
onSubmit: PropTypes.func,
|
||||
basepath: PropTypes.string
|
||||
basepath: PropTypes.string,
|
||||
cat: PropTypes.array
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
@ -102,10 +103,9 @@ 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.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 !== '')
|
||||
this.props.onSubmit(values)
|
||||
}
|
||||
});
|
||||
@ -337,6 +337,24 @@ class InterfaceEditForm extends Component {
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="选择分类"
|
||||
>
|
||||
{getFieldDecorator('catid', {
|
||||
initialValue: _.find(this.props.cat, item=> item._id === this.state.catid).name,
|
||||
rules: [
|
||||
{ required: true, message: '请选择一个分类' }
|
||||
]
|
||||
})(
|
||||
<Select placeholder="请选择一个分类">
|
||||
{this.props.cat.map(item => {
|
||||
return <Option key={item._id} value={item._id + ""} >{item.name}</Option>
|
||||
})}
|
||||
</Select>
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
className="interface-edit-item"
|
||||
{...formItemLayout}
|
||||
|
@ -1,34 +1,44 @@
|
||||
import React,{Component} from 'react'
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types'
|
||||
import axios from 'axios'
|
||||
import {
|
||||
Table
|
||||
Table, Tag
|
||||
} from 'antd';
|
||||
class InterfaceList extends Component{
|
||||
constructor(props){
|
||||
import { formatTime } from '../../../../common.js'
|
||||
|
||||
@connect(
|
||||
state => {
|
||||
return {
|
||||
curProject: state.project.currProject
|
||||
}
|
||||
})
|
||||
class InterfaceList extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
data : [],
|
||||
data: [],
|
||||
sortedInfo: {
|
||||
order: 'descend',
|
||||
order: 'ascend',
|
||||
columnKey: 'title'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
match: PropTypes.object
|
||||
match: PropTypes.object,
|
||||
curProject: PropTypes.object
|
||||
}
|
||||
|
||||
handleRequest = async (props)=>{
|
||||
const {params} = props.match;
|
||||
if(!params.actionId){
|
||||
handleRequest = async (props) => {
|
||||
const { params } = props.match;
|
||||
if (!params.actionId) {
|
||||
let projectId = params.id;
|
||||
let r = await axios.get('/api/interface/list?project_id=' + projectId);
|
||||
this.setState({
|
||||
data: r.data.data
|
||||
})
|
||||
}else if(isNaN(params.actionId)){
|
||||
} else if (isNaN(params.actionId)) {
|
||||
let catid = params.actionId.substr(4)
|
||||
let r = await axios.get('/api/interface/list_cat?catid=' + catid);
|
||||
this.setState({
|
||||
@ -43,51 +53,79 @@ class InterfaceList extends Component{
|
||||
});
|
||||
}
|
||||
|
||||
componentWillMount(){
|
||||
componentWillMount() {
|
||||
this.actionId = this.props.match.params.actionId;
|
||||
this.handleRequest(this.props)
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps){
|
||||
componentWillReceiveProps(nextProps) {
|
||||
let _actionId = nextProps.match.params.actionId;
|
||||
if(this.actionId !== _actionId){
|
||||
this.actionId = _actionId;
|
||||
if (this.actionId !== _actionId) {
|
||||
this.actionId = _actionId;
|
||||
this.handleRequest(nextProps)
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
render() {
|
||||
let { sortedInfo } = this.state;
|
||||
sortedInfo = sortedInfo || {};
|
||||
const columns = [{
|
||||
title: '接口名称',
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
sorter: (a, b) => b.title.length - a.title.length,
|
||||
sorter: (a, b) => {
|
||||
return a.title.localeCompare(b.title) === 1
|
||||
},
|
||||
sortOrder: sortedInfo.columnKey === 'title' && sortedInfo.order
|
||||
},{
|
||||
title: '接口URL',
|
||||
}, {
|
||||
title: '接口路径',
|
||||
dataIndex: 'path',
|
||||
key: 'path'
|
||||
},{
|
||||
key: 'path',
|
||||
render: (item)=>{
|
||||
return <span>{this.props.curProject.basepath + item}</span>
|
||||
}
|
||||
}, {
|
||||
title: '请求方式',
|
||||
dataIndex: 'method',
|
||||
key: 'method'
|
||||
},{
|
||||
}, {
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
render: (item) => {
|
||||
return <div>{item === 'done' ?
|
||||
<Tag color="#87d068">完成</Tag>
|
||||
:
|
||||
<Tag color="#f50">未完成</Tag>
|
||||
}</div>
|
||||
},
|
||||
filters: [{
|
||||
text: '完成',
|
||||
value: 'done'
|
||||
}, {
|
||||
text: '未完成',
|
||||
value: 'undone'
|
||||
}],
|
||||
onFilter: (value, record) => record.status.indexOf(value) === 0
|
||||
}, {
|
||||
title: '更新日期',
|
||||
dataIndex: 'add_time',
|
||||
key: 'add_time'
|
||||
dataIndex: 'up_time',
|
||||
key: 'up_time',
|
||||
render: (item) => {
|
||||
return <span>{formatTime(item)}</span>
|
||||
}
|
||||
}]
|
||||
|
||||
const data = this.state.data.map(item=>{
|
||||
const data = this.state.data.map(item => {
|
||||
item.key = item._id;
|
||||
return item;
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<section className="interface-table">
|
||||
<Table size="small" pagination={false} bordered={true} columns={columns} onChange={this.handleChange} dataSource={data} />
|
||||
</section>
|
||||
<div style={{padding:"15px"}}>
|
||||
<h2 style={{marginBottom: '10px'}}>接口列表</h2>
|
||||
<Table pagination={false} columns={columns} onChange={this.handleChange} dataSource={data} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ const TreeNode = Tree.TreeNode;
|
||||
return {
|
||||
list: state.inter.list,
|
||||
inter: state.inter.curdata,
|
||||
curProject: state.project.curProject
|
||||
curProject: state.project.currProject
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -21,12 +21,24 @@
|
||||
background-color: #fff
|
||||
}
|
||||
.ant-tabs.ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active{
|
||||
background-color: #efefef
|
||||
background-color: #efefef;
|
||||
color:#021b2d;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.ant-tabs.ant-tabs-card > .ant-tabs-bar .ant-tabs-nav-container{
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.ant-tabs.ant-tabs-card > .ant-tabs-bar{
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
height:40px;
|
||||
}
|
||||
|
||||
.ant-tabs-nav-wrap{
|
||||
height: 40px;
|
||||
line-height: 31px;
|
||||
}
|
||||
|
||||
.interface-filter{
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Route, Switch, Redirect } from 'react-router-dom';
|
||||
import { Route, Switch, Redirect, matchPath } from 'react-router-dom';
|
||||
import { Subnav } from '../../components/index'
|
||||
import { getProject } from '../../reducer/modules/project';
|
||||
import { getProject } from '../../reducer/modules/project';
|
||||
import Interface from './Interface/Interface.js'
|
||||
import Activity from './Activity/Activity.js'
|
||||
import Setting from './Setting/Setting.js'
|
||||
@ -19,12 +19,14 @@ import Setting from './Setting/Setting.js'
|
||||
getProject
|
||||
}
|
||||
)
|
||||
|
||||
export default class Project extends Component {
|
||||
|
||||
static propTypes = {
|
||||
match: PropTypes.object,
|
||||
curProject: PropTypes.object,
|
||||
getProject: PropTypes.func
|
||||
getProject: PropTypes.func,
|
||||
location: PropTypes.object
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
@ -35,27 +37,43 @@ export default class Project extends Component {
|
||||
this.props.getProject(this.props.match.params.id)
|
||||
}
|
||||
|
||||
render () {
|
||||
const { match } = this.props;
|
||||
render() {
|
||||
const { match, location } = this.props;
|
||||
const routers = {
|
||||
activity: { name: '动态', path: "/project/:id/activity" },
|
||||
interface: { name: '接口', path: "/project/:id/interface/:action" },
|
||||
setting: { name: '设置', path: "/project/:id/setting" }
|
||||
}
|
||||
|
||||
let key, defaultName;
|
||||
for (key in routers) {
|
||||
if (matchPath(location.pathname, {
|
||||
path: routers[key].path
|
||||
}) !== null) {
|
||||
defaultName = routers[key].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Subnav
|
||||
default={'动态'}
|
||||
default={defaultName}
|
||||
data={[{
|
||||
name: '接口',
|
||||
name: routers.interface.name,
|
||||
path: `/project/${match.params.id}/interface/api`
|
||||
}, {
|
||||
name: '设置',
|
||||
name: routers.setting.name,
|
||||
path: `/project/${match.params.id}/setting`
|
||||
}, {
|
||||
name: '动态',
|
||||
name: routers.activity.name,
|
||||
path: `/project/${match.params.id}/activity`
|
||||
}]}/>
|
||||
}]} />
|
||||
<Switch>
|
||||
<Redirect exact from="/project/:id" to={`/project/${match.params.id}/activity`}/>
|
||||
<Route path="/project/:id/activity" component={Activity} />
|
||||
<Route path="/project/:id/interface/:action" component={Interface} />
|
||||
<Route path="/project/:id/setting" component={Setting} />
|
||||
<Redirect exact from="/project/:id" to={`/project/${match.params.id}/interface/api`} />
|
||||
<Route path={routers.activity.path} component={Activity} />
|
||||
<Route path={routers.interface.path} component={Interface} />
|
||||
<Route path={routers.setting.path} component={Setting} />
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
|
@ -311,6 +311,10 @@ class interfaceController extends baseController {
|
||||
data.res_body = params.res_body;
|
||||
}
|
||||
|
||||
if(params.status){
|
||||
data.status = params.status;
|
||||
}
|
||||
|
||||
try {
|
||||
let result = await this.Model.up(id, data);
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
|
@ -4,6 +4,7 @@ import baseController from './base.js';
|
||||
import interfaceModel from '../models/interface.js';
|
||||
import interfaceColModel from '../models/interfaceCol.js';
|
||||
import interfaceCaseModel from '../models/interfaceCase.js';
|
||||
import interfaceCatModel from '../models/interfaceCat.js';
|
||||
import groupModel from '../models/group';
|
||||
import commons from '../utils/commons.js';
|
||||
import userModel from '../models/user.js';
|
||||
@ -287,12 +288,14 @@ class projectController extends baseController {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
|
||||
}
|
||||
try {
|
||||
let result = await this.Model.get(params.id);
|
||||
let result = await this.Model.getBaseInfo(params.id);
|
||||
if(!result){
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '不存在的项目');
|
||||
}
|
||||
result = result.toObject();
|
||||
delete result.members;
|
||||
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) {
|
||||
|
@ -33,11 +33,17 @@ class projectModel extends baseModel {
|
||||
return m.save();
|
||||
}
|
||||
|
||||
get(id) {
|
||||
console.log(id)
|
||||
get(id) {
|
||||
return this.model.findOne({
|
||||
_id: id
|
||||
}).exec();
|
||||
}
|
||||
|
||||
getBaseInfo(id){
|
||||
return this.model.findOne({
|
||||
_id: id
|
||||
}).select('_id uid name basepath desc group_id group_name project_type env icon color add_time up_time')
|
||||
.exec()
|
||||
}
|
||||
|
||||
getByDomain(domain) {
|
||||
|
@ -622,29 +622,33 @@ var interfaceController = function (_baseController) {
|
||||
data.res_body = params.res_body;
|
||||
}
|
||||
|
||||
_context6.prev = 32;
|
||||
_context6.next = 35;
|
||||
if (params.status) {
|
||||
data.status = params.status;
|
||||
}
|
||||
|
||||
_context6.prev = 33;
|
||||
_context6.next = 36;
|
||||
return this.Model.up(id, data);
|
||||
|
||||
case 35:
|
||||
case 36:
|
||||
result = _context6.sent;
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(result);
|
||||
_context6.next = 42;
|
||||
_context6.next = 43;
|
||||
break;
|
||||
|
||||
case 39:
|
||||
_context6.prev = 39;
|
||||
_context6.t0 = _context6['catch'](32);
|
||||
case 40:
|
||||
_context6.prev = 40;
|
||||
_context6.t0 = _context6['catch'](33);
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context6.t0.message);
|
||||
|
||||
case 42:
|
||||
case 43:
|
||||
case 'end':
|
||||
return _context6.stop();
|
||||
}
|
||||
}
|
||||
}, _callee6, this, [[32, 39]]);
|
||||
}, _callee6, this, [[33, 40]]);
|
||||
}));
|
||||
|
||||
function up(_x6) {
|
||||
|
@ -56,6 +56,10 @@ var _interfaceCase = require('../models/interfaceCase.js');
|
||||
|
||||
var _interfaceCase2 = _interopRequireDefault(_interfaceCase);
|
||||
|
||||
var _interfaceCat = require('../models/interfaceCat.js');
|
||||
|
||||
var _interfaceCat2 = _interopRequireDefault(_interfaceCat);
|
||||
|
||||
var _group = require('../models/group');
|
||||
|
||||
var _group2 = _interopRequireDefault(_group);
|
||||
@ -636,7 +640,7 @@ var projectController = function (_baseController) {
|
||||
key: 'get',
|
||||
value: function () {
|
||||
var _ref6 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee6(ctx) {
|
||||
var params, result;
|
||||
var params, result, catInst, cat;
|
||||
return _regenerator2.default.wrap(function _callee6$(_context6) {
|
||||
while (1) {
|
||||
switch (_context6.prev = _context6.next) {
|
||||
@ -653,7 +657,7 @@ var projectController = function (_baseController) {
|
||||
case 3:
|
||||
_context6.prev = 3;
|
||||
_context6.next = 6;
|
||||
return this.Model.get(params.id);
|
||||
return this.Model.getBaseInfo(params.id);
|
||||
|
||||
case 6:
|
||||
result = _context6.sent;
|
||||
@ -667,29 +671,36 @@ var projectController = function (_baseController) {
|
||||
|
||||
case 9:
|
||||
result = result.toObject();
|
||||
delete result.members;
|
||||
catInst = _yapi2.default.getInst(_interfaceCat2.default);
|
||||
_context6.next = 13;
|
||||
return this.getProjectRole(params.id, 'project');
|
||||
return catInst.list(params.id);
|
||||
|
||||
case 13:
|
||||
cat = _context6.sent;
|
||||
|
||||
result.cat = cat;
|
||||
_context6.next = 17;
|
||||
return this.getProjectRole(params.id, 'project');
|
||||
|
||||
case 17:
|
||||
result.role = _context6.sent;
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(result);
|
||||
_context6.next = 20;
|
||||
_context6.next = 24;
|
||||
break;
|
||||
|
||||
case 17:
|
||||
_context6.prev = 17;
|
||||
case 21:
|
||||
_context6.prev = 21;
|
||||
_context6.t0 = _context6['catch'](3);
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context6.t0.message);
|
||||
|
||||
case 20:
|
||||
case 24:
|
||||
case 'end':
|
||||
return _context6.stop();
|
||||
}
|
||||
}
|
||||
}, _callee6, this, [[3, 17]]);
|
||||
}, _callee6, this, [[3, 21]]);
|
||||
}));
|
||||
|
||||
function get(_x7) {
|
||||
|
@ -71,11 +71,17 @@ var projectModel = function (_baseModel) {
|
||||
}, {
|
||||
key: 'get',
|
||||
value: function get(id) {
|
||||
console.log(id);
|
||||
return this.model.findOne({
|
||||
_id: id
|
||||
}).exec();
|
||||
}
|
||||
}, {
|
||||
key: 'getBaseInfo',
|
||||
value: function getBaseInfo(id) {
|
||||
return this.model.findOne({
|
||||
_id: id
|
||||
}).select('_id uid name basepath desc group_id group_name project_type env icon color add_time up_time').exec();
|
||||
}
|
||||
}, {
|
||||
key: 'getByDomain',
|
||||
value: function getByDomain(domain) {
|
||||
|
Loading…
Reference in New Issue
Block a user