fix(接口测试): 接口测试部分参数样式改为表格,并针对一系列问题汇总进行优化

--bug=1020653 --user=宋天阳 【接口测试】接口高级设置问题汇总 {#_orginal_url#}
This commit is contained in:
song-tianyang 2022-12-05 19:04:44 +08:00 committed by 建国
parent 4d4826f7c3
commit 6fc4f75e10
11 changed files with 447 additions and 238 deletions

View File

@ -13,6 +13,9 @@
{{ this.$t('commons.import') }} {{ this.$t('commons.import') }}
</el-button> </el-button>
<div style="float: right"> <div style="float: right">
<el-button style="margin-right: 5px" type="text" size="mini" @click="expandAll">
{{ expandTitle }}
</el-button>
<api-params-config <api-params-config
v-if="apiJsonSchemaConfigFields" v-if="apiJsonSchemaConfigFields"
:storage-key="storageKey" :storage-key="storageKey"
@ -28,6 +31,7 @@
:disabled="jsonSchemaDisable || isReadOnly" :disabled="jsonSchemaDisable || isReadOnly"
:value="schema" :value="schema"
:show-mock-vars="showMockVars" :show-mock-vars="showMockVars"
:expand-all-params="expandAllParams"
:scenario-definition="scenarioDefinition" :scenario-definition="scenarioDefinition"
@editScenarioAdvance="editScenarioAdvance" @editScenarioAdvance="editScenarioAdvance"
:param-columns="apiJsonSchemaShowColumns" :param-columns="apiJsonSchemaShowColumns"
@ -128,6 +132,7 @@ export default {
}, },
loading: false, loading: false,
reloadedApiVariable: true, reloadedApiVariable: true,
expandAllParams: false,
preview: null, preview: null,
activeName: 'apiTemplate', activeName: 'apiTemplate',
storageKey: 'API_JSON_SCHEMA_SHOW_FIELD', storageKey: 'API_JSON_SCHEMA_SHOW_FIELD',
@ -170,6 +175,14 @@ export default {
editScenarioAdvance(data) { editScenarioAdvance(data) {
this.$emit('editScenarioAdvance', data); this.$emit('editScenarioAdvance', data);
}, },
expandAll() {
this.expandAllParams = !this.expandAllParams;
},
},
computed: {
expandTitle() {
return this.expandAllParams ? this.$t('commons.close_all') : this.$t('commons.expand_all');
},
}, },
}; };
</script> </script>

View File

@ -33,7 +33,7 @@
</el-tooltip> </el-tooltip>
</el-col> </el-col>
<el-col style="width: 120px; padding: 0 5px"> <el-col style="width: 120px; padding: 0 5px" class="ms-col-name">
<el-select <el-select
v-model="pickValue.type" v-model="pickValue.type"
:disabled="disabled || disabledType" :disabled="disabled || disabledType"
@ -44,7 +44,7 @@
<el-option :key="t" :value="t" :label="t" v-for="t in types" /> <el-option :key="t" :value="t" :label="t" v-for="t in types" />
</el-select> </el-select>
</el-col> </el-col>
<el-col style="min-width: 200px; padding: 0 5px"> <el-col class="ms-col-name" style="min-width: 200px; padding: 0 5px">
<ms-mock <ms-mock
:disabled=" :disabled="
disabled || disabled ||
@ -60,10 +60,10 @@
style="width: 100%" style="width: 100%"
@editScenarioAdvance="editScenarioAdvance" /> @editScenarioAdvance="editScenarioAdvance" />
</el-col> </el-col>
<el-col v-if="showColumns('MIX_LENGTH')" class="item kv-select ms-col-name" style="width: 150px; padding: 0 5px">
<el-col v-if="showColumns('MIX_LENGTH')" class="item kv-select" style="width: 150px; padding: 0 5px">
<el-input-number <el-input-number
:min="0" :min="0"
:controls="false"
v-model="pickValue.minLength" v-model="pickValue.minLength"
:placeholder="$t('schema.minLength')" :placeholder="$t('schema.minLength')"
size="small" size="small"
@ -77,9 +77,10 @@
style="width: 140px" /> style="width: 140px" />
</el-col> </el-col>
<el-col v-if="showColumns('MAX_LENGTH')" class="item kv-select" style="width: 150px; padding: 0 5px"> <el-col v-if="showColumns('MAX_LENGTH')" class="item kv-select ms-col-name" style="width: 150px; padding: 0 5px">
<el-input-number <el-input-number
:min="0" :min="0"
:controls="false"
v-model="pickValue.maxLength" v-model="pickValue.maxLength"
:placeholder="$t('schema.maxLength')" :placeholder="$t('schema.maxLength')"
size="small" size="small"
@ -93,7 +94,7 @@
style="width: 140px" /> style="width: 140px" />
</el-col> </el-col>
<el-col v-if="showColumns('DEFAULT')" class="item kv-select" style="min-width: 200px; padding: 0 5px"> <el-col v-if="showColumns('DEFAULT')" class="item kv-select ms-col-name" style="min-width: 200px; padding: 0 5px">
<el-input <el-input
:disabled=" :disabled="
disabled || disabled ||
@ -108,7 +109,7 @@
style="width: 100%" style="width: 100%"
size="small" /> size="small" />
</el-col> </el-col>
<el-col v-if="showColumns('PATTERN')" style="min-width: 200px; padding: 0 5px"> <el-col v-if="showColumns('PATTERN')" class="ms-col-name" style="min-width: 200px; padding: 0 5px">
<el-input <el-input
:disabled=" :disabled="
disabled || disabled ||
@ -122,7 +123,7 @@
:placeholder="$t('schema.pattern')" :placeholder="$t('schema.pattern')"
size="small" /> size="small" />
</el-col> </el-col>
<el-col v-if="showColumns('FORMAT')" style="min-width: 120px; padding: 0 5px"> <el-col v-if="showColumns('FORMAT')" class="ms-col-name" style="min-width: 120px; padding: 0 5px">
<div v-if="advancedAttr.format"> <div v-if="advancedAttr.format">
<el-select <el-select
:disabled=" :disabled="
@ -143,17 +144,23 @@
<el-input :disabled="true" size="small" :placeholder="$t('schema.format')"></el-input> <el-input :disabled="true" size="small" :placeholder="$t('schema.format')"></el-input>
</div> </div>
</el-col> </el-col>
<el-col v-if="showColumns('ENUM')" style="min-width: 300px; padding: 0 5px"> <el-col v-if="showColumns('ENUM')" class="ms-col-name" style="min-width: 300px; padding: 0 5px">
<el-input <el-input
type="textarea" type="textarea"
autosize :autosize="{ minRows: 1, maxRows: 2 }"
:disabled="disabled" :disabled="
disabled ||
pickValue.type === 'object' ||
pickKey === 'root' ||
pickValue.type === 'array' ||
pickValue.type === 'null'
"
v-model="pickValue.enum" v-model="pickValue.enum"
class="ms-col-title" class="ms-col-title"
:placeholder="$t('schema.enum')" :placeholder="$t('schema.enum')"
size="small" /> size="small" />
</el-col> </el-col>
<el-col v-if="showColumns('DESCRIPTION')" style="min-width: 300px; padding: 0 5px"> <el-col v-if="showColumns('DESCRIPTION')" class="ms-col-name" style="min-width: 300px; padding: 0 5px">
<el-input <el-input
:disabled="disabled" :disabled="disabled"
v-model="pickValue.description" v-model="pickValue.description"
@ -162,7 +169,7 @@
size="small" /> size="small" />
</el-col> </el-col>
<!--其余操作--> <!--其余操作-->
<el-col style="width: 220px" class="col-item-setting" v-if="!disabled"> <el-col style="width: 220px" class="col-item-setting ms-col-name" v-if="!disabled">
<div style="width: 80px"> <div style="width: 80px">
<el-tooltip class="item" effect="dark" :content="$t('schema.adv_setting')" placement="top"> <el-tooltip class="item" effect="dark" :content="$t('schema.adv_setting')" placement="top">
<i class="el-icon-setting" @click="onSetting" /> <i class="el-icon-setting" @click="onSetting" />
@ -182,6 +189,7 @@
v-for="(item, key, index) in pickValue.properties" v-for="(item, key, index) in pickValue.properties"
:value="{ [key]: item }" :value="{ [key]: item }"
:parent="pickValue" :parent="pickValue"
:expand-all-params="expandAllParams"
:key="index" :key="index"
:deep="deep + 1" :deep="deep + 1"
:root="false" :root="false"
@ -202,6 +210,7 @@
v-for="(item, key, index) in pickValue.items" v-for="(item, key, index) in pickValue.items"
:value="{ [key]: item }" :value="{ [key]: item }"
:parent="pickValue" :parent="pickValue"
:expand-all-params="expandAllParams"
:key="index" :key="index"
:deep="deep + 1" :deep="deep + 1"
:root="false" :root="false"
@ -289,6 +298,12 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
expandAllParams: {
type: Boolean,
default() {
return false;
},
},
paramColumns: Array, paramColumns: Array,
showMockVars: { showMockVars: {
type: Boolean, type: Boolean,
@ -393,16 +408,31 @@ export default {
}; };
}, },
created() { created() {
if (this.pickValue) { if (this.expandAllParams) {
if (this.pickValue.hidden === undefined) { this.hidden = false;
this.hidden = this.root ? false : true;
} else {
this.hidden = this.root ? false : this.pickValue.hidden;
}
} else { } else {
this.hidden = true; if (this.pickValue) {
if (this.pickValue.hidden === undefined) {
this.hidden = this.root ? false : true;
} else {
this.hidden = this.root ? false : this.pickValue.hidden;
}
} else {
this.hidden = true;
}
} }
}, },
watch: {
expandAllParams() {
if (this.expandAllParams) {
this.hidden = false;
} else {
if (!this.root) {
this.hidden = true;
}
}
},
},
methods: { methods: {
showColumns(columns) { showColumns(columns) {
if (!this.paramColumns) { if (!this.paramColumns) {

View File

@ -4,170 +4,157 @@
<span class="kv-description" v-if="description"> <span class="kv-description" v-if="description">
{{ description }} {{ description }}
</span> </span>
<el-row> <el-table @cell-dblclick="clickRow" border :show-header="true" row-key="id" :data="parameters" ref="expandTable">
<el-checkbox v-model="isSelectAll" v-if="parameters.length > 1" /> <el-table-column
</el-row> v-for="item in tableColumnArr"
:key="item.id"
<!-- 数据--> :prop="item.prop"
<div class="item kv-row" v-for="(item, index) in parameters" :key="index" style="width: 99%"> :label="item.label"
<el-row type="flex" :gutter="20" justify="space-between" align="middle"> :min-width="getTableMinWidth(item.prop)"
<el-col class="kv-checkbox" v-if="isShowEnable"> show-overflow-tooltip>
<el-checkbox v-if="!isDisable(index)" v-model="item.enable" :disabled="isReadOnly" /> <template v-slot:default="scope">
</el-col> <div v-show="!scope.row.isEdit">
<span style="margin-left: 10px" v-else></span> <div v-if="item.prop === 'required' || item.prop === 'urlEncode'">
<i class="el-icon-top" style="cursor: pointer" @click="moveTop(index)" /> <span class="param-span" v-if="scope.row[item.prop]">{{ $t('commons.yes') }}</span>
<i class="el-icon-bottom" style="cursor: pointer" @click="moveBottom(index)" /> <span class="param-span" v-else>{{ $t('commons.no') }}</span>
</div>
<el-col class="item" style="min-width: 200px; padding: 0 5px"> <div v-else-if="item.prop === 'value' && isActive && scope.row.type === 'file'">
<el-row> <ms-api-body-file-upload :parameter="scope.row" :id="id" :is-read-only="true" :disabled="true" />
<span class="param-header-span" v-if="index === 0"> {{ keyText }}</span> </div>
</el-row> <span v-else>
<el-input {{ scope.row[item.prop] }}
v-if="!suggestions" </span>
:disabled="isReadOnly" </div>
v-model="item.name" <div v-show="scope.row.isEdit">
size="small" <div v-if="item.prop === 'type'">
maxlength="200"
@change="change"
:placeholder="keyText"
show-word-limit>
<template v-slot:prepend>
<el-select <el-select
v-if="type === 'body'" v-if="type === 'body'"
:disabled="isReadOnly" :disabled="isReadOnly"
class="kv-type" v-model="scope.row.type"
v-model="item.type"
@change="typeChange(item)"> @change="typeChange(item)">
<el-option value="text" /> <el-option value="text" />
<el-option value="file" /> <el-option value="file" />
<el-option value="json" /> <el-option value="json" />
</el-select> </el-select>
</template> </div>
</el-input> <div v-else-if="item.prop === 'name'">
<el-input
v-if="!suggestions"
:disabled="isReadOnly"
v-model="scope.row.name"
size="small"
maxlength="200"
@change="change"
:placeholder="keyText">
</el-input>
<el-autocomplete
:disabled="isReadOnly"
v-if="suggestions"
v-model="scope.row.name"
size="small"
:fetch-suggestions="querySearch"
@change="change"
:placeholder="keyText"
show-word-limit />
</div>
<div v-else-if="item.prop === 'required'">
<el-select v-model="scope.row.required" size="small" style="width: 99%">
<el-option v-for="req in requireds" :key="req.id" :label="req.name" :value="req.id" />
</el-select>
</div>
<div v-else-if="item.prop === 'value'">
<div v-if="isActive && scope.row.type !== 'file'">
<el-autocomplete
:disabled="isReadOnly"
size="small"
class="input-with-autocomplete"
v-model="scope.row.value"
:fetch-suggestions="funcSearch"
:placeholder="valueText"
value-key="name"
highlight-first-item
@select="change">
<i slot="suffix" class="el-input__icon el-icon-edit pointer" @click="advanced(item)"></i>
</el-autocomplete>
</div>
<div v-else-if="isActive && scope.row.type === 'file'">
<ms-api-body-file-upload :parameter="scope.row" :id="id" :is-read-only="isReadOnly" />
</div>
<div v-else class="param-div-show">
<span class="param-span">{{ item.value }}</span>
</div>
</div>
<div v-else-if="item.prop === 'contentType'">
<el-input
:disabled="isReadOnly"
v-model="scope.row.contentType"
size="small"
@change="change"
:placeholder="$t('api_test.request.content_type')"
show-word-limit />
</div>
<div v-else-if="item.prop === 'min'">
<el-input-number
:min="0"
v-model="scope.row.min"
:controls="false"
:placeholder="$t('schema.minLength')"
size="small"
style="width: 99%" />
</div>
<div v-else-if="item.prop === 'max'">
<el-input-number
:min="0"
v-model="scope.row.max"
:controls="false"
:placeholder="$t('schema.maxLength')"
size="small"
style="width: 99%" />
</div>
<div v-else-if="item.prop === 'description'">
<el-input
v-model="scope.row.description"
size="small"
maxlength="200"
:placeholder="$t('commons.description')"
show-word-limit>
</el-input>
</div>
<div v-else-if="item.prop === 'urlEncode'">
<el-select v-model="scope.row.urlEncode" size="small" clearable style="width: 100px">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</div>
<div v-else>
{{ item.prop }}
</div>
</div>
</template>
</el-table-column>
<el-autocomplete <el-table-column prop="uuid" :label="$t('commons.operating')" width="140px" show-overflow-tooltip>
:disabled="isReadOnly" <template v-slot:default="scope">
v-if="suggestions" <el-switch
v-model="item.name" size="mini"
size="small" style="margin-right: 5px"
:fetch-suggestions="querySearch" :disabled="!(isShowEnable && !isDisable(scope.$index)) || isReadOnly"
@change="change" v-model="scope.row.enable" />
:placeholder="keyText"
show-word-limit />
</el-col>
<el-col class="item kv-select" style="width: 130px; padding: 0 5px">
<el-row>
<span class="param-header-span" v-if="index === 0">
{{ $t('api_test.definition.document.table_coloum.is_required') }}</span
>
</el-row>
<el-select v-model="item.required" size="small" style="width: 120px">
<el-option v-for="req in requireds" :key="req.id" :label="req.name" :value="req.id" />
</el-select>
</el-col>
<el-col class="item" v-if="isActive && item.type !== 'file'" style="min-width: 200px; padding: 0 5px">
<el-row>
<span class="param-header-span" v-if="index === 0"> {{ valueText }}</span>
</el-row>
<el-autocomplete
:disabled="isReadOnly"
size="small"
class="input-with-autocomplete"
v-model="item.value"
:fetch-suggestions="funcSearch"
:placeholder="valueText"
value-key="name"
highlight-first-item
@select="change">
<i slot="suffix" class="el-input__icon el-icon-edit pointer" @click="advanced(item)"></i>
</el-autocomplete>
</el-col>
<el-col v-if="isActive && item.type === 'file'" class="item" style="min-width: 200px; padding: 0 5px">
<el-row>
<span class="param-header-span" v-if="index === 0"> {{ valueText }}</span>
</el-row>
<ms-api-body-file-upload :parameter="item" :id="id" :is-read-only="isReadOnly" />
</el-col>
<el-col v-if="type === 'body'" class="item kv-select" style="min-width: 160px; padding: 0 5px">
<el-row>
<span class="param-header-span" v-if="index === 0"> {{ $t('api_test.request.content_type') }}</span>
</el-row>
<el-input
:disabled="isReadOnly"
v-model="item.contentType"
size="small"
@change="change"
:placeholder="$t('api_test.request.content_type')"
show-word-limit>
</el-input>
</el-col>
<el-col v-if="showColumns('MIX_LENGTH')" class="item kv-select" style="width: 150px; padding: 0 5px">
<el-row>
<span class="param-header-span" v-if="index === 0"> {{ $t('schema.minLength') }}</span>
</el-row>
<el-input-number
:min="0"
v-model="item.min"
:placeholder="$t('schema.minLength')"
size="small"
style="width: 140px" />
</el-col>
<el-col v-if="showColumns('MAX_LENGTH')" class="item kv-select" style="width: 150px; padding: 0 5px">
<el-row>
<span class="param-header-span" v-if="index === 0"> {{ $t('schema.maxLength') }}</span>
</el-row>
<el-input-number
:min="0"
v-model="item.max"
:placeholder="$t('schema.maxLength')"
size="small"
style="width: 140px" />
</el-col>
<el-col v-if="showColumns('ENCODE')" class="item kv-select" style="width: 130px; padding: 0 5px">
<el-row>
<span class="param-header-span" v-if="index === 0"> {{ $t('commons.encode') }}</span>
</el-row>
<el-select v-model="item.urlEncode" size="small" clearable style="width: 100px">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-col>
<el-col class="item" v-if="showColumns('DESCRIPTION')" style="min-width: 300px; padding: 0 5px">
<el-row>
<span class="param-header-span" v-if="index === 0"> {{ $t('commons.description') }}</span>
</el-row>
<el-input
v-model="item.description"
size="small"
maxlength="200"
:placeholder="$t('commons.description')"
show-word-limit>
</el-input>
</el-col>
<el-col v-if="withMoreSetting" class="item kv-setting">
<el-tooltip effect="dark" :content="$t('schema.adv_setting')" placement="top">
<i class="el-icon-setting" @click="openApiVariableSetting(item)" />
</el-tooltip>
</el-col>
<el-col class="item kv-delete">
<el-button <el-button
size="mini" size="mini"
class="el-icon-delete-solid" class="el-icon-delete-solid"
style="margin-right: 5px"
circle circle
@click="remove(index)" @click="remove(scope.$index)"
:disabled="isDisable(index) || isReadOnly" /> :disabled="isDisable(scope.$index) || isReadOnly" />
</el-col> <i class="el-icon-top" style="cursor: pointer" @click="moveTop(scope.$index)" />
</el-row> <i class="el-icon-bottom" style="cursor: pointer" @click="moveBottom(scope.$index)" />
</div> </template>
</el-table-column>
</el-table>
</div> </div>
<ms-api-variable-advance <ms-api-variable-advance
@ -226,6 +213,10 @@ export default {
type: String, type: String,
default: '', default: '',
}, },
paramType: {
type: String,
default: 'request',
},
appendDialogToBody: { appendDialogToBody: {
type: Boolean, type: Boolean,
default() { default() {
@ -254,6 +245,9 @@ export default {
isSelectAll: true, isSelectAll: true,
isActive: true, isActive: true,
paramColumns: [], paramColumns: [],
storageKey: 'API_PARAMS_SHOW_FIELD',
editRowIndex: -1,
tableColumnArr: [],
options: [ options: [
{ {
value: true, value: true,
@ -291,6 +285,73 @@ export default {
}, },
}, },
methods: { methods: {
closeAllTableDataEdit() {
this.parameters.forEach((item) => {
item.isEdit = false;
});
},
getTableMinWidth(col) {
if (col === 'name') {
return '200px';
} else if (col === 'value') {
return '300px';
} else if (col === 'description') {
return '200px';
} else {
return '120px';
}
},
clickRow(row, column, event) {
this.closeAllTableDataEdit();
if (!this.isReadOnly) {
this.$nextTick(() => {
this.$set(row, 'isEdit', true);
});
}
},
initTableColumn() {
this.tableColumnArr = [];
if (this.type === 'body') {
this.tableColumnArr.push({
id: 0,
prop: 'type',
label: this.$t('api_test.definition.document.request_param') + this.$t('commons.type'),
});
}
this.tableColumnArr.push({ id: 1, prop: 'name', label: this.$t('api_definition.document.name') });
this.tableColumnArr.push({ id: 3, prop: 'required', label: this.$t('api_definition.document.is_required') });
this.tableColumnArr.push({ id: 4, prop: 'value', label: this.$t('api_definition.document.value') });
if (this.type === 'body') {
this.tableColumnArr.push({ id: 2, prop: 'contentType', label: this.$t('api_definition.document.type') });
}
if (this.paramColumns) {
this.paramColumns.forEach((item) => {
let tableColumn = {};
if (item === 'MIX_LENGTH') {
tableColumn.id = 5;
tableColumn.prop = 'min';
tableColumn.label = this.$t('schema.minLength');
} else if (item === 'MAX_LENGTH') {
tableColumn.id = 6;
tableColumn.prop = 'max';
tableColumn.label = this.$t('schema.maxLength');
} else if (item === 'ENCODE') {
tableColumn.id = 7;
tableColumn.prop = 'urlEncode';
tableColumn.label = this.$t('commons.encode');
} else if (item === 'DESCRIPTION') {
tableColumn.id = 8;
tableColumn.prop = 'description';
tableColumn.label = this.$t('commons.description');
} else {
tableColumn = null;
}
if (tableColumn) {
this.tableColumnArr.push(tableColumn);
}
});
}
},
showColumns(columns) { showColumns(columns) {
return this.paramColumns.indexOf(columns) >= 0; return this.paramColumns.indexOf(columns) >= 0;
}, },
@ -359,6 +420,7 @@ export default {
urlEncode: this.urlEncode, urlEncode: this.urlEncode,
uuid: this.uuid(), uuid: this.uuid(),
required: false, required: false,
isEdit: false,
contentType: 'text/plain', contentType: 'text/plain',
}) })
); );
@ -443,6 +505,9 @@ export default {
}, },
}, },
created() { created() {
if (this.paramType === 'response') {
this.storageKey = 'API_RESPONSE_PARAMS_SHOW_FIELD';
}
if (this.parameters.length === 0 || this.parameters[this.parameters.length - 1].name) { if (this.parameters.length === 0 || this.parameters[this.parameters.length - 1].name) {
this.parameters.push( this.parameters.push(
new KeyValue({ new KeyValue({
@ -451,14 +516,25 @@ export default {
required: false, required: false,
urlEncode: this.urlEncode, urlEncode: this.urlEncode,
uuid: this.uuid(), uuid: this.uuid(),
isEdit: false,
contentType: 'text/plain', contentType: 'text/plain',
}) })
); );
} }
let savedApiParamsShowFields = getShowFields('API_PARAMS_SHOW_FIELD'); let savedApiParamsShowFields = getShowFields(this.storageKey);
if (savedApiParamsShowFields) { if (savedApiParamsShowFields) {
this.paramColumns = savedApiParamsShowFields; this.paramColumns = savedApiParamsShowFields;
} }
this.parameters.forEach((item) => {
this.$set(item, 'isEdit', false);
});
this.initTableColumn();
},
activated() {
this.initTableColumn();
},
mounted() {
this.initTableColumn();
}, },
}; };
</script> </script>
@ -515,4 +591,8 @@ export default {
margin-bottom: 5px; margin-bottom: 5px;
font-weight: 600; font-weight: 600;
} }
.param-div-show {
min-height: 16px;
}
</style> </style>

View File

@ -31,9 +31,11 @@
<api-params-config <api-params-config
v-if="apiParamsConfigFields" v-if="apiParamsConfigFields"
@refresh="refreshApiParamsField" @refresh="refreshApiParamsField"
:storage-key="storageKey"
:api-params-config-fields="apiParamsConfigFields" /> :api-params-config-fields="apiParamsConfigFields" />
</el-row> </el-row>
<ms-api-variable <ms-api-variable
:param-type="bodyType"
:with-more-setting="true" :with-more-setting="true"
:is-read-only="isReadOnly" :is-read-only="isReadOnly"
:parameters="body.kvs" :parameters="body.kvs"
@ -131,6 +133,10 @@ export default {
}; };
}, },
}, },
bodyType: {
type: String,
default: 'request',
},
headers: Array, headers: Array,
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
@ -153,9 +159,9 @@ export default {
codeEditActive: true, codeEditActive: true,
hasOwnProperty: Object.prototype.hasOwnProperty, hasOwnProperty: Object.prototype.hasOwnProperty,
propIsEnumerable: Object.prototype.propertyIsEnumerable, propIsEnumerable: Object.prototype.propertyIsEnumerable,
storageKey: 'API_PARAMS_SHOW_FIELD',
}; };
}, },
watch: { watch: {
'body.typeChange'() { 'body.typeChange'() {
this.reloadCodeEdit(); this.reloadCodeEdit();
@ -370,6 +376,9 @@ export default {
}, },
}, },
created() { created() {
if (this.bodyType === 'response') {
this.storageKey = 'API_RESPONSE_PARAMS_SHOW_FIELD';
}
if (!this.body.type) { if (!this.body.type) {
this.body.type = BODY_TYPE.FORM_DATA; this.body.type = BODY_TYPE.FORM_DATA;
} }

View File

@ -1,8 +1,15 @@
<template> <template>
<span v-if="showHide"> <span v-if="showHide">
<el-upload action="#" class="ms-upload-header" list-type="picture-card" :file-list="parameter.files" ref="upload"> <el-upload
action="#"
class="ms-upload-header"
list-type="picture-card"
:disabled="disabled"
:file-list="parameter.files"
ref="upload">
<div class="upload-default" @click.stop> <div class="upload-default" @click.stop>
<el-popover placement="right" trigger="hover"> <i class="el-icon-plus" v-show="disabled" slot="reference" />
<el-popover placement="right" v-show="!disabled" trigger="hover">
<div> <div>
<el-upload <el-upload
action="#" action="#"
@ -64,7 +71,6 @@ export default {
}, },
data() { data() {
return { return {
disabled: false,
file: {}, file: {},
showHide: true, showHide: true,
}; };
@ -79,6 +85,10 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
disabled: {
type: Boolean,
default: false,
},
}, },
methods: { methods: {
exist() { exist() {

View File

@ -60,18 +60,6 @@
:label="item.label" :label="item.label"
show-overflow-tooltip> show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column type="expand" v-if="tableCanExpand" :label="getCollapseOption()" width="80px">
<template slot="header">
<el-button type="text" size="mini" @click="expandAllRows">
<span :id="tableExpandButtonId">
{{ expandTitle }}
</span>
</el-button>
</template>
<template v-slot:default="scope">
<table-advanced-setting :table-data="scope.row"></table-advanced-setting>
</template>
</el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>

View File

@ -25,18 +25,6 @@
:prop="item.prop" :prop="item.prop"
:label="item.label" :label="item.label"
show-overflow-tooltip /> show-overflow-tooltip />
<el-table-column type="expand" :label="getCollapseOption()" width="80px">
<template slot="header">
<el-button type="text" size="mini" @click="expandAllRows">
<span :id="tableExpandButtonId">
{{ expandTitle }}
</span>
</el-button>
</template>
<template v-slot:default="scope">
<table-advanced-setting :table-data="scope.row"></table-advanced-setting>
</template>
</el-table-column>
</el-table> </el-table>
</div> </div>

View File

@ -2,36 +2,24 @@
<div> <div>
<el-row class="apiInfoRow"> <el-row class="apiInfoRow">
<div> <div>
<el-row>
<div style="float: right">
<api-params-config
v-if="apiParamsConfigFields"
@refresh="refreshApiParamsField"
:api-params-config-fields="apiParamsConfigFields" />
</div>
</el-row>
<el-table <el-table
border border
v-if="formParamTypes.includes(apiInfo.responseBodyParamType)" v-if="formParamTypes.includes(apiInfo.responseBodyParamType)"
:data="getJsonArr(apiInfo.responseBodyFormData)" :data="getJsonArr(apiInfo.responseBodyFormData)"
class="test-content document-table"> class="test-content document-table">
<el-table-column <el-table-column
prop="name" v-for="item in tableColumnArr"
:label="$t('api_definition.document.name')" :key="item.id"
min-width="120px" :prop="item.prop"
show-overflow-tooltip /> :label="item.label"
<el-table-column
prop="contentType"
:label="$t('api_definition.document.type')"
min-width="120px"
show-overflow-tooltip />
<el-table-column
prop="description"
:label="$t('api_definition.document.desc')"
min-width="280px"
show-overflow-tooltip />
<el-table-column
prop="required"
:label="$t('api_definition.document.is_required')"
:formatter="formatBoolean"
min-width="80px"
show-overflow-tooltip />
<el-table-column
prop="value"
:label="$t('api_definition.document.default_value')"
min-width="120px"
show-overflow-tooltip /> show-overflow-tooltip />
</el-table> </el-table>
<div v-else-if="apiInfo.responseBodyParamType == 'JSON-SCHEMA'" style="margin-left: 10px"> <div v-else-if="apiInfo.responseBodyParamType == 'JSON-SCHEMA'" style="margin-left: 10px">
@ -62,25 +50,111 @@
<script> <script>
import MsJsonCodeEdit from '@/business/commons/json-schema/JsonSchemaEditor'; import MsJsonCodeEdit from '@/business/commons/json-schema/JsonSchemaEditor';
import { getApiParamsConfigFields, getShowFields } from 'metersphere-frontend/src/utils/custom_field';
import ApiParamsConfig from '@/business/definition/components/request/components/ApiParamsConfig';
export default { export default {
name: 'ApiResponseInfo', name: 'ApiResponseInfo',
components: { MsJsonCodeEdit }, components: { MsJsonCodeEdit, ApiParamsConfig },
data() { data() {
return { return {
active: true, active: true,
formParamTypes: ['form-data', 'x-www-from-urlencoded', 'BINARY'], formParamTypes: ['form-data', 'x-www-from-urlencoded', 'BINARY'],
apiParamsConfigFields: getApiParamsConfigFields(this),
apiParamStorageKey: 'API_RESPONSE_PARAMS_SHOW_FIELD',
tableColumnArr: [],
}; };
}, },
props: { props: {
apiInfo: Object, apiInfo: Object,
}, },
activated() {}, activated() {
created: function () {}, this.formatTableData();
mounted() {}, this.initTableColumn();
},
created: function () {
this.formatTableData();
this.initTableColumn();
},
mounted() {
this.formatTableData();
this.initTableColumn();
},
computed: {}, computed: {},
watch: {}, watch: {},
methods: { methods: {
formatTableData() {
if (this.tableData) {
this.tableData.forEach((item) => {
if (item.urlEncode !== null && item.urlEncode !== undefined) {
if (item.urlEncode === true) {
item.urlEncode = this.$t('commons.yes');
} else {
item.urlEncode = this.$t('commons.no');
}
}
if (item.enable !== null && item.enable !== undefined) {
if (item.enable === true) {
item.enable = this.$t('commons.yes');
} else {
item.enable = this.$t('commons.no');
}
}
});
}
},
refreshApiParamsField() {
this.initTableColumn();
this.reloadedApiVariable = false;
this.$nextTick(() => {
this.reloadedApiVariable = true;
});
},
initTableColumn() {
this.tableColumnArr = [
{ id: 1, prop: 'name', label: this.$t('api_definition.document.name') },
{ id: 2, prop: 'contentType', label: this.$t('api_definition.document.type') },
{
id: 3,
prop: 'enable',
label: this.$t('api_definition.document.is_required'),
},
{
id: 4,
prop: 'value',
label: this.$t('api_definition.document.value'),
},
];
let apiParamConfigArr = getShowFields(this.apiParamStorageKey);
if (apiParamConfigArr) {
apiParamConfigArr.forEach((item) => {
let tableColumn = {};
if (item === 'MIX_LENGTH') {
tableColumn.id = 5;
tableColumn.prop = 'min';
tableColumn.label = this.$t('schema.minLength');
} else if (item === 'MAX_LENGTH') {
tableColumn.id = 6;
tableColumn.prop = 'max';
tableColumn.label = this.$t('schema.maxLength');
} else if (item === 'ENCODE') {
tableColumn.id = 7;
tableColumn.prop = 'urlEncode';
tableColumn.label = this.$t('commons.encode');
} else if (item === 'DESCRIPTION') {
tableColumn.id = 8;
tableColumn.prop = 'description';
tableColumn.label = this.$t('commons.description');
} else {
tableColumn = null;
}
if (tableColumn) {
this.tableColumnArr.push(tableColumn);
}
});
}
},
formatRowData(dataType, data) { formatRowData(dataType, data) {
var returnData = data; var returnData = data;
if (data) { if (data) {

View File

@ -16,7 +16,7 @@
@blur="onInputName" @blur="onInputName"
size="small" /> size="small" />
</el-col> </el-col>
<el-col style="width: 120px; padding: 0 5px"> <el-col class="ms-col-name" style="width: 120px; padding: 0 5px">
<el-select <el-select
v-model="pickValue.type" v-model="pickValue.type"
:disabled="disabled || disabledType" :disabled="disabled || disabledType"
@ -27,7 +27,7 @@
<el-option :key="t" :value="t" :label="t" v-for="t in types" /> <el-option :key="t" :value="t" :label="t" v-for="t in types" />
</el-select> </el-select>
</el-col> </el-col>
<el-col style="min-width: 200px; padding: 0 5px"> <el-col class="ms-col-name" style="min-width: 200px; padding: 0 5px">
<ms-mock <ms-mock
:disabled=" :disabled="
disabled || disabled ||
@ -42,12 +42,13 @@
style="width: 100%" style="width: 100%"
@editScenarioAdvance="editScenarioAdvance" /> @editScenarioAdvance="editScenarioAdvance" />
</el-col> </el-col>
<el-col v-if="showColumns('MIX_LENGTH')" class="item kv-select" style="width: 150px; padding: 0 5px"> <el-col v-if="showColumns('MIX_LENGTH')" class="item kv-select ms-col-name" style="width: 150px; padding: 0 5px">
<el-input-number <el-input-number
:min="0" :min="0"
v-model="pickValue.minLength" v-model="pickValue.minLength"
:placeholder="$t('schema.minLength')" :placeholder="$t('schema.minLength')"
size="small" size="small"
:controls="false"
:disabled=" :disabled="
disabled || disabled ||
pickValue.type === 'object' || pickValue.type === 'object' ||
@ -58,12 +59,13 @@
style="width: 140px" /> style="width: 140px" />
</el-col> </el-col>
<el-col v-if="showColumns('MAX_LENGTH')" class="item kv-select" style="width: 150px; padding: 0 5px"> <el-col v-if="showColumns('MAX_LENGTH')" class="item kv-select ms-col-name" style="width: 150px; padding: 0 5px">
<el-input-number <el-input-number
:min="0" :min="0"
v-model="pickValue.maxLength" v-model="pickValue.maxLength"
:placeholder="$t('schema.maxLength')" :placeholder="$t('schema.maxLength')"
size="small" size="small"
:controls="false"
:disabled=" :disabled="
disabled || disabled ||
pickValue.type === 'object' || pickValue.type === 'object' ||
@ -74,7 +76,7 @@
style="width: 140px" /> style="width: 140px" />
</el-col> </el-col>
<el-col v-if="showColumns('DEFAULT')" class="item kv-select" style="min-width: 200px; padding: 0 5px"> <el-col v-if="showColumns('DEFAULT')" class="item kv-select ms-col-name" style="min-width: 200px; padding: 0 5px">
<el-input <el-input
:disabled=" :disabled="
disabled || disabled ||
@ -89,7 +91,7 @@
style="width: 100%" style="width: 100%"
size="small" /> size="small" />
</el-col> </el-col>
<el-col v-if="showColumns('PATTERN')" style="min-width: 200px; padding: 0 5px"> <el-col class="ms-col-name" v-if="showColumns('PATTERN')" style="min-width: 200px; padding: 0 5px">
<el-input <el-input
:disabled=" :disabled="
disabled || disabled ||
@ -103,10 +105,19 @@
:placeholder="$t('schema.pattern')" :placeholder="$t('schema.pattern')"
size="small" /> size="small" />
</el-col> </el-col>
<el-col v-if="showColumns('FORMAT')" style="min-width: 120px; padding: 0 5px"> <el-col class="ms-col-name" v-if="showColumns('FORMAT')" style="min-width: 120px; padding: 0 5px">
<el-input :disabled="true" size="small" :placeholder="$t('schema.format')"></el-input> <el-input :disabled="true" size="small" :placeholder="$t('schema.format')"></el-input>
</el-col> </el-col>
<el-col v-if="showColumns('ENUM')" style="min-width: 300px; padding: 0 5px"> <el-col class="ms-col-name" v-if="showColumns('ENUM')" style="min-width: 300px; padding: 0 5px">
<el-input
:disabled="disabled"
type="textarea"
v-model="pickValue.enum"
class="ms-col-title"
:placeholder="$t('schema.enum')"
size="small" />
</el-col>
<el-col v-if="showColumns('DESCRIPTION')" class="ms-col-name" style="min-width: 300px; padding: 0 5px">
<el-input <el-input
:disabled="disabled" :disabled="disabled"
v-model="pickValue.description" v-model="pickValue.description"
@ -142,6 +153,7 @@
:parent="pickValue" :parent="pickValue"
:key="index" :key="index"
:deep="deep + 1" :deep="deep + 1"
:disabled="disabled"
:root="false" :root="false"
class="children" class="children"
:param-columns="paramColumns" :param-columns="paramColumns"

View File

@ -7,7 +7,12 @@
<ms-api-key-value :isShowEnable="false" :suggestions="headerSuggestions" :items="response.headers" /> <ms-api-key-value :isShowEnable="false" :suggestions="headerSuggestions" :items="response.headers" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_test.definition.request.response_body')" name="body" class="pane"> <el-tab-pane :label="$t('api_test.definition.request.response_body')" name="body" class="pane">
<ms-api-body :isReadOnly="false" :isShowEnable="false" :body="response.body" :headers="response.headers" /> <ms-api-body
body-type="response"
:isReadOnly="false"
:isShowEnable="false"
:body="response.body"
:headers="response.headers" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_test.definition.request.status_code')" name="status_code" class="pane"> <el-tab-pane :label="$t('api_test.definition.request.status_code')" name="status_code" class="pane">

View File

@ -76,7 +76,7 @@
<div <div
style=" style="
width: 100%; width: 100%;
height: 144px; height: 238px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;