feat(接口测试): 处理变量
This commit is contained in:
parent
01e22c9f1a
commit
b63c136fb5
|
@ -3,7 +3,7 @@
|
||||||
<span class="kv-description" v-if="description">
|
<span class="kv-description" v-if="description">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</span>
|
</span>
|
||||||
<div class="kv-row" v-for="(item, index) in items" :key="index">
|
<div class="kv-row" v-for="(item, index) in parameters" :key="index">
|
||||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-input v-if="!suggestions" :disabled="isReadOnly" v-model="item.name" size="small" maxlength="200"
|
<el-input v-if="!suggestions" :disabled="isReadOnly" v-model="item.name" size="small" maxlength="200"
|
||||||
|
@ -39,23 +39,19 @@
|
||||||
:visible.sync="itemValueVisible"
|
:visible.sync="itemValueVisible"
|
||||||
class="advanced-item-value"
|
class="advanced-item-value"
|
||||||
width="70%">
|
width="70%">
|
||||||
<el-tabs tab-position="top" style="height: 50vh;">
|
<el-tabs tab-position="top" style="height: 50vh;" @tab-click="selectTab">
|
||||||
<el-tab-pane :label="$t('api_test.request.parameters_advance_mock')">
|
<el-tab-pane :label="$t('api_test.request.parameters_advance_mock')">
|
||||||
<el-row type="flex" :gutter="20" style="overflow-x: auto;">
|
<el-row type="flex" :gutter="20">
|
||||||
<el-col :span="6">
|
<el-col :span="6" class="col-height">
|
||||||
<el-autocomplete
|
<div>
|
||||||
:disabled="isReadOnly"
|
<el-input size="small" v-model="filterText"
|
||||||
size="small"
|
:placeholder="$t('api_test.request.parameters_mock_filter_tips')"/>
|
||||||
class="input-with-autocomplete"
|
<el-tree class="filter-tree" ref="tree" :data="mockFuncs" :props="treeProps"
|
||||||
v-model="itemValue"
|
default-expand-all @node-click="selectVariable"
|
||||||
:fetch-suggestions="funcSearch"
|
:filter-node-method="filterNode"></el-tree>
|
||||||
:placeholder="valueText"
|
</div>
|
||||||
value-key="name"
|
|
||||||
highlight-first-item
|
|
||||||
@select="change">
|
|
||||||
</el-autocomplete>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" v-for="(itemFunc, itemIndex) in itemFuncs" :key="itemIndex">
|
<el-col :span="6" v-for="(itemFunc, itemIndex) in mockVariableFuncs" :key="itemIndex">
|
||||||
<div v-for="(func, funcIndex) in funcs"
|
<div v-for="(func, funcIndex) in funcs"
|
||||||
:key="`${itemIndex}-${funcIndex}`">
|
:key="`${itemIndex}-${funcIndex}`">
|
||||||
<el-row>
|
<el-row>
|
||||||
|
@ -75,28 +71,50 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="变量">
|
<el-tab-pane label="变量">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="6">
|
<el-col :span="6" class="col-height">
|
||||||
<div v-if="environment">
|
<div v-if="environment">
|
||||||
<el-tree :data="environmentParams" :props="{ children: 'children', label: 'name'}"></el-tree>
|
<p>{{ $t('api_test.environment.environment') }}</p>
|
||||||
|
<el-tree :data="environmentParams" :props="treeProps" @node-click="selectVariable"></el-tree>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="scenario">
|
<div v-if="scenario">
|
||||||
<el-tree :data="scenarioParams" :props="{ children: 'children', label: 'name'}"></el-tree>
|
<p>{{ $t('api_test.scenario.scenario') }}</p>
|
||||||
|
<el-tree :data="scenarioParams" :props="treeProps" @node-click="selectVariable"></el-tree>
|
||||||
|
</div>
|
||||||
|
<div v-if="preRequestParams">
|
||||||
|
<p>{{ $t('api_test.request.parameters_pre_request') }}</p>
|
||||||
|
<el-tree :data="preRequestParams" :props="treeProps" @node-click="selectVariable"></el-tree>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6" v-for="(itemFunc, itemIndex) in jmeterVariableFuncs" :key="itemIndex" class="col-height">
|
||||||
|
<div>
|
||||||
|
<div v-for="(func, funcIndex) in jmeterFuncs"
|
||||||
|
:key="`${itemIndex}-${funcIndex}`">
|
||||||
|
<el-row>
|
||||||
|
<el-radio size="mini" v-model="itemFunc.name" :label="func.name"
|
||||||
|
@change="methodChange(itemFunc, func)"/>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
<el-form>
|
||||||
|
<el-form-item>
|
||||||
|
<el-input :placeholder="valueText" size="small"
|
||||||
|
v-model="itemValue"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
<div style="padding-top: 10px;">
|
<div style="padding-top: 10px;">
|
||||||
<el-row type="flex" align="middle">
|
<el-row type="flex" align="middle">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-button size="small" type="primary" plain @click="saveAdvanced()">
|
<el-button size="small" type="primary" plain @click="saveAdvanced()">
|
||||||
{{ $t('commons.save') }}
|
{{ $t('commons.save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="small" type="info" plain @click="addFunc()">
|
<el-button size="small" type="info" plain @click="addFunc()" v-if="currentTab === 0">
|
||||||
{{ $t('api_test.request.parameters_advance_add_func') }}
|
{{ $t('api_test.request.parameters_advance_add_func') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="small" type="success" plain @click="showPreview()">
|
<el-button size="small" type="success" plain @click="showPreview()" v-if="currentTab === 0">
|
||||||
{{ $t('api_test.request.parameters_preview') }}
|
{{ $t('api_test.request.parameters_preview') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -110,8 +128,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {KeyValue, Scenario} from "../model/ScenarioModel";
|
import {HttpRequest, KeyValue, Scenario} from "../model/ScenarioModel";
|
||||||
import {MOCKJS_FUNC} from "@/common/js/constants";
|
import {JMETER_FUNC, MOCKJS_FUNC} from "@/common/js/constants";
|
||||||
import {calculate} from "@/business/components/api/test/model/ScenarioModel";
|
import {calculate} from "@/business/components/api/test/model/ScenarioModel";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -121,7 +139,7 @@ export default {
|
||||||
keyPlaceholder: String,
|
keyPlaceholder: String,
|
||||||
valuePlaceholder: String,
|
valuePlaceholder: String,
|
||||||
description: String,
|
description: String,
|
||||||
items: Array,
|
request: HttpRequest,
|
||||||
environment: Object,
|
environment: Object,
|
||||||
scenario: Scenario,
|
scenario: Scenario,
|
||||||
isReadOnly: {
|
isReadOnly: {
|
||||||
|
@ -131,27 +149,53 @@ export default {
|
||||||
suggestions: Array
|
suggestions: Array
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
if (this.request) {
|
||||||
|
this.parameters = this.request.parameters;
|
||||||
|
}
|
||||||
if (this.scenario) {
|
if (this.scenario) {
|
||||||
let variables = this.scenario.variables;
|
let variables = this.scenario.variables;
|
||||||
this.scenarioParams = [
|
this.scenarioParams = [
|
||||||
{
|
{
|
||||||
name: this.scenario.name,
|
name: this.scenario.name,
|
||||||
children: variables.filter(v => v.name),
|
children: variables.filter(v => v.name).map(v => {
|
||||||
|
return {name: v.name, value: '${' + v.name + '}'}
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
if (this.environment) {
|
||||||
if (this.environment) {
|
let variables = JSON.parse(this.environment.variables);
|
||||||
let variables = JSON.parse(this.environment.variables);
|
this.environmentParams = [
|
||||||
this.environmentParams = [
|
{
|
||||||
{
|
name: this.environment.name,
|
||||||
name: this.environment.name,
|
children: variables.filter(v => v.name).map(v => {
|
||||||
children: variables.filter(v => v.name),
|
return {name: v.name, value: '${' + v.name + '}'}
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
let i = this.scenario.requests.indexOf(this.request);
|
||||||
|
this.preRequests = this.scenario.requests.slice(0, i);
|
||||||
|
this.preRequests.forEach(r => {
|
||||||
|
let js = r.extract.json.map(v => {
|
||||||
|
return {name: v.variable, value: v.value}
|
||||||
|
});
|
||||||
|
let xs = r.extract.xpath.map(v => {
|
||||||
|
return {name: v.variable, value: v.value}
|
||||||
|
});
|
||||||
|
let rx = r.extract.regex.map(v => {
|
||||||
|
return {name: v.variable, value: v.value}
|
||||||
|
});
|
||||||
|
let vs = [...js, ...xs, ...rx];
|
||||||
|
if (vs.length > 0) {
|
||||||
|
this.preRequestParams.push({name: r.name, children: vs});
|
||||||
}
|
}
|
||||||
];
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
filterText: '',
|
||||||
itemValueVisible: false,
|
itemValueVisible: false,
|
||||||
itemValue: null,
|
itemValue: null,
|
||||||
funcs: [
|
funcs: [
|
||||||
|
@ -178,14 +222,26 @@ export default {
|
||||||
{name: "number"}
|
{name: "number"}
|
||||||
],
|
],
|
||||||
itemValuePreview: null,
|
itemValuePreview: null,
|
||||||
itemFuncs: [],
|
mockVariableFuncs: [],
|
||||||
currentFunc: "",
|
jmeterVariableFuncs: [],
|
||||||
mockFuncs: MOCKJS_FUNC,
|
currentTab: 0,
|
||||||
|
mockFuncs: MOCKJS_FUNC.map(f => {
|
||||||
|
return {name: f.name, value: f.name}
|
||||||
|
}),
|
||||||
|
jmeterFuncs: JMETER_FUNC,
|
||||||
environmentParams: [],
|
environmentParams: [],
|
||||||
scenarioParams: [],
|
scenarioParams: [],
|
||||||
|
parameters: [],
|
||||||
|
preRequests: [],
|
||||||
|
preRequestParams: [],
|
||||||
|
treeProps: {children: 'children', label: 'name'}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
filterText(val) {
|
||||||
|
this.$refs.tree.filter(val);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
keyText() {
|
keyText() {
|
||||||
return this.keyPlaceholder || this.$t("api_test.key");
|
return this.keyPlaceholder || this.$t("api_test.key");
|
||||||
|
@ -197,16 +253,16 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
remove: function (index) {
|
remove: function (index) {
|
||||||
this.items.splice(index, 1);
|
this.parameters.splice(index, 1);
|
||||||
this.$emit('change', this.items);
|
this.$emit('change', this.parameters);
|
||||||
},
|
},
|
||||||
change: function () {
|
change: function () {
|
||||||
let isNeedCreate = true;
|
let isNeedCreate = true;
|
||||||
let removeIndex = -1;
|
let removeIndex = -1;
|
||||||
this.items.forEach((item, index) => {
|
this.parameters.forEach((item, index) => {
|
||||||
if (!item.name && !item.value) {
|
if (!item.name && !item.value) {
|
||||||
// 多余的空行
|
// 多余的空行
|
||||||
if (index !== this.items.length - 1) {
|
if (index !== this.parameters.length - 1) {
|
||||||
removeIndex = index;
|
removeIndex = index;
|
||||||
}
|
}
|
||||||
// 没有空行,需要创建空行
|
// 没有空行,需要创建空行
|
||||||
|
@ -214,13 +270,13 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (isNeedCreate) {
|
if (isNeedCreate) {
|
||||||
this.items.push(new KeyValue());
|
this.parameters.push(new KeyValue());
|
||||||
}
|
}
|
||||||
this.$emit('change', this.items);
|
this.$emit('change', this.parameters);
|
||||||
// TODO 检查key重复
|
// TODO 检查key重复
|
||||||
},
|
},
|
||||||
isDisable: function (index) {
|
isDisable: function (index) {
|
||||||
return this.items.length - 1 === index;
|
return this.parameters.length - 1 === index;
|
||||||
},
|
},
|
||||||
querySearch(queryString, cb) {
|
querySearch(queryString, cb) {
|
||||||
let suggestions = this.suggestions;
|
let suggestions = this.suggestions;
|
||||||
|
@ -243,6 +299,17 @@ export default {
|
||||||
return (func.name.toLowerCase().indexOf(queryString.toLowerCase()) > -1);
|
return (func.name.toLowerCase().indexOf(queryString.toLowerCase()) > -1);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
filterNode(value, data) {
|
||||||
|
if (!value) return true;
|
||||||
|
return data.name.indexOf(value) !== -1;
|
||||||
|
},
|
||||||
|
selectVariable(node) {
|
||||||
|
this.itemValue = node.value;
|
||||||
|
},
|
||||||
|
selectTab(tab) {
|
||||||
|
this.currentTab = +tab.index;
|
||||||
|
this.itemValue = null;
|
||||||
|
},
|
||||||
showPreview() {
|
showPreview() {
|
||||||
// 找到变量本身
|
// 找到变量本身
|
||||||
if (!this.itemValue) {
|
if (!this.itemValue) {
|
||||||
|
@ -253,7 +320,7 @@ export default {
|
||||||
this.itemValue = this.itemValue.substring(0, index).trim();
|
this.itemValue = this.itemValue.substring(0, index).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.itemFuncs.forEach(f => {
|
this.mockVariableFuncs.forEach(f => {
|
||||||
if (!f.name) {
|
if (!f.name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -266,19 +333,19 @@ export default {
|
||||||
this.itemValuePreview = calculate(this.itemValue);
|
this.itemValuePreview = calculate(this.itemValue);
|
||||||
},
|
},
|
||||||
methodChange(itemFunc, func) {
|
methodChange(itemFunc, func) {
|
||||||
let index = this.itemFuncs.indexOf(itemFunc);
|
let index = this.mockVariableFuncs.indexOf(itemFunc);
|
||||||
this.itemFuncs = this.itemFuncs.slice(0, index);
|
this.mockVariableFuncs = this.mockVariableFuncs.slice(0, index);
|
||||||
// 这里要用 deep copy
|
// 这里要用 deep copy
|
||||||
this.itemFuncs.push(JSON.parse(JSON.stringify(func)));
|
this.mockVariableFuncs.push(JSON.parse(JSON.stringify(func)));
|
||||||
this.showPreview();
|
this.showPreview();
|
||||||
},
|
},
|
||||||
addFunc() {
|
addFunc() {
|
||||||
if (this.itemFuncs.length > 4) {
|
if (this.mockVariableFuncs.length > 4) {
|
||||||
this.$info(this.$t('api_test.request.parameters_advance_add_func_limit'));
|
this.$info(this.$t('api_test.request.parameters_advance_add_func_limit'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.itemFuncs.length > 0) {
|
if (this.mockVariableFuncs.length > 0) {
|
||||||
let func = this.itemFuncs[this.itemFuncs.length - 1];
|
let func = this.mockVariableFuncs[this.mockVariableFuncs.length - 1];
|
||||||
if (!func.name) {
|
if (!func.name) {
|
||||||
this.$warning(this.$t('api_test.request.parameters_advance_add_func_error'));
|
this.$warning(this.$t('api_test.request.parameters_advance_add_func_error'));
|
||||||
return;
|
return;
|
||||||
|
@ -292,24 +359,24 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.itemFuncs.push({name: '', params: []});
|
this.mockVariableFuncs.push({name: '', params: []});
|
||||||
},
|
},
|
||||||
advanced(item) {
|
advanced(item) {
|
||||||
this.currentItem = item;
|
this.currentItem = item;
|
||||||
this.itemValueVisible = true;
|
this.itemValueVisible = true;
|
||||||
this.itemValue = '';
|
this.itemValue = '';
|
||||||
this.itemValuePreview = null;
|
this.itemValuePreview = null;
|
||||||
this.itemFuncs = [];
|
this.mockVariableFuncs = [];
|
||||||
},
|
},
|
||||||
saveAdvanced() {
|
saveAdvanced() {
|
||||||
this.currentItem.value = this.itemValue;
|
this.currentItem.value = this.itemValue;
|
||||||
this.itemValueVisible = false;
|
this.itemValueVisible = false;
|
||||||
this.itemFuncs = [];
|
this.mockVariableFuncs = [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.items.length === 0) {
|
if (this.parameters.length === 0) {
|
||||||
this.items.push(new KeyValue());
|
this.parameters.push(new KeyValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,4 +407,8 @@ export default {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.col-height {
|
||||||
|
height: 40vh;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -45,9 +45,11 @@
|
||||||
|
|
||||||
<el-tabs v-model="activeName">
|
<el-tabs v-model="activeName">
|
||||||
<el-tab-pane :label="$t('api_test.request.parameters')" name="parameters">
|
<el-tab-pane :label="$t('api_test.request.parameters')" name="parameters">
|
||||||
<ms-api-variable :is-read-only="isReadOnly" :items="request.parameters"
|
<ms-api-variable :is-read-only="isReadOnly"
|
||||||
|
:request="request"
|
||||||
:environment="request.environment"
|
:environment="request.environment"
|
||||||
:scenario="scenario"
|
:scenario="scenario"
|
||||||
|
:extract="request.extract"
|
||||||
:description="$t('api_test.request.parameters_desc')"/>
|
:description="$t('api_test.request.parameters_desc')"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('api_test.request.headers')" name="headers">
|
<el-tab-pane :label="$t('api_test.request.headers')" name="headers">
|
||||||
|
|
|
@ -368,6 +368,7 @@ export default {
|
||||||
please_save_test: "Please Save Test First",
|
please_save_test: "Please Save Test First",
|
||||||
},
|
},
|
||||||
scenario: {
|
scenario: {
|
||||||
|
scenario: "Scenario",
|
||||||
dubbo: "Dubbo Config",
|
dubbo: "Dubbo Config",
|
||||||
config: "Scenario Config",
|
config: "Scenario Config",
|
||||||
input_name: "Please enter the scenario name",
|
input_name: "Please enter the scenario name",
|
||||||
|
@ -402,7 +403,8 @@ export default {
|
||||||
parameters_filter_tips: "Only support MockJs function result preview",
|
parameters_filter_tips: "Only support MockJs function result preview",
|
||||||
parameters_advance: "Advanced parameter settings",
|
parameters_advance: "Advanced parameter settings",
|
||||||
parameters_preview: "Preview",
|
parameters_preview: "Preview",
|
||||||
parameters_preview_warning: "Please enter the template first",
|
parameters_mock_filter_tips: "Please enter keywords to filter",
|
||||||
|
parameters_pre_request: "Pre-request extraction",
|
||||||
parameters_advance_mock: "Mock Data",
|
parameters_advance_mock: "Mock Data",
|
||||||
parameters_advance_add_func: "Add Function",
|
parameters_advance_add_func: "Add Function",
|
||||||
parameters_advance_add_func_limit: "Support up to 5 functions",
|
parameters_advance_add_func_limit: "Support up to 5 functions",
|
||||||
|
|
|
@ -369,6 +369,7 @@ export default {
|
||||||
please_save_test: "请先保存测试",
|
please_save_test: "请先保存测试",
|
||||||
},
|
},
|
||||||
scenario: {
|
scenario: {
|
||||||
|
scenario: "场景",
|
||||||
dubbo: "Dubbo配置",
|
dubbo: "Dubbo配置",
|
||||||
config: "场景配置",
|
config: "场景配置",
|
||||||
input_name: "请输入场景名称",
|
input_name: "请输入场景名称",
|
||||||
|
@ -405,7 +406,8 @@ export default {
|
||||||
parameters_filter_tips: "只支持 MockJs 函数结果预览",
|
parameters_filter_tips: "只支持 MockJs 函数结果预览",
|
||||||
parameters_advance: "高级参数设置",
|
parameters_advance: "高级参数设置",
|
||||||
parameters_preview: "预览",
|
parameters_preview: "预览",
|
||||||
parameters_preview_warning: "请先输入模版",
|
parameters_mock_filter_tips: "请输入关键字进行过滤",
|
||||||
|
parameters_pre_request: "前置请求提取",
|
||||||
parameters_advance_mock: "Mock 数据",
|
parameters_advance_mock: "Mock 数据",
|
||||||
parameters_advance_add_func: "添加函数",
|
parameters_advance_add_func: "添加函数",
|
||||||
parameters_advance_add_func_limit: "最多支持5个函数",
|
parameters_advance_add_func_limit: "最多支持5个函数",
|
||||||
|
|
|
@ -367,6 +367,7 @@ export default {
|
||||||
please_save_test: "請先保存測試",
|
please_save_test: "請先保存測試",
|
||||||
},
|
},
|
||||||
scenario: {
|
scenario: {
|
||||||
|
scenario: "場景",
|
||||||
dubbo: "Dubbo配寘",
|
dubbo: "Dubbo配寘",
|
||||||
creator: "創建人",
|
creator: "創建人",
|
||||||
config: "場景配寘",
|
config: "場景配寘",
|
||||||
|
@ -402,7 +403,8 @@ export default {
|
||||||
parameters_filter_tips: "只支持MockJs函數結果預覽",
|
parameters_filter_tips: "只支持MockJs函數結果預覽",
|
||||||
parameters_advance: "高級參數設置",
|
parameters_advance: "高級參數設置",
|
||||||
parameters_preview: "預覽",
|
parameters_preview: "預覽",
|
||||||
parameters_preview_warning: "請先輸入模版",
|
parameters_mock_filter_tips: "請輸入關鍵字進行過濾",
|
||||||
|
parameters_pre_request: "前置請求提取",
|
||||||
parameters_advance_mock: "Mock 數據",
|
parameters_advance_mock: "Mock 數據",
|
||||||
parameters_advance_add_func: "添加函數",
|
parameters_advance_add_func: "添加函數",
|
||||||
parameters_advance_add_func_limit: "最多支持5個函數",
|
parameters_advance_add_func_limit: "最多支持5個函數",
|
||||||
|
|
Loading…
Reference in New Issue