This commit is contained in:
qitmac000249 2017-08-24 19:28:03 +08:00
commit d993d6992f
44 changed files with 111 additions and 80 deletions

View File

@ -60,3 +60,8 @@ exports.pickRandomProperty = (obj) => {
if (Math.random() < 1/++count) result = prop;
return result;
}
exports.getImgPath = (path, type) => {
let rate = window.devicePixelRatio >= 2 ? 2 : 1;
return `${path}@${rate}x.${type}`;
}

View File

@ -9,6 +9,7 @@ import { changeMenuItem } from '../../reducer/modules/menu'
import { withRouter } from 'react-router';
import Srch from './Search/Search'
const { Header } = Layout;
import { logoSVG } from '../../common.js';
const MenuUser = (props) => (
<Menu className="user-menu" >
@ -166,7 +167,7 @@ export default class HeaderCom extends Component {
<div className="content g-row">
<div className="logo">
<Link to="/group" onClick={this.relieveLink} className="href">
<img className="img" src="/image/logo_header@1x.png" /><span className="logo-name">YAPI<span className="ui-badge"></span></span>
<span className="img">{logoSVG('32px')}</span><span className="logo-name">YAPI<span className="ui-badge"></span></span>
</Link>
</div>
<div className="user-toolbar">

View File

@ -28,7 +28,7 @@
position: absolute;
left: 0;
top: 50%;
transform: translateY(-56%);
transform: translateY(-17px);
}
.ui-badge {
position: absolute;

View File

@ -1,21 +1,14 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
// import { connect } from 'react-redux'
import { Button, Input, Select, Card, Alert, Spin, Icon, Collapse, Radio, Tooltip, message } from 'antd'
import { autobind } from 'core-decorators';
import crossRequest from 'cross-request';
import mockEditor from '../../containers/Project/Interface/InterfaceList/mockEditor'
// import { withRouter } from 'react-router';
// import axios from 'axios';
import URL from 'url';
// import AddColModal from './AddColModal'
// import {
// } from '../../../reducer/modules/group.js'
import './Postman.scss'
const { TextArea } = Input;
// const { TextArea } = Input;
const InputGroup = Input.Group;
const Option = Select.Option;
const Panel = Collapse.Panel;
@ -42,7 +35,8 @@ export default class Run extends Component {
headers: [],
currDomain: '',
bodyType: '',
bodyOther: ''
bodyOther: '',
isDidMount: false
}
constructor(props) {
@ -59,6 +53,13 @@ export default class Run extends Component {
}
}
componentDidMount() {
const { bodyType } = this.state;
if(bodyType !== 'file' && bodyType !== 'form') {
this.loadBodyEditor()
}
}
@autobind
getInterfaceState(nextProps) {
const props = nextProps || this.props;
@ -107,6 +108,10 @@ export default class Run extends Component {
currDomain: domain || (env[0] && env[0].domain),
bodyType: req_body_type || 'form',
loading: false
}, () => {
if(req_body_type !== 'file' && req_body_type !== 'form') {
this.loadBodyEditor()
}
});
}
@ -301,7 +306,11 @@ export default class Run extends Component {
@autobind
changeBodyType(value) {
this.setState({bodyType: value})
this.setState({bodyType: value}, () => {
if(value !== 'file' && value !== 'form') {
this.loadBodyEditor()
}
})
}
hasCrossRequestPlugin() {
@ -358,7 +367,6 @@ export default class Run extends Component {
}
bindAceEditor = () => {
console.log(mockEditor)
mockEditor({
container: 'res-body-pretty',
data: JSON.stringify(this.state.res, null, 2),
@ -372,6 +380,21 @@ export default class Run extends Component {
onChange: function () {}
})
}
loadBodyEditor = () => {
const that = this;
setTimeout(function() {
mockEditor({
container: 'body-other-edit',
data: that.state.bodyOther,
onChange: function (d) {
if (d.format !== true) return false;
that.setState({
bodyOther: d.text
})
}
})
}, 0);
}
@autobind
fileChange(e, index) {
@ -381,7 +404,7 @@ export default class Run extends Component {
render () {
const { method, domains, pathParam, pathname, query, headers, bodyForm, bodyOther, currDomain, bodyType } = this.state;
const { method, domains, pathParam, pathname, query, headers, bodyForm, currDomain, bodyType } = this.state;
const hasPlugin = this.hasCrossRequestPlugin();
let path = pathname;
pathParam.forEach(item => {
@ -491,7 +514,7 @@ export default class Run extends Component {
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<div>BODY</div>
<div onClick={e => e.stopPropagation()} style={{marginRight: 5}}>
<Select defaultValue={bodyType} onChange={this.changeBodyType} className={method === 'POST' ? '' : 'hidden'}>
<Select value={bodyType !== 'form' && bodyType !== 'file' ? 'text' : bodyType} onChange={this.changeBodyType} className={method === 'POST' ? '' : 'hidden'}>
<Option value="text">Text</Option>
<Option value="file">File</Option>
<Option value="form">Form</Option>
@ -503,17 +526,12 @@ export default class Run extends Component {
>
{ method === 'POST' && bodyType !== 'form' && bodyType !== 'file' &&
<div>
<RadioGroup defaultValue="json">
<RadioGroup value={bodyType} onChange={(e) => this.changeBodyType(e.target.value)}>
<RadioButton value="json">JSON</RadioButton>
<RadioButton value="text">TEXT</RadioButton>
<RadioButton value="xml">XML</RadioButton>
<RadioButton value="html">HTML</RadioButton>
</RadioGroup>
<TextArea
value={bodyOther}
style={{marginTop: 10}}
autosize={{ minRows: 2, maxRows: 10 }}
></TextArea>
<div id="body-other-edit" style={{marginTop: 10}} className="pretty-editor"></div>
</div>
}
{
@ -566,14 +584,14 @@ export default class Run extends Component {
value={typeof this.state.res === 'object' ? JSON.stringify(this.state.res, null, 2) : this.state.res.toString()}
autosize={{ minRows: 2, maxRows: 10 }}
></TextArea>*/}
<div id="res-body-pretty" className="pretty-editor" style={{height: 200}}></div>
<div id="res-body-pretty" className="pretty-editor"></div>
</Panel>
<Panel header="HEADERS" key="1" >
{/*<TextArea
value={typeof this.state.resHeader === 'object' ? JSON.stringify(this.state.resHeader, null, 2) : this.state.resHeader.toString()}
autosize={{ minRows: 2, maxRows: 10 }}
></TextArea>*/}
<div id="res-headers-pretty" className="pretty-editor" style={{height: 200}}></div>
<div id="res-headers-pretty" className="pretty-editor"></div>
</Panel>
</Collapse>
</Spin>

View File

@ -2,5 +2,6 @@
.pretty-editor {
border: 1px solid #d9d9d9;
border-radius: 4px;
height: 200px;
}
}

View File

@ -89,45 +89,34 @@
}
// .card-panel-s {
// .m-card {
// .ant-card-body {
// padding-top: .6rem;
// }
// .ui-logo {
// width: .6rem;
// height: .6rem;
// line-height: .6rem;
// transform: translate(-50%, -20%);
// font-size: .24rem;
// background-color: #2395f1;
// }
// }
// }
@media (max-width: 768px) {
.m-card {
.ant-card-body {
padding-top: .24rem + .16rem + .6rem;
}
.ui-logo {
width: .6rem;
height: .6rem;
line-height: .6rem;
font-size: .3rem;
transform: translate(-50%, 0.08rem);
}
.ant-card-body {
padding-top: .08rem + .08rem + .6rem;
padding-bottom: .08rem;
}
}
}
@media (min-width: 768px) and (max-width: 992px) {
.m-card {
.ant-card-body {
padding-top: .24rem + .16rem + .8rem;
}
.ui-logo {
width: .8rem;
height: .8rem;
line-height: .8rem;
font-size: .4rem;
transform: translate(-50%, 0.16rem);
}
.ant-card-body {
padding-top: .16rem + .16rem + .8rem;
padding-bottom: .16rem;
}
}
}

View File

@ -147,7 +147,7 @@ class ProjectList extends Component {
>
{getFieldDecorator('desc', {
rules: [{
required: false, message: '请输入描述!'
required: false, message: '描述不超过50字!', max: 50
}]
})(
<TextArea rows={4} />

View File

@ -1,7 +1,13 @@
@import '../../styles/common.scss';
@import '../../styles/mixin.scss';
.follow-box{
padding: 24px;
background-color: #fff;
}
.card-panel {
border-radius: 4px;
box-shadow: $box-shadow-panel;
}

View File

@ -1,10 +1,17 @@
@import '../../../styles/mixin.scss';
.m-panel{
background-color: #fff;
padding: 24px;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
border-radius: 4px;
min-height: 5rem;
min-height: 4.68rem;
margin-top: 0;
box-shadow: $box-shadow-panel;
}
.m-tab {
overflow: inherit !important;
}
.btn-container {

View File

@ -8,7 +8,7 @@
padding: 24px;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
border-radius: 4px;
min-height: 5rem;
min-height: 4.68rem;
margin-top: 0;
}

View File

@ -5,7 +5,7 @@ import { Link } from 'react-router-dom';
import { Row, Col, Button, Icon, Card } from 'antd';
import PropTypes from "prop-types";
import { withRouter } from 'react-router';
import { logoSVG } from '../../common.js';
import { logoSVG, getImgPath } from '../../common.js';
import { changeMenuItem } from '../../reducer/modules/menu'
const HomeGuest = () => (
@ -33,7 +33,7 @@ const HomeGuest = () => (
{logoSVG('72px')}
<span className="name">YAPI</span>
</div>
<div className="detail">高效易用可部署的API管理平台<br/><span className="desc">旨在为开发产品测试人员提供更优雅的接口管理服务</span></div>
<div className="detail">高效易用功能强大的API管理平台<br/><span className="desc">旨在为开发产品测试人员提供更优雅的接口管理服务</span></div>
<div className="btn-group">
<Link to="/login"><Button type="primary" className="btn-home btn-login">登录 / 注册</Button></Link>
<Button className="btn-home btn-home-normal" id="qsso-login">QSSO 登录</Button>
@ -42,7 +42,7 @@ const HomeGuest = () => (
</Col>
<Col span={15}>
<div className="img-container">
<img className="img" src="./image/demo-img.jpg"/>
<img className="img" src={getImgPath('./image/demo-img', 'jpg')}/>
</div>
</Col>
</Row>
@ -55,18 +55,18 @@ const HomeGuest = () => (
<Row key="feat-motion-row">
<Col span={8} className="section-item" key="feat-wrapper-1">
<Icon type="api" className="img" />
<h4 className="title">项目接口管理</h4>
<h4 className="title">项目管理</h4>
<span className="desc">提供基本的项目分组项目管理接口管理功能</span>
</Col>
<Col span={8} className="section-item" key="feat-wrapper-2">
<Icon type="code-o" className="img" />
<h4 className="title">可部署</h4>
<span className="desc">用户只需配置接口的基本路径通过将线上域名指到我们的YApi平台服务器就可使用mockServer服务</span>
<h4 className="title">接口管理</h4>
<span className="desc">友好的接口文档基于websocket的多人协作接口编辑功能和类postman测试工具让多人协作成倍提升开发效率</span>
</Col>
<Col span={8} className="section-item" key="feat-wrapper-3">
<Icon type="team" className="img" />
<h4 className="title">用户管理</h4>
<span className="desc">提供基本的用户注册登录管理等功能集成了去哪儿QSSO登录</span>
<h4 className="title">MockServer</h4>
<span className="desc">基于Mockjs使用简单功能强大</span>
</Col>
</Row>
</div>
@ -101,7 +101,7 @@ const HomeGuest = () => (
</Col>
<Col span={12} className="section-card mock-after">
<Card title="生成的 Mock 数据">
<p className="mock-desc">生成的 Mock 数据可以在线使用也可以下载到本地使用</p>
<p className="mock-desc">生成的 Mock 数据可以直接用 ajax 请求使用也可以通过服务器代理使用不需要修改项目一行代码</p>
<div className="code">
<ol start="1">
<li className="alt"><span className="orderNum orderNum-first">1</span><span><span>&#123;&ensp;&ensp;</span></span></li>

View File

@ -264,7 +264,7 @@ $color-bg-lightblue: #c6e2ff;
transform: translateX(-50%);
text-align: right;
.img{
width: 7.3rem;
width: 7.12rem;
border-radius: 4px;
box-shadow : 0 30px 60px rgba(0,0,0,0.2);
}

View File

@ -16,12 +16,12 @@ import '../Setting.scss';
// layout
const formItemLayout = {
labelCol: {
lg: { span: 3 },
lg: { offset: 1, span: 3 },
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
lg: { span: 21 },
lg: { span: 19 },
xs: { span: 24 },
sm: { span: 14 }
},
@ -323,12 +323,12 @@ class ProjectMessage extends Component {
return (
<div className="m-panel">
<Row className="project-setting">
<Col sm={6} lg={3} className="setting-logo">
<Col xs={6} lg={{offset: 1, span: 3}} className="setting-logo">
<Popover placement="bottom" title={colorSelector} content={iconSelector} trigger="click" overlayClassName="change-project-container">
<Icon type={projectMsg.icon || 'star-o'} className="ui-logo" style={{ backgroundColor: constants.PROJECT_COLOR[projectMsg.color] || constants.PROJECT_COLOR.blue }} />
</Popover>
</Col>
<Col sm={18} lg={21} className="setting-intro">
<Col xs={18} sm={15} lg={19} className="setting-intro">
<h2 className="ui-title">{projectMsg.group_name + ' / ' + projectMsg.name}</h2>
<p className="ui-desc">{projectMsg.desc}</p>
</Col>
@ -407,7 +407,7 @@ class ProjectMessage extends Component {
{getFieldDecorator('desc', {
initialValue: initFormValues.desc,
rules: [{
required: false, message: '请输入描述!'
required: false, message: '描述不超过50字!', max: 50
}]
})(
<TextArea rows={4} />

View File

@ -35,14 +35,14 @@
border-radius: 2px;
.ant-card-head {
background-color: #eee;
padding: 0 .08rem !important;
padding: 0 .08rem !important;
}
.ant-card-head-title {
font-size: .12rem;
float: inherit;
}
.ant-card-body {
padding: 0;
padding: 0 !important;
}
.card-item {
padding: .1rem .15rem;

View File

@ -13,6 +13,9 @@ html, body {
height: 100%;
background: #ececec;
}
::selection {
background-color: #2395f1;
}
div, article, p, table, tr, td, th, ul, ol, li, h1, h2, h3, form, dl, dt, dd {
margin: 0;

View File

@ -4,7 +4,8 @@ $color-blue : #108ee9;
$color-blue-deeper: #34495E;
$color-grey-deep : #929aac;
$color-black-light : #404040;
$color-bg-dark: #202d3a; // 背景色 - 深蓝
$color-bg-dark: #202d3a; // 背景色 - header 用的深蓝色
$box-shadow-panel: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
@mixin row-width-limit {
max-width: 12.2rem;

View File

@ -98,9 +98,9 @@
@background-color-active: #eee;
// Disabled states
@disabled-color : fade(#0d1b3e, 25%);
@disabled-color : fade(#0d1b3e, 45%);
@disabled-bg : @background-color-base;
@disabled-color-dark : fade(#fff, 35%);
@disabled-color-dark : fade(#fff, 55%);
// Shadow
@shadow-color : rgba(0, 0, 0, .2);

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
doc/images/project_add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
doc/images/project_list.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

View File

@ -41,5 +41,5 @@
#### 4.4 测试接口
点击运行tab,可进入到接口测试页面,首先安装chrome crossRequest扩展才可正常使用此功能
<img src="./images/interface_run.png" width="400" style="margin:0px auto;display:block;" alt="图片名称" align=center />
<img src="./images/interface_run.png" width="800" style="margin:0px auto;display:block;" alt="图片名称" align=center />
点击保存按钮可把当前测试保存到测试集,方便下次调试

View File

@ -31,10 +31,10 @@ class interfaceCase extends baseModel {
type: String,
enum: ['form', 'json', 'text', 'xml']
},
res_body_form: [{
req_body_form: [{
name: String, value: String
}],
res_body_other: String
req_body_other: String
};
}

View File

@ -70,10 +70,10 @@ var interfaceCase = function (_baseModel) {
type: String,
enum: ['form', 'json', 'text', 'xml']
},
res_body_form: [{
req_body_form: [{
name: String, value: String
}],
res_body_other: String
req_body_other: String
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

View File

@ -59,7 +59,7 @@
<a class="ydoc-banner-button home-btn" href="./interface.html">开始</a>
<a class="ydoc-banner-button home-btn" href="./start.html">开始</a>
<a class="ydoc-banner-button home-btn" href="https://github.com/YMFE/yapi">Github</a>
@ -94,7 +94,7 @@
</div>
<h3 class="home-thumbnail-name">项目管理</h3>
<p class="home-thumbnail-desc">无论是大企业还是创业团队Yapi成熟的团队管理项目权限和优化的交互都能满足您的需求</p>
<p class="home-thumbnail-desc">YApi成熟的团队管理扁平化项目权限配置满足各类企业的需求</p>
</div>
<div class="home-item">
@ -114,7 +114,7 @@
</div>
<h3 class="home-thumbnail-name">MockServer</h3>
<p class="home-thumbnail-desc">基于Mockjs使用简单功能强大</p>
<p class="home-thumbnail-desc">基于Mockjs使用简单功能强大</p>
</div>
</div>

View File

@ -80,7 +80,7 @@
<p><img src="./images/interface_add.png" width="400" style="margin:0px auto;display:block;" alt="图片名称" align=center /></p>
<h4 class="subject" id="4.3 接口编辑">4.3 接口编辑 <a class="hashlink" href="#4.3 接口编辑">#</a></h4><p>添加完接口点击新添加的接口,跳转到接口预览页面,可看到刚才填写的信息。接口的详细信息点击编辑功能进行添加</p>
<h4 class="subject" id="4.4 测试接口">4.4 测试接口 <a class="hashlink" href="#4.4 测试接口">#</a></h4><p>点击运行tab,可进入到接口测试页面,首先安装chrome crossRequest扩展才可正常使用此功能
<img src="./images/interface_run.png" width="400" style="margin:0px auto;display:block;" alt="图片名称" align=center />
<img src="./images/interface_run.png" width="800" style="margin:0px auto;display:block;" alt="图片名称" align=center />
点击保存按钮可把当前测试保存到测试集,方便下次调试</p>
</article>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -24,7 +24,7 @@
"version": "v1.0.0", // banner
"button": [{ // banner
"name": "开始",
"href": "./interface.html"
"href": "./start.html"
},{
"name": "Github",
"href": "https://github.com/YMFE/yapi"
@ -39,7 +39,7 @@
"content": [{ // keykey
"name": "项目管理", //
"src": "http://ojk406wln.bkt.clouddn.com/intro_muti.png", //
"desc": "无论是大企业还是创业团队Yapi成熟的团队管理项目权限和优化的交互都能满足您的需求" //
"desc": "YApi成熟的团队管理扁平化项目权限配置满足各类企业的需求" //
},{
"name": "接口管理",
"src": "http://ojk406wln.bkt.clouddn.com/intro_md.png",
@ -47,7 +47,7 @@
},{
"name": "MockServer",
"src": "http://ojk406wln.bkt.clouddn.com/intro_theme.png",
"desc": "基于Mockjs使用简单功能强大"
"desc": "基于Mockjs使用简单功能强大"
}]
}
}]