### Features

This commit is contained in:
suxiaoxin 2017-10-17 11:22:21 +08:00
parent c5916568fc
commit 40b1da811e
10 changed files with 78 additions and 35 deletions

View File

@ -1,4 +1,12 @@
## 1.1.2
### Features
* 接口运行增加了 query 和 body 的 enable 选项,可选择是否请求该字段
* Mock 支持了时间戳占位符 @timestamp
### Bug Fixed
* 修复了接口集运行功能会忽略 domain path 的 bug
## 1.1.1
### Features
* 添加插件开发文档

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Mock from 'mockjs'
import { Button, Input, Select, Alert, Spin, Icon, Collapse, Tooltip, message, AutoComplete, Switch } from 'antd'
import { Button, Input, Checkbox, Select, Alert, Spin, Icon, Collapse, Tooltip, message, AutoComplete, Switch } from 'antd'
import { autobind } from 'core-decorators';
import constants from '../../constants/variable.js'
@ -202,8 +202,8 @@ export default class Run extends Component {
pathParam.forEach(item => {
path = path.replace(`:${item.name}`, item.value || `:${item.name}`);
});
if(urlObj.pathname){
if(urlObj.pathname[urlObj.pathname.length - 1] !== '/'){
if (urlObj.pathname) {
if (urlObj.pathname[urlObj.pathname.length - 1] !== '/') {
urlObj.pathname += '/'
}
}
@ -331,12 +331,14 @@ export default class Run extends Component {
}
@autobind
changeQuery(v, index, isKey) {
changeQuery(v, index, key) {
key = key || 'value';
const query = json_parse(JSON.stringify(this.state.query));
if (isKey) {
query[index].name = v;
if (key == 'enable') {
query[index].enable = v;
} else {
query[index].value = v;
query[index].enable = true;
}
this.setState({ query });
}
@ -382,13 +384,20 @@ export default class Run extends Component {
}
@autobind
changeBody(v, index) {
changeBody(v, index, key) {
const bodyForm = json_parse(JSON.stringify(this.state.bodyForm));
if (bodyForm[index].type === 'file') {
bodyForm[index].value = 'file_' + index
} else {
bodyForm[index].value = v
key = key || 'value';
if (key === 'value') {
bodyForm[index].enable = true;
if (bodyForm[index].type === 'file') {
bodyForm[index].value = 'file_' + index
} else {
bodyForm[index].value = v
}
} else if (key === 'enable') {
bodyForm[index].enable = v
}
this.setState({ bodyForm });
}
@autobind
@ -445,9 +454,10 @@ export default class Run extends Component {
arrToObj(arr) {
const obj = {};
arr.forEach(item => {
if (item.name && item.type !== 'file') {
obj[item.name] = handleMockWord(item.value);
}
if (item)
if (item.name && item.type !== 'file' && item.enable) {
obj[item.name] = handleMockWord(item.value);
}
})
return obj;
}
@ -455,7 +465,7 @@ export default class Run extends Component {
getFiles(bodyForm) {
const files = {};
bodyForm.forEach(item => {
if (item.name && item.type === 'file') {
if (item.name && item.enable === true && item.type === 'file') {
files[item.name] = item.value
}
})
@ -464,7 +474,7 @@ export default class Run extends Component {
getQueryObj(query) {
const queryObj = {};
query.forEach(item => {
if (item.name) {
if (item.name && item.enable) {
queryObj[item.name] = handleMockWord(item.value);
}
})
@ -487,7 +497,7 @@ export default class Run extends Component {
readOnly: true,
onChange: function () { }
})
mockEditor({
container: 'res-headers-pretty',
@ -649,7 +659,12 @@ export default class Run extends Component {
query.map((item, index) => {
return (
<div key={index} className="key-value-wrap">
<Input disabled value={item.name} onChange={e => this.changeQuery(e, index, true)} className="key" />
<Input disabled value={item.name} className="key" />
&nbsp;
{item.required == 1 ?
<Checkbox checked={true} disabled >enable</Checkbox> :
<Checkbox checked={item.enable} onChange={e => this.changeQuery(e.target.checked, index, 'enable')}>enable</Checkbox>
}
<span className="eq-symbol">=</span>
<AutoComplete
value={item.value}
@ -710,12 +725,13 @@ export default class Run extends Component {
return (
<div key={index} className="key-value-wrap">
<Input disabled value={item.name} onChange={e => this.changeBody(e, index, 'key')} className="key" />
<span>[</span>
<Select disabled value={item.type} onChange={e => this.changeBody(e, index, 'type')}>
<Option value="file">File</Option>
<Option value="text">Text</Option>
</Select>
<span>]</span>
&nbsp;
{item.required == 1 ?
<Checkbox checked={true} disabled >enable</Checkbox> :
<Checkbox checked={item.enable} onChange={e => this.changeBody(e.target.checked, index, 'enable')}>enable</Checkbox>
}
<span className="eq-symbol">=</span>
{item.type === 'file' ?
<Input type="file" id={'file_' + index} onChange={e => this.changeBody(e, index, 'value')} multiple className="value" /> :
@ -752,10 +768,11 @@ export default class Run extends Component {
<h2 className="interface-title">返回结果</h2>
<Spin spinning={this.state.loading}>
<h2 style={{ display: this.state.resStatusCode !== null ? '' : 'none' }} className={'res-code ' + ((this.state.resStatusCode >= 200 && this.state.resStatusCode < 400 && !this.state.loading) ? 'success' : 'fail')}>{this.state.resStatusCode + ' ' + this.state.resStatusText}</h2>
<Spin spinning={this.state.loading}>
<h2 style={{ display: this.state.resStatusCode ? '' : 'none' }} className={'res-code ' + ((this.state.resStatusCode >= 200 && this.state.resStatusCode < 400 && !this.state.loading) ? 'success' : 'fail')}>
{this.state.resStatusCode + ' ' + this.state.resStatusText}</h2>
<div style={{ display: this.state.res ? '' : 'none' }} className="container-header-body">
<div style={{ display: this.state.res ? '' : 'none' }} className="container-header-body">
<div className="header">
<div className="container-title">
<h4>Headers</h4>
@ -780,7 +797,7 @@ export default class Run extends Component {
</div>
</Spin>
<p style={{ display: this.state.resStatusCode===null ? '' : 'none' }}>发送请求后在这里查看返回结果</p>
<p style={{ display: this.state.resStatusCode === null ? '' : 'none' }}>发送请求后在这里查看返回结果</p>
<h2 className="interface-title">数据结构验证
<Switch style={{ verticalAlign: 'text-bottom', marginLeft: '8px' }} checked={this.state.resMockTest} onChange={this.onTestSwitched} />

View File

@ -128,6 +128,7 @@ export default {
{ name: 'id', mock: '@id' },
{ name: 'guid', mock: '@guid' },
{ name: '当前时间', mock: '@now' },
{ name: '时间戳', mock: '@timestamp'},
{ name: '日期', mock: '@date' },
{ name: '时间', mock: '@time' },
{ name: '日期时间', mock: '@datetime' },

View File

@ -273,7 +273,7 @@ class InterfaceColContent extends Component {
arr = arr || [];
const obj = {};
arr.forEach(item => {
if (item.name && item.type !== 'file') {
if (item.name && item.enable && item.type !== 'file') {
obj[item.name] = this.handleValue(item.value);
}
})
@ -284,7 +284,7 @@ class InterfaceColContent extends Component {
query = query || [];
const queryObj = {};
query.forEach(item => {
if (item.name) {
if (item.name && item.enable) {
queryObj[item.name] = this.handleValue(item.value);
}
})

View File

@ -19,6 +19,7 @@ var langTools = ace.acequire("ace/ext/language_tools"),
{ name: 'id', mock: '@id' },
{ name: 'guid', mock: '@guid' },
{ name: '当前时间', mock: '@now' },
{ name: '时间戳', mock: '@timestamp'},
{ name: '日期', mock: '@date' },
{ name: '时间', mock: '@time' },
{ name: '日期时间', mock: '@datetime' },

View File

@ -1 +1 @@
module.exports = {"qsso" : {module: require('plugins/yapi-plugin-qsso/client.js'),options: null},"qsso" : {module: require('plugins/yapi-plugin-qsso/client.js'),options: null},"import-postman" : {module: require('exts/yapi-plugin-import-postman/client.js'),options: null},"import-har" : {module: require('exts/yapi-plugin-import-har/client.js'),options: null},"advanced-mock" : {module: require('exts/yapi-plugin-advanced-mock/client.js'),options: null},"import-swagger" : {module: require('exts/yapi-plugin-import-swagger/client.js'),options: null}}
module.exports = {"qsso" : {module: require('plugins/yapi-plugin-qsso/client.js'),options: null},"import-postman" : {module: require('exts/yapi-plugin-import-postman/client.js'),options: null},"import-har" : {module: require('exts/yapi-plugin-import-har/client.js'),options: null},"advanced-mock" : {module: require('exts/yapi-plugin-advanced-mock/client.js'),options: null},"import-swagger" : {module: require('exts/yapi-plugin-import-swagger/client.js'),options: null}}

View File

@ -1,6 +1,13 @@
var strRegex = /\${([a-zA-Z0-9_\.]+)\}/g;
var varSplit = '.';
var mockSplit = '|';
var Mock = require('mockjs');
Mock.Random.extend({
timestamp: function(){
var time = new Date().getTime() + '';
return +time.substr(0, time.length - 3)
}
})
function mock(mockJSON, context) {
context = context || {};

View File

@ -1,6 +1,6 @@
{
"name": "yapi",
"version": "1.1.1",
"version": "1.1.2",
"description": "YAPI",
"main": "index.js",
"scripts": {

View File

@ -4,6 +4,7 @@ const interfaceModel = require('../models/interface.js');
const projectModel = require('../models/project.js');
const baseController = require('./base.js');
const yapi = require('../yapi.js');
const _ = require('underscore');
class interfaceColController extends baseController{
constructor(ctx) {
@ -406,6 +407,11 @@ class interfaceColController extends baseController{
}
}
/**
*
* @param {*} params 接口定义的参数
* @param {*} val 接口case 定义的参数值
*/
handleParamsValue(params, val){
let value = {};
try{
@ -419,7 +425,10 @@ class interfaceColController extends baseController{
})
params.forEach((item, index)=>{
if(!value[item.name] || typeof value[item.name] !== 'object') return null;
params[index].value = value[item.name].value;
params[index].value = value[item.name].value;
if(!_.isUndefined(value[item.name].enable)){
params[index].enable = value[item.name].enable
}
})
return params;
}

View File

@ -23,11 +23,11 @@ class interfaceCase extends baseModel {
name: String, value: String
}],
req_query: [{
name: String, value: String
name: String, value: String, enable: {type: Boolean, default: true}
}],
req_body_form: [{
name: String, value: String
name: String, value: String, enable: {type: Boolean, default: true}
}],
req_body_other: String,
test_res_body: String,