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

This commit is contained in:
suxiaoxin 2017-09-22 17:35:18 +08:00
commit ecc079f006
7 changed files with 158 additions and 101 deletions

View File

@ -1,7 +1,7 @@
.col-list-tree {
line-height: 25px;
.ant-tree-node-content-wrapper {
width: calc(100% - 24px);
width: calc(100% - 28px);
}
.opts-icon, .case-delete-icon {
line-height: 25px;

View File

@ -748,7 +748,7 @@ class InterfaceEditForm extends Component {
className={'interface-edit-item ' + this.state.hideTabs.other.remark}
>
<div >
<div id="desc" ></div>
<div id="desc" className="remark-editor"></div>
</div>
</FormItem>
<FormItem

View File

@ -2,7 +2,8 @@ import './View.scss'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { Table,Icon } from 'antd'
import { Table,Icon, Row, Col } from 'antd'
import { Link } from 'react-router-dom'
const mockEditor = require('./mockEditor.js')
import { formatTime } from '../../../../common.js';
import ErrMsg from '../../../../components/ErrMsg/ErrMsg.js';
@ -51,20 +52,33 @@ class View extends Component {
title: '是否必须',
dataIndex: 'required',
key: 'required'
}, {
},{
title: '示例',
dataIndex: 'example',
key: 'example',
width: 4,
render(_, item) {
return <pre>{item.example}</pre>;
}
},{
title: '备注',
dataIndex: 'value',
key: 'value',
width: '45%'
width: 4,
render(_, item) {
return <pre>{item.value}</pre>;
}
}];
const dataSource = [];
if(req_body_form&&req_body_form.length){
req_body_form.map((item,i)=>{
console.log(item);
dataSource.push({
key: i,
name: item.name,
value: item.desc,
example: item.example,
required: item.required==0?"否":"是",
type: item.type
})
@ -72,21 +86,21 @@ class View extends Component {
}
return <div style={{display:dataSource.length?"":"none"}} className="colBody">
<span className="colKey">请求Body</span>
<h3 className="col-title">Body</h3>
<Table bordered size="small" pagination = {false} columns= {columns} dataSource = {dataSource} />
</div>
}else if(req_body_type === 'file'){
return <div style={{display:this.props.curData.req_body_other?"":"none"}} className="colBody">
<span className="colKey">请求Body</span>
<h3 className="col-title">Body</h3>
<div>{this.props.curData.req_body_other}</div>
</div>
}else if(req_body_type === 'raw'){
return <div style={{display:this.props.curData.req_body_other?"":"none"}} className="colBody">
<span className="colKey">请求Body</span>
<h3 className="col-title">Body</h3>
<div>{this.props.curData.req_body_other}</div>
</div>
}
@ -95,12 +109,10 @@ class View extends Component {
if(res_body_type === 'json'){
let h = this.countEnter(this.props.curData.res_body);
return <div style={{display:this.props.curData.res_body?"":"none"}} className="colBody">
<span className="colKey">返回Body</span>
<div id="vres_body_json" style={{ minHeight: h*16+20 }}></div>
</div>
}else if(res_body_type === 'raw'){
return <div style={{display:this.props.curData.res_body?"":"none"}} className="colBody">
<span className="colKey">返回Body</span>
<div>{res_body}</div>
</div>
}
@ -110,16 +122,29 @@ class View extends Component {
const columns = [{
title: '参数名称',
dataIndex: 'name',
width: 4,
key: 'name'
}, {
title: '是否必须',
width: 4,
dataIndex: 'required',
key: 'required'
}, {
title: '示例',
dataIndex: 'example',
key: 'example',
width: 4,
render(_, item) {
return <pre>{item.example}</pre>;
}
}, {
title: '备注',
dataIndex: 'value',
key: 'value',
width: '45%'
width: 4,
render(_, item) {
return <pre>{item.value}</pre>;
}
}];
const dataSource = [];
@ -129,6 +154,7 @@ class View extends Component {
key: i,
name: item.name,
value: item.desc,
example: item.example,
required: item.required==0?"否":"是"
})
})
@ -191,10 +217,12 @@ class View extends Component {
name: item.name,
required: item.required==0?"否":"是",
value: item.value,
example: item.example,
desc: item.desc
})
})
}
console.log(this.props);
const req_dataSource = [];
if(this.props.curData.req_params&&this.props.curData.req_params.length){
this.props.curData.req_params.map((item,i)=>{
@ -230,11 +258,22 @@ class View extends Component {
dataIndex: 'required',
key: 'required',
width: 1
},{
title: '示例',
dataIndex: 'example',
key: 'example',
width: 4,
render(_, item) {
return <pre>{item.example}</pre>;
}
},{
title: '备注',
dataIndex: 'desc',
key: 'desc',
width: 4
width: 4,
render(_, item) {
return <pre>{item.desc}</pre>;
}
}];
let status = {
undone: "未完成",
@ -249,48 +288,48 @@ class View extends Component {
</div>
if(!methodColor) methodColor = "get";
let res = <div className="caseContainer">
<div className="colName">
<span className="colKey">接口名称</span>
<span className="colValue">{this.props.curData.title}</span>
</div>
<div className="colMethod">
<span className="colKey">请求方法</span>
<span style={{color:methodColor.color,backgroundColor:methodColor.bac}} className="colValue">{this.props.curData.method}</span>
</div>
<div className="colPath">
<span className="colKey">接口路径</span>
<h2 className="interface-title" style={{ marginTop: 0 }}>基本信息</h2>
<div className="panel-sub">
<Row className="row">
<Col span={4} className="colKey">接口名称</Col>
<Col span={8}>{this.props.curData.title}</Col>
<Col span={4} className="colKey">创建人</Col>
<Col span={8} className="colValue"><Link className="user-name" to={"/user/profile/" + this.props.curData.uid} ><img src={'/api/user/avatar?uid=' + this.props.curData.uid} className="user-img" />{this.props.curData.username}</Link></Col>
</Row>
<Row className="row">
<Col span={4} className="colKey"> </Col>
<Col span={8} className={'tag-status ' + this.props.curData.status}>{status[this.props.curData.status]}</Col>
<Col span={4} className="colKey">更新时间</Col>
<Col span={8}>{formatTime(this.props.curData.up_time)}</Col>
</Row>
<Row className="row">
<Col span={4} className="colKey">接口路径</Col>
<Col span={18} className="colValue">
<span style={{color:methodColor.color,backgroundColor:methodColor.bac}} className="colValue tag-method">{this.props.curData.method}</span>
<span className="colValue">{this.props.currProject.basepath}{this.props.curData.path}</span>
</Col>
</Row>
<Row className="row">
<Col span={4} className="colKey">Mock地址</Col>
<Col span={18} className="colValue href"><span onClick={() => window.open(location.protocol + '//' + location.hostname + (location.port !== "" ? ":" + location.port : "") + `/mock/${this.props.currProject._id}${this.props.currProject.basepath}${this.props.curData.path}`, '_blank')}>{location.protocol + '//' + location.hostname + (location.port !== "" ? ":" + location.port : "") + `/mock/${this.props.currProject._id}${this.props.currProject.basepath}${this.props.curData.path}`}</span></Col>
</Row>
{this.props.curData.desc?
<Row className="row">
<Col span={4} className="colKey">接口备注</Col>
<Col span={18} className="colValue" dangerouslySetInnerHTML={{__html: this.props.curData.desc}}></Col>
</Row>:""}
</div>
<div className="colstatus">
<span className="colKey">&emsp;&emsp;</span>
<span className={'tag-status ' + this.props.curData.status}>{status[this.props.curData.status]}</span>
</div>
<div className="colAddTime">
<span className="colKey">创建时间</span>
<span className="colValue">{formatTime(this.props.curData.add_time)}</span>
</div>
<div className="colUpTime">
<span className="colKey">更新时间</span>
<span className="colValue">{formatTime(this.props.curData.up_time)}</span>
</div>
<div className="colMockUrl">
<span className="colKey">Mock地址</span>
<span className="colValue href" onClick={() => window.open(location.protocol + '//' + location.hostname + (location.port !== "" ? ":" + location.port : "") + `/mock/${this.props.currProject._id}${this.props.currProject.basepath}${this.props.curData.path}`, '_blank')}>{location.protocol + '//' + location.hostname + (location.port !== "" ? ":" + location.port : "") + `/mock/${this.props.currProject._id}${this.props.currProject.basepath}${this.props.curData.path}`}</span>
</div>
{this.props.curData.desc?<div className="colDesc">
<span className="colKey">接口备注</span>
<span className="colValue" dangerouslySetInnerHTML={{__html: this.props.curData.desc}}></span>
</div>:""}
<h2 className="interface-title">Request</h2>
{req_dataSource.length?<div className="colHeader">
<span className="colKey">路径参数</span>
<h3 className="col-title">路径参数</h3>
<Table bordered size="small" pagination = {false} columns= {req_params_columns} dataSource = {req_dataSource} />
</div>:""}
{dataSource.length?<div className="colHeader">
<span className="colKey">请求Headers</span>
<h3 className="col-title">Headers</h3>
<Table bordered size="small" pagination = {false} columns= {columns} dataSource = {dataSource} />
</div>:""}
{this.props.curData.req_query&&this.props.curData.req_query.length?<div className="colQuery">
<span className="colKey">Query</span>
<h3 className="col-title">Query</h3>
{this.req_query(this.props.curData.req_query)}
</div>:""}
{/*<div className="colreqBodyType">
@ -303,6 +342,7 @@ class View extends Component {
<span className="colKey">返回Body类型</span>
<span className="colValue">{this.props.curData.res_body_type}</span>
</div>*/}
<h2 className="interface-title">Response</h2>
{this.res_body(this.props.curData.res_body_type,this.props.curData.res_body)}
</div>;
if(!this.props.curData.title){

View File

@ -11,17 +11,9 @@
box-sizing: border-box;
float: left;
.colKey{
font-weight: bolder;
margin-right: 16px;
padding-bottom: 16px;
display: inline-block;
}
}
.colreqBodyType{
margin: 0px;
.colKey{
padding-bottom: 0px;
font-weight: bold;
text-align: right;
max-width: 100px;
}
}
.colValue.href {
@ -31,15 +23,6 @@
.ace_print-margin{
display: none;
}
.colName,.colPath,.colstatus,.colAddTime,.colUpTime,.colMethod{
width: 50%;
float: left;
padding: 8px 16px;
height: 40px;
.colKey{
padding-bottom: 0px;
}
}
.colBody{
.query-icon {
display: inline-block;
@ -97,26 +80,44 @@
color: white;
}
}
.colMockUrl{
margin-bottom: 0px;
padding-bottom: 0px;
line-height: 1.5em;
.user-img {
width: .3rem;
height: .3rem;
border-radius: 50%;
border: 2px solid #eee;
vertical-align: middle;
margin-right: 4px;
}
.colDesc{
line-height: 1.5em;
.colKey{
margin-right: 0px;
float: left;
margin-bottom: 8px;
.tag-method {
padding: 4px 6px;
margin-right: 8px;
border-radius: 4px;
vertical-align: middle;
}
}
.colHalf {
width: 50%;
float: left;
margin-bottom: .16rem;
.colKey{
padding-bottom: 0px;
text-align: right;
}
}
.panel-sub {
.row {
margin-bottom: .16rem;
line-height: 36px;
}
.user-img {
position: absolute;
left: 0;
top: 50%;
transform: translate(0, -50%);
}
.user-name {
padding-left: .32rem;
}
.colValue{
float: left;
text-indent: 2em;
}
}
// .ace_scroller{
// position: relative;
// margin-left: 50px;
// overflow:visible;
// }
}

View File

@ -69,7 +69,7 @@
transform: translateY(-50%);
}
.ant-tree li .ant-tree-node-content-wrapper {
width: calc(100% - 24px);
width: calc(100% - 28px);
position: relative;
}
@ -97,7 +97,7 @@
a{
color: #333
color: rgba(13, 27, 62, 0.65);
}
.btn-http{
@ -123,11 +123,6 @@
}
}
a{
color: #333;
}
.btn-http{
height: 23px;
font-size: 10px;
@ -166,6 +161,7 @@
}
}
.interface-title {
clear: both;
font-weight: normal;
margin-top: .48rem;
margin-bottom: .16rem;
@ -191,4 +187,18 @@
color: #2395f1;
cursor: pointer;
}
.remark-editor {
background-color: #fff;
}
table {
border-collapse: collapse;
}
th {
text-align: left;
}
th, td {
border: 1px solid #e9e9e9;
padding: 8px;
}
tr:nth-child(odd){background: rgba(236, 238, 241, 0.67);}
}

View File

@ -171,7 +171,7 @@ class ProjectMember extends Component {
key: 'username',
render: (text, record) => {
return (<div className="m-user">
<img src={location.protocol + '//' + location.host + '/api/user/avatar?uid=' + record.uid} className="m-user-img" />
<img src={'/api/user/avatar?uid=' + record.uid} className="m-user-img" />
<p className="m-user-name">{text}</p>
</div>);
}

View File

@ -203,12 +203,18 @@ class interfaceController extends baseController {
try {
let result = await this.Model.get(params.id);
if(!result){
return ctx.body = yapi.commons.resReturn(null, 490, '不存在的');
}
let userinfo = await this.userModel.findById(result.uid);
let project = await this.projectModel.getBaseInfo(result.project_id);
if (project.project_type === 'private') {
if (await this.checkAuth(project._id, 'project', 'view') !== true) {
return ctx.body = yapi.commons.resReturn(null, 406, '没有权限');
}
}
result = result.toObject();
result.username = userinfo.username;
ctx.body = yapi.commons.resReturn(result);
} catch (e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);