From e1da7273045678b2e40a72511efe911305c73e0b Mon Sep 17 00:00:00 2001 From: zwjamnsss Date: Fri, 28 Jul 2017 17:28:32 +0800 Subject: [PATCH 1/8] fix: query decode --- .../InterfaceTest/InterfaceTest.js | 85 ++++++++++++------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/client/containers/AddInterface/InterfaceTest/InterfaceTest.js b/client/containers/AddInterface/InterfaceTest/InterfaceTest.js index fe031b1d..c381eb6f 100644 --- a/client/containers/AddInterface/InterfaceTest/InterfaceTest.js +++ b/client/containers/AddInterface/InterfaceTest/InterfaceTest.js @@ -50,7 +50,6 @@ export default class InterfaceTest extends Component { params: {}, paramsNotJson: false, headers: {}, - search: '', currDomain: '' } @@ -59,15 +58,15 @@ export default class InterfaceTest extends Component { } componentWillMount() { - this.interfacePropsToState() + this.getInterfaceState() } componentWillReceiveProps(nextProps) { - this.interfacePropsToState(nextProps) + this.getInterfaceState(nextProps) } @autobind - interfacePropsToState(nextProps) { + getInterfaceState(nextProps) { const props = nextProps || this.props; const { method, url, seqGroup, interfaceProject } = props; const { prd_host, basepath, protocol, env } = interfaceProject; @@ -105,6 +104,7 @@ export default class InterfaceTest extends Component { }) this.setState({ + method, domains, pathname, query, @@ -118,8 +118,7 @@ export default class InterfaceTest extends Component { @autobind testInterface() { - const { method } = this.props; - const { pathname, query, headers, params, currDomain } = this.state; + const { headers, params, currDomain, method, pathname, query } = this.state; const urlObj = URL.parse(currDomain); const href = URL.format({ @@ -156,8 +155,12 @@ export default class InterfaceTest extends Component { @autobind changeDomain(value) { - const domain = this.state.domains[value]; - this.setState({ currDomain: domain }); + this.setState({ currDomain: value }); + } + + @autobind + selectDomain(value) { + this.setState({ currDomain: value }); } @autobind @@ -171,6 +174,7 @@ export default class InterfaceTest extends Component { changeQuery(e, key) { const query = JSON.parse(JSON.stringify(this.state.query)); query[key] = e.target.value; + this.setState({ query }); } @@ -181,6 +185,21 @@ export default class InterfaceTest extends Component { this.setState({ params }); } + @autobind + changeMethod(value) { + this.setState({ method: value }); + } + + @autobind + changePath(e) { + const path = e.target.value; + const urlObj = URL.parse(path, true); + this.setState({ + query: urlObj.query, + pathname: urlObj.pathname + }) + } + hasCrossRequestPlugin() { const dom = document.getElementById('y-request'); return dom.getAttribute('key') === 'yapi'; @@ -188,12 +207,10 @@ export default class InterfaceTest extends Component { render () { - const { interfaceName, method } = this.props; - const { domains, pathname, query, headers, params, paramsNotJson } = this.state; - const search = URL.format({ - query - }); + const { interfaceName } = this.props; + const { method, domains, pathname, query, headers, params, paramsNotJson, currDomain } = this.state; const hasPlugin = this.hasCrossRequestPlugin(); + const search = decodeURIComponent(URL.format({query})); return ( @@ -217,6 +234,8 @@ export default class InterfaceTest extends Component { }
{interfaceName}
+ + {/* url */}
@@ -225,13 +244,16 @@ export default class InterfaceTest extends Component { - - + + + + - + (请求测试真实接口)
- -
- { - Object.keys(headers).map((key, index) => { - return ( -
- {' = '} - this.changeHeader(e, key)} style={{display: 'inline-block', width: 200, margin: 10}} /> -
- ) - }) - } -
-
+
{ @@ -270,6 +279,20 @@ export default class InterfaceTest extends Component { }
+ +
+ { + Object.keys(headers).map((key, index) => { + return ( +
+ {' = '} + this.changeHeader(e, key)} style={{display: 'inline-block', width: 200, margin: 10}} /> +
+ ) + }) + } +
+
{ paramsNotJson ? From d31d3580cbe5ed62c9ba9b06c8546b31058cf4d5 Mon Sep 17 00:00:00 2001 From: zwjamnsss Date: Fri, 28 Jul 2017 17:29:42 +0800 Subject: [PATCH 2/8] opti: remove disabled --- .../AddInterface/InterfaceTest/InterfaceTest.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/containers/AddInterface/InterfaceTest/InterfaceTest.js b/client/containers/AddInterface/InterfaceTest/InterfaceTest.js index c381eb6f..8e69d2a6 100644 --- a/client/containers/AddInterface/InterfaceTest/InterfaceTest.js +++ b/client/containers/AddInterface/InterfaceTest/InterfaceTest.js @@ -239,9 +239,9 @@ export default class InterfaceTest extends Component {
- - - + + + {' = '} + {' = '} this.changeQuery(e, key)} style={{display: 'inline-block', width: 200, margin: 10}} />
) @@ -285,7 +285,7 @@ export default class InterfaceTest extends Component { Object.keys(headers).map((key, index) => { return (
- {' = '} + {' = '} this.changeHeader(e, key)} style={{display: 'inline-block', width: 200, margin: 10}} />
) @@ -305,7 +305,7 @@ export default class InterfaceTest extends Component { const value = typeof params[key] === 'object' ? JSON.stringify(params[key]) : params[key].toString(); return (
- {' = '} + {' = '} this.changeParams(e, key)} style={{display: 'inline-block', width: 200, margin: 10}} />
) From a6bc82179abef70cca9ef4aad5e0557c26b951f9 Mon Sep 17 00:00:00 2001 From: zwjamnsss Date: Sun, 30 Jul 2017 11:10:33 +0800 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20query=E5=A2=9E=E5=88=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InterfaceTest/InterfaceTest.js | 85 +++++++++++++------ .../InterfaceTest/InterfaceTest.scss | 8 +- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/client/containers/AddInterface/InterfaceTest/InterfaceTest.js b/client/containers/AddInterface/InterfaceTest/InterfaceTest.js index 8e69d2a6..941b4814 100644 --- a/client/containers/AddInterface/InterfaceTest/InterfaceTest.js +++ b/client/containers/AddInterface/InterfaceTest/InterfaceTest.js @@ -1,10 +1,11 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' -import { Button, Input, Select, Card, Alert, Spin } from 'antd' +import { Button, Input, Select, Card, Alert, Spin, Icon } from 'antd' import { autobind } from 'core-decorators'; import crossRequest from 'cross-request'; import { withRouter } from 'react-router'; +import axios from 'axios'; import URL from 'url'; import { @@ -77,7 +78,7 @@ export default class InterfaceTest extends Component { domains[item.name] = item.domain; }) - const query = {}; + const query = []; let params = {}; let reqParams = this.props.reqParams ? this.props.reqParams : '{}'; let paramsNotJson = false; @@ -90,7 +91,7 @@ export default class InterfaceTest extends Component { if (method === 'GET') { Object.keys(reqParams).forEach(key => { const value = typeof reqParams[key] === 'object' ? JSON.stringify(reqParams[key]) : reqParams[key].toString(); - query[key] = value; + query.push({key, value}) }) } else if (method === 'POST') { params = reqParams; @@ -117,7 +118,7 @@ export default class InterfaceTest extends Component { } @autobind - testInterface() { + requestInterface() { const { headers, params, currDomain, method, pathname, query } = this.state; const urlObj = URL.parse(currDomain); @@ -125,7 +126,7 @@ export default class InterfaceTest extends Component { protocol: urlObj.protocol || 'http', host: urlObj.host, pathname, - query + query: this.getQueryObj(query) }); this.setState({ loading: true }) @@ -171,12 +172,26 @@ export default class InterfaceTest extends Component { } @autobind - changeQuery(e, key) { + changeQuery(e, index, isKey) { const query = JSON.parse(JSON.stringify(this.state.query)); - query[key] = e.target.value; - + const v = e.target.value; + if (isKey) { + query[index].key = v; + } else { + query[index].value = v; + } this.setState({ query }); } + @autobind + addQuery() { + const { query } = this.state; + this.setState({query: query.concat([{key: '', value: ''}])}) + } + @autobind + deleteQuery(index) { + const { query } = this.state; + this.setState({query: query.filter((item, i) => +index !== +i)}); + } @autobind changeParams(e, key) { @@ -205,12 +220,25 @@ export default class InterfaceTest extends Component { return dom.getAttribute('key') === 'yapi'; } + getQueryObj(query) { + const queryObj = {}; + query.forEach(item => { + if (item.key) { + queryObj[item.key] = item.value || ''; + } + }) + return queryObj; + } + render () { const { interfaceName } = this.props; const { method, domains, pathname, query, headers, params, paramsNotJson, currDomain } = this.state; const hasPlugin = this.hasCrossRequestPlugin(); - const search = decodeURIComponent(URL.format({query})); + const search = decodeURIComponent(URL.format({query: this.getQueryObj(query)})); + + console.log(axios) + window.axios = axios return ( @@ -239,9 +267,9 @@ export default class InterfaceTest extends Component {
- - - + + +
- -
- { - Object.keys(query).map((key, index) => { - const value = typeof query[key] === 'object' ? JSON.stringify(query[key]) : query[key].toString(); - return ( -
- {' = '} - this.changeQuery(e, key)} style={{display: 'inline-block', width: 200, margin: 10}} /> -
- ) - }) - } -
+ + { + query.map((item, index) => { + return ( +
+ this.changeQuery(e, index, true)} style={{display: 'inline-block', width: 200, margin: 10}} />{' = '} + this.changeQuery(e, index)} style={{display: 'inline-block', width: 200, margin: 10}} /> + this.deleteQuery(index)} /> +
+ ) + }) + } +
@@ -291,9 +318,10 @@ export default class InterfaceTest extends Component { ) }) } +
- +
{ paramsNotJson ? : - Object.keys(params).map((key, index) => { - const value = typeof params[key] === 'object' ? JSON.stringify(params[key]) : params[key].toString(); - return ( -
- {' = '} - this.changeParams(e, key)} style={{display: 'inline-block', width: 200, margin: 10}} /> -
- ) - }) + + { method === 'POST' && paramsType !== 'form' && paramsType !== 'file' && +
+ +
{paramsType}
+
+ } + { + method === 'POST' && paramsType === 'form' && ( +
+ { + params.map((item, index) => { + return ( +
+ this.changeParams(e, index, 'key')} style={{display: 'inline-block', width: 200, margin: 10}} /> + []{' = '} + {item.type === 'file' ? + : + this.changeParams(e, index, 'value')} style={{display: 'inline-block', width: 200, margin: 10}} /> + } +
+ ) + }) + } + +
+ ) + } + { + method === 'POST' && paramsType === 'file' && ( +
+ +
+ ) + } + { + method !== 'POST' && ( +
GET 请求没有 Body。
+ ) } -
From e9d95ebbc9ec4696a6a510a7d77b506b2ce20668 Mon Sep 17 00:00:00 2001 From: sean Date: Mon, 31 Jul 2017 10:15:16 +0800 Subject: [PATCH 5/8] feat: mockServer add crossRequest and change autoincrement num --- server/middleware/mockServer.js | 11 +++++++--- server/models/base.js | 2 +- server/models/interface.js | 5 +++-- server_dist/middleware/mockServer.js | 33 ++++++++++++++++++---------- server_dist/models/base.js | 2 +- server_dist/models/interface.js | 5 +++-- 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/server/middleware/mockServer.js b/server/middleware/mockServer.js index e6389063..22637a72 100644 --- a/server/middleware/mockServer.js +++ b/server/middleware/mockServer.js @@ -16,7 +16,6 @@ module.exports = async (ctx, next) => { yapi.commons.log('MockServer Running...'); let projectInst = yapi.getInst(projectModel), projects; - try { projects = await projectInst.getByDomain(hostname); } catch (e) { @@ -46,9 +45,15 @@ module.exports = async (ctx, next) => { let interfaceInst = yapi.getInst(interfaceModel); try { - interfaceData = await interfaceInst.getByPath(project._id, ctx.path.substr(project.basepath.length)); + interfaceData = await interfaceInst.getByPath(project._id, ctx.path.substr(project.basepath.length), ctx.method); if (!interfaceData || interfaceData.length === 0) { + //非正常跨域预检请求回应 + if(ctx.method === 'OPTIONS'){ + ctx.set("Access-Control-Allow-Origin", "*") + ctx.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE") + return ctx.body = 'ok' + } return ctx.body = yapi.commons.resReturn(null, 404, '不存在的api'); } @@ -57,7 +62,7 @@ module.exports = async (ctx, next) => { } interfaceData = interfaceData[0]; - + ctx.set("Access-Control-Allow-Origin", "*") if (interfaceData.res_body_type === 'json') { return ctx.body = Mock.mock( yapi.commons.json_parse(interfaceData.res_body) diff --git a/server/models/base.js b/server/models/base.js index 83553958..a2651393 100644 --- a/server/models/base.js +++ b/server/models/base.js @@ -16,7 +16,7 @@ class baseModel{ model: this.name, field: this.getPrimaryKey(), startAt: 101, - incrementBy: yapi.commons.rand(1, 100) + incrementBy: yapi.commons.rand(1, 10) }); } diff --git a/server/models/interface.js b/server/models/interface.js index f5c4e1c9..e71ad853 100644 --- a/server/models/interface.js +++ b/server/models/interface.js @@ -47,10 +47,11 @@ class interfaceModel extends baseModel { .exec(); } - getByPath(project_id, path) { + getByPath(project_id, path, method) { return this.model.find({ project_id: project_id, - path: path + path: path, + method: method }) .exec(); } diff --git a/server_dist/middleware/mockServer.js b/server_dist/middleware/mockServer.js index 14cd95ef..2658e80d 100644 --- a/server_dist/middleware/mockServer.js +++ b/server_dist/middleware/mockServer.js @@ -103,51 +103,62 @@ module.exports = function () { interfaceInst = _yapi2.default.getInst(_interface2.default); _context.prev = 25; _context.next = 28; - return interfaceInst.getByPath(project._id, ctx.path.substr(project.basepath.length)); + return interfaceInst.getByPath(project._id, ctx.path.substr(project.basepath.length), ctx.method); case 28: interfaceData = _context.sent; if (!(!interfaceData || interfaceData.length === 0)) { - _context.next = 31; + _context.next = 35; break; } + if (!(ctx.method === 'OPTIONS')) { + _context.next = 34; + break; + } + + ctx.set("Access-Control-Allow-Origin", "*"); + ctx.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); + return _context.abrupt('return', ctx.body = 'ok'); + + case 34: return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 404, '不存在的api')); - case 31: + case 35: if (!(interfaceData.length > 1)) { - _context.next = 33; + _context.next = 37; break; } return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 405, '存在多个api,请检查数据库')); - case 33: + case 37: interfaceData = interfaceData[0]; + ctx.set("Access-Control-Allow-Origin", "*"); if (!(interfaceData.res_body_type === 'json')) { - _context.next = 36; + _context.next = 41; break; } return _context.abrupt('return', ctx.body = _mockjs2.default.mock(_yapi2.default.commons.json_parse(interfaceData.res_body))); - case 36: + case 41: return _context.abrupt('return', ctx.body = interfaceData.res_body); - case 39: - _context.prev = 39; + case 44: + _context.prev = 44; _context.t1 = _context['catch'](25); return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 409, _context.t1.message)); - case 42: + case 47: case 'end': return _context.stop(); } } - }, _callee, undefined, [[10, 16], [25, 39]]); + }, _callee, undefined, [[10, 16], [25, 44]]); })); return function (_x, _x2) { diff --git a/server_dist/models/base.js b/server_dist/models/base.js index 62d976e5..2680baef 100644 --- a/server_dist/models/base.js +++ b/server_dist/models/base.js @@ -38,7 +38,7 @@ var baseModel = function () { model: this.name, field: this.getPrimaryKey(), startAt: 101, - incrementBy: _yapi2.default.commons.rand(1, 100) + incrementBy: _yapi2.default.commons.rand(1, 10) }); } diff --git a/server_dist/models/interface.js b/server_dist/models/interface.js index 7e7b1ef6..aa3165c0 100644 --- a/server_dist/models/interface.js +++ b/server_dist/models/interface.js @@ -88,10 +88,11 @@ var interfaceModel = function (_baseModel) { } }, { key: 'getByPath', - value: function getByPath(project_id, path) { + value: function getByPath(project_id, path, method) { return this.model.find({ project_id: project_id, - path: path + path: path, + method: method }).exec(); } }, { From 8dd18f15c6e964bcf908ed8a3f7bb59e3c6a0664 Mon Sep 17 00:00:00 2001 From: zwjamnsss Date: Mon, 31 Jul 2017 10:30:45 +0800 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=E6=8E=A5=E5=8F=A3=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InterfaceTest/InterfaceTest.js | 42 ++++++++++++++----- .../InterfaceTest/InterfaceTest.scss | 5 +++ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/client/containers/AddInterface/InterfaceTest/InterfaceTest.js b/client/containers/AddInterface/InterfaceTest/InterfaceTest.js index 9c7f6938..43664fe7 100644 --- a/client/containers/AddInterface/InterfaceTest/InterfaceTest.js +++ b/client/containers/AddInterface/InterfaceTest/InterfaceTest.js @@ -140,8 +140,8 @@ export default class InterfaceTest extends Component { crossRequest({ url: href, method, - headers, - data: params, + headers: this.getHeadersObj(headers), + data: this.arrToObj(params), success: (res) => { try { res = JSON.parse(res) @@ -266,6 +266,15 @@ export default class InterfaceTest extends Component { return dom.getAttribute('key') === 'yapi'; } + arrToObj(arr) { + const obj = {}; + arr.forEach(item => { + if (item.key) { + obj[item.key] = item.value || ''; + } + }) + return obj; + } getQueryObj(query) { const queryObj = {}; query.forEach(item => { @@ -275,6 +284,15 @@ export default class InterfaceTest extends Component { }) return queryObj; } + getHeadersObj(headers) { + const headersObj = {}; + headers.forEach(item => { + if (item.name && item.value) { + headersObj[item.name] = item.value; + } + }) + return headersObj; + } render () { @@ -350,7 +368,7 @@ export default class InterfaceTest extends Component { ) }) } - +
@@ -365,16 +383,18 @@ export default class InterfaceTest extends Component { ) }) } - +
- +
+ +
{ method === 'POST' && paramsType !== 'form' && paramsType !== 'file' &&