mirror of
https://github.com/YMFE/yapi.git
synced 2025-04-06 15:00:26 +08:00
### Features
This commit is contained in:
parent
c5916568fc
commit
40b1da811e
@ -1,4 +1,12 @@
|
||||
|
||||
## 1.1.2
|
||||
### Features
|
||||
* 接口运行增加了 query 和 body 的 enable 选项,可选择是否请求该字段
|
||||
* Mock 支持了时间戳占位符 @timestamp
|
||||
|
||||
### Bug Fixed
|
||||
* 修复了接口集运行功能会忽略 domain path 的 bug
|
||||
|
||||
## 1.1.1
|
||||
### Features
|
||||
* 添加插件开发文档
|
||||
|
@ -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" />
|
||||
|
||||
{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>
|
||||
|
||||
{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} />
|
||||
|
@ -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' },
|
||||
|
@ -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);
|
||||
}
|
||||
})
|
||||
|
@ -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' },
|
||||
|
@ -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}}
|
@ -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 || {};
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "yapi",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"description": "YAPI",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user