feat(接口定义): 优化需求3初步完成 #1001749

--story=1001749 --user=赵勇 3将接口相关的操作统一... https://www.tapd.cn/55049933/s/1029800
This commit is contained in:
fit2-zhao 2021-07-27 17:18:45 +08:00 committed by fit2-zhao
parent 5b7d4d5d67
commit 6465ba583b
5 changed files with 387 additions and 91 deletions

View File

@ -33,7 +33,7 @@
:middle-button-enable="false"
left-content="API"
right-content="CASE"
>
>
<!-- 列表集合 -->
<ms-api-list
v-if="trashActiveDom==='left'"
@ -126,61 +126,66 @@
@handleCase="handleCase"
@showExecResult="showExecResult"
ref="caseList"/>
<api-documents-page class="api-doc-page"
v-if="activeDom==='right'"
:project-id="projectId"
:trash-enable="trashEnable"
:module-ids="selectNodeIds"/>
<api-documents-page
class="api-doc-page"
v-if="activeDom==='right'"
:project-id="projectId"
:trash-enable="trashEnable"
:module-ids="selectNodeIds"/>
</ms-tab-button>
<!-- 添加/编辑测试窗口-->
<div v-if="item.type=== 'ADD'" class="ms-api-div">
<ms-api-config :syncTabs="syncTabs" @runTest="runTest" @saveApi="saveApi" @mockConfig="mockConfig"
@createRootModel="createRootModel" ref="apiConfig"
:current-api="item.api"
:project-id="projectId"
:currentProtocol="currentProtocol"
:moduleOptions="moduleOptions"/>
<ms-edit-complete-container
:syncTabs="syncTabs"
@runTest="runTest"
@saveApi="saveApi"
@createRootModel="createRootModel"
@editApi="editApi"
@refresh="refresh"
:current-api="item.api"
:project-id="projectId"
:currentProtocol="currentProtocol"
:moduleOptions="moduleOptions"
@changeSelectDataRangeAll="changeSelectDataRangeAll"
@handleCase="handleCase"
@showExecResult="showExecResult"
ref="apiConfig"
/>
</div>
<!-- 快捷调试 -->
<div v-else-if="item.type=== 'debug'" class="ms-api-div">
<ms-debug-http-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi"
@refreshModule="refreshModule"
v-if="currentProtocol==='HTTP'"/>
<ms-debug-jdbc-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi"
@refreshModule="refreshModule"
v-if="currentProtocol==='SQL'"/>
<ms-debug-tcp-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi"
@refreshModule="refreshModule"
v-if="currentProtocol==='TCP'"/>
<ms-debug-dubbo-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi"
@refreshModule="refreshModule"
v-if="currentProtocol==='DUBBO'"/>
</div>
<!-- 测试-->
<div v-else-if="item.type=== 'TEST'" class="ms-api-div">
<ms-run-test-http-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api"
:project-id="projectId"
@saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='HTTP'"/>
<ms-run-test-tcp-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api"
:project-id="projectId"
@saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='TCP'"/>
<ms-run-test-sql-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api"
:project-id="projectId"
@saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='SQL'"/>
<ms-run-test-dubbo-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api"
:project-id="projectId"
@saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='DUBBO'"/>
<ms-debug-http-page
:currentProtocol="currentProtocol"
:testCase="item.api"
@saveAs="editApi"
@refreshModule="refreshModule"
v-if="currentProtocol==='HTTP'"/>
<ms-debug-jdbc-page
:currentProtocol="currentProtocol"
:testCase="item.api"
@saveAs="editApi"
@refreshModule="refreshModule"
v-if="currentProtocol==='SQL'"/>
<ms-debug-tcp-page
:currentProtocol="currentProtocol"
:testCase="item.api"
@saveAs="editApi"
@refreshModule="refreshModule"
v-if="currentProtocol==='TCP'"/>
<ms-debug-dubbo-page
:currentProtocol="currentProtocol"
:testCase="item.api"
@saveAs="editApi"
@refreshModule="refreshModule"
v-if="currentProtocol==='DUBBO'"/>
</div>
<!-- 定时任务 -->
<div v-if="item.type=== 'SCHEDULE'" class="ms-api-div">
<api-schedule :param="param" :module-options="nodeTree" ref="apiSchedules"/>
</div>
<div v-else-if="item.type=== 'MOCK'" class="ms-api-div">
<mock-config :base-mock-config-data="item.mock"></mock-config>
</div>
</el-tab-pane>
<el-tab-pane name="add" v-if="hasPermission('PROJECT_API_DEFINITION:READ+CREATE_API')">
@ -233,6 +238,8 @@ import MsTabButton from "@/business/components/common/components/MsTabButton";
import MockConfig from "@/business/components/api/definition/components/mock/MockConfig";
import ApiSchedule from "@/business/components/api/definition/components/import/ApiSchedule";
import MsEditCompleteContainer from "./components/EditCompleteContainer";
export default {
name: "ApiDefinition",
@ -270,7 +277,8 @@ export default {
MsRunTestSqlPage,
MsRunTestDubboPage,
ApiDocumentsPage,
MockConfig
MockConfig,
MsEditCompleteContainer
},
props: {
visible: {
@ -322,10 +330,10 @@ export default {
this.activeDom = 'middle';
}
let dataType = this.$route.params.dataType;
if(dataType){
if(dataType === "api"){
if (dataType) {
if (dataType === "api") {
this.activeDom = 'left';
}else {
} else {
this.activeDom = 'middle';
}
}
@ -390,17 +398,19 @@ export default {
addTab(tab) {
if (tab.name === 'add') {
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug");
}else if(tab.name === 'trash'){
if(this.$refs.trashApiList){
} else if (tab.name === 'trash') {
if (this.$refs.trashApiList) {
this.$refs.trashApiList.initTable();
}
if(this.$refs.trashCaseList){
if (this.$refs.trashCaseList) {
this.$refs.trashCaseList.initTable();
}
}
if (this.$refs.apiConfig) {
this.$refs.apiConfig.forEach(item => {
item.removeListener();
if (item) {
item.removeListener();
}
}); // tab ctrl + s
let tabs = this.apiTabs;
let index = tabs.findIndex(item => item.name === tab.name); // tabindex
@ -526,9 +536,9 @@ export default {
name = "copy" + "-" + row.name;
row.name = "copy" + "-" + row.name;
} else {
if(row.name){
if (row.name) {
name = this.$t('api_test.definition.request.edit_api') + "-" + row.name;
}else {
} else {
name = this.$t('api_test.definition.request.title');
}
@ -553,16 +563,16 @@ export default {
this.$refs.nodeTree.list();
},
refresh(data) {
if(this.$refs.caseList && this.$refs.caseList[0]){
if (this.$refs.caseList && this.$refs.caseList[0]) {
this.$refs.caseList[0].initTable();
}
if(this.$refs.trashApiList){
if (this.$refs.trashApiList) {
this.$refs.trashApiList.initTable();
}
if(this.$refs.trashCaseList){
if (this.$refs.trashCaseList) {
this.$refs.trashCaseList.initTable();
}
if(this.$refs.apiDefList && this.$refs.apiDefList[0]){
if (this.$refs.apiDefList && this.$refs.apiDefList[0]) {
this.$refs.apiDefList[0].initTable();
}
@ -616,13 +626,13 @@ export default {
enableTrash(data) {
this.initApiTableOpretion = "trashEnable";
this.trashEnable = data;
if(data){
if (data) {
this.apiDefaultTab = "trash";
}else {
} else {
this.apiDefaultTab = "default"
}
},
updateInitApiTableOpretion(param){
updateInitApiTableOpretion(param) {
this.initApiTableOpretion = param;
}
}

View File

@ -0,0 +1,254 @@
<template>
<el-card class="card-content" v-if="isShow && !loading">
<el-button-group v-if="currentApi.id">
<el-tooltip class="item" effect="dark" :content="$t('api_test.definition.api_title')" placement="left">
<el-button plain :class="{active: showApiList}" @click="changeTab('api')" size="small">API</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="$t('commons.test')" placement="top">
<el-button plain :class="{active: showTest}" @click="changeTab('test')" size="small">{{ $t('commons.test') }}</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="$t('api_test.definition.case_title')" placement="top">
<el-button plain :class="{active: showTestCaseList}" @click="changeTab('testCase')" size="small">CASE</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="Mock设置" placement="right" v-if="currentProtocol==='HTTP'">
<el-button plain :class="{active: showMock}" @click="changeTab('mock')" size="small"> Mock</el-button>
</el-tooltip>
</el-button-group>
<template v-slot:header>
<slot name="header"></slot>
</template>
<slot></slot>
<div v-if="showApiList">
<ms-api-config
:syncTabs="syncTabs" ref="apiConfig"
:current-api="currentApi"
:project-id="projectId"
:currentProtocol="currentProtocol"
:moduleOptions="moduleOptions"
@runTest="runTest"
@saveApi="saveApi"
@createRootModel="createRootModel"
/>
</div>
<div v-else-if="showTest" class="ms-api-div">
<ms-run-test-http-page
:syncTabs="syncTabs"
:currentProtocol="currentProtocol"
:api-data="currentApi"
:project-id="projectId"
@saveAsApi="editApi"
@refresh="refresh"
v-if="currentProtocol==='HTTP'"
/>
<ms-run-test-tcp-page
:syncTabs="syncTabs"
:currentProtocol="currentProtocol"
:api-data="currentApi"
:project-id="projectId"
@saveAsApi="editApi"
@refresh="refresh"
v-if="currentProtocol==='TCP'"
/>
<ms-run-test-sql-page
:syncTabs="syncTabs"
:currentProtocol="currentProtocol"
:api-data="currentApi"
:project-id="projectId"
@saveAsApi="editApi"
@refresh="refresh"
v-if="currentProtocol==='SQL'"
/>
<ms-run-test-dubbo-page
:syncTabs="syncTabs"
:currentProtocol="currentProtocol"
:api-data="currentApi"
:project-id="projectId"
@saveAsApi="editApi"
@refresh="refresh"
v-if="currentProtocol==='DUBBO'"
/>
</div>
<div v-if="showMock" class="ms-api-div">
<mock-config :base-mock-config-data="baseMockConfigData"/>
</div>
<div v-if="showTestCaseList">
<!--测试用例列表-->
<api-case-simple-list
:apiDefinitionId="currentApi.id"
:trash-enable="false"
@changeSelectDataRangeAll="changeSelectDataRangeAll"
@handleCase="handleCase"
@refreshTable="refresh"
@showExecResult="showExecResult"
ref="trashCaseList"/>
</div>
</el-card>
</template>
<script>
import MsApiConfig from "./ApiConfig";
import MsRunTestHttpPage from "./runtest/RunTestHTTPPage";
import MsRunTestTcpPage from "./runtest/RunTestTCPPage";
import MsRunTestSqlPage from "./runtest/RunTestSQLPage";
import MsRunTestDubboPage from "./runtest/RunTestDubboPage";
import MockConfig from "@/business/components/api/definition/components/mock/MockConfig";
import ApiCaseSimpleList from "./list/ApiCaseSimpleList";
export default {
name: "EditCompleteContainer",
components: {
MsApiConfig,
MsRunTestHttpPage,
MsRunTestTcpPage,
MsRunTestSqlPage,
MsRunTestDubboPage,
MockConfig,
ApiCaseSimpleList
},
data() {
return {
isShow: true,
showApiList: true,
showTest: false,
showMock: false,
showTestCaseList: false,
baseMockConfigData: {},
loading: false
}
},
props: {
activeDom: String,
isShowChangeButton: {
type: Boolean,
default: true
},
currentApi: {},
moduleOptions: {},
currentProtocol: String,
syncTabs: Array,
projectId: String,
selectNodeIds: Array,
visible: {
type: Boolean,
default: false,
},
},
created() {
this.refreshButtonActiveClass(this.activeDom);
if (this.currentApi.id !== null && this.currentProtocol === "HTTP") {
this.mockSetting();
}
},
watch: {
showMock() {
this.mockSetting();
}
},
methods: {
mockSetting() {
let mockParam = {};
mockParam.projectId = this.projectId;
mockParam.apiId = this.currentApi.id;
this.$post('/mockConfig/genMockConfig', mockParam, response => {
let mockConfig = response.data;
mockConfig.apiName = this.currentApi.name;
this.baseMockConfigData = mockConfig;
});
},
runTest(data) {
this.$emit("runTest", data);
},
saveApi(data) {
this.$emit("saveApi", data);
if (data != null && data.tags != 'null' && data.tags != undefined) {
if (Object.prototype.toString.call(data.tags).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
data.tags = JSON.parse(data.tags);
}
}
Object.assign(this.currentApi, data);
this.mockSetting();
this.reload();
},
createRootModel() {
this.$emit("createRootModel");
},
editApi(data) {
this.$emit("editApi", data);
},
refresh() {
this.$emit("refresh");
},
changeTab(tabType) {
this.refreshButtonActiveClass(tabType);
},
removeListener() {
if (this.$refs && this.$refs.apiConfig) {
this.$refs.apiConfig.removeListener();
}
},
changeSelectDataRangeAll() {
this.$emit("changeSelectDataRangeAll");
},
handleCase(api) {
this.$emit("handleCase", api);
},
showExecResult(data) {
this.$emit("showExecResult", data);
},
addListener() {
if (this.$refs && this.$refs.apiConfig) {
this.$refs.apiConfig.addListener();
}
},
reload() {
this.loading = true
this.$nextTick(() => {
this.loading = false
});
},
refreshButtonActiveClass(tabType) {
if (tabType === "testCase") {
this.showApiList = false;
this.showTestCaseList = true;
this.showTest = false;
this.showMock = false;
} else if (tabType === "test") {
this.showApiList = false;
this.showTestCaseList = false;
this.showTest = true;
this.showMock = false;
} else if (tabType === "mock") {
this.showApiList = false;
this.showTestCaseList = false;
this.showTest = false;
this.showMock = true;
} else {
this.showApiList = true;
this.showTestCaseList = false;
this.showTest = false;
this.showMock = false;
}
}
},
}
</script>
<style scoped>
.active {
border: solid 1px #6d317c !important;
background-color: var(--primary_color) !important;
color: #FFFFFF !important;
}
.case-button {
border-left: solid 1px var(--primary_color);
}
.item {
border: solid 1px var(--primary_color);
}
</style>

View File

@ -142,12 +142,12 @@ export default {
},
},
methods: {
apiCaseSelected(){
apiCaseSelected() {
this.selectSize = 0;
if (this.apiCaseList.length > 0) {
this.apiCaseList.forEach(item => {
if (item.selected && item.id) {
this.selectSize ++;
this.selectSize++;
}
});
}
@ -160,6 +160,18 @@ export default {
this.getApiTest(true);
this.visible = true;
},
add(api) {
this.api = api;
this.condition = {components: API_CASE_CONFIGS};
this.sysAddition();
this.visible = true;
},
copy(apiCase) {
this.api.id = apiCase.apiDefinitionId;
this.condition = {components: API_CASE_CONFIGS};
this.sysAddition(apiCase);
this.visible = true;
},
runTestCase(api, testCaseId) {
this.api = api;
// testCaseId
@ -177,7 +189,7 @@ export default {
setEnvironment(environment) {
this.environment = environment;
},
sysAddition() {
sysAddition(apiCase) {
this.condition.projectId = this.projectId;
this.condition.apiDefinitionId = this.api.id;
this.$post("/api/testcase/list", this.condition, response => {
@ -195,7 +207,11 @@ export default {
}
});
this.apiCaseList = data;
this.addCase();
if (apiCase) {
this.copyCase(apiCase);
} else {
this.addCase();
}
});
},

View File

@ -9,7 +9,6 @@
{{ $t('operating_log.change_history') }}
</el-link>
<el-button type="primary" size="small" @click="saveApi" title="ctrl + s">{{ $t('commons.save') }}</el-button>
<el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button>
</div>
<br/>
<p class="tip">{{ $t('test_track.plan_view.base_info') }} </p>
@ -85,15 +84,12 @@
<p class="tip">{{ $t('test_track.plan_view.mock_info') }} </p>
<div class="base-info mock-info">
<el-row>
<el-col :span="20">
<el-col :span="24">
Mock地址
<el-link :href="getUrlPrefix" target="_blank" style="color: black"
type="primary">{{ this.getUrlPrefix }}
</el-link>
</el-col>
<el-col :span="4">
<el-link @click="mockSetting" type="primary">Mock设置</el-link>
</el-col>
</el-row>
</div>
@ -322,21 +318,6 @@
}
});
},
mockSetting() {
if (this.httpForm.id == null) {
this.$alert(this.$t('api_test.mock.create_error'));
} else {
let mockParam = {};
mockParam.projectId = this.projectId;
mockParam.apiId = this.httpForm.id;
this.$post('/mockConfig/genMockConfig', mockParam, response => {
let mockConfig = response.data;
mockConfig.apiName = this.httpForm.name;
this.$emit('mockConfig', mockConfig);
});
}
}
},
created() {

View File

@ -7,7 +7,7 @@
<el-input :placeholder="$t('commons.search_by_id_name_tag')" @blur="search" @keyup.enter.native="search"
class="search-input" size="small"
v-model="condition.name"/>
<el-button type="primary" style="float: right;margin-right: 10px" icon="el-icon-plus" size="small" @click="addTestCase" v-if="apiDefinitionId">{{ $t('commons.add') }}</el-button>
<ms-table :data="tableData" :select-node-ids="selectNodeIds" :condition="condition" :page-size="pageSize"
:total="total"
:operators="operators"
@ -16,7 +16,7 @@
:fields.sync="fields"
:field-key="tableHeaderKey"
@saveSortField="saveSortField"
operator-width="170px"
operator-width="190px"
@refresh="initTable"
ref="caseTable"
>
@ -163,7 +163,7 @@ import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn";
import MsBatchEdit from "../basis/BatchEdit";
import {API_METHOD_COLOUR, CASE_PRIORITY, DUBBO_METHOD, REQ_METHOD, SQL_METHOD, TCP_METHOD} from "../../model/JsonData";
import {getBodyUploadFiles, getCurrentProjectID} from "@/common/js/utils";
import {getBodyUploadFiles, getCurrentProjectID, getUUID} from "@/common/js/utils";
import PriorityTableItem from "../../../../track/common/tableItems/planview/PriorityTableItem";
import MsApiCaseTableExtendBtns from "../reference/ApiCaseTableExtendBtns";
import MsReferenceView from "../reference/ReferenceView";
@ -248,6 +248,13 @@ export default {
exec: this.handleTestCase,
permissions: ['PROJECT_API_DEFINITION:READ+EDIT_CASE']
},
{
tip: this.$t('commons.copy'),
exec: this.handleCopy,
icon: "el-icon-document-copy",
type: "primary",
permissions: ['PROJECT_API_DEFINITION:READ+COPY_CASE']
},
{
tip: this.$t('commons.delete'),
exec: this.deleteToGc,
@ -294,6 +301,7 @@ export default {
},
props: {
currentProtocol: String,
apiDefinitionId: String,
selectNodeIds: Array,
activeDom: String,
visible: {
@ -406,6 +414,9 @@ export default {
this.condition.orders.splice(index, 1);
}
}
if (this.apiDefinitionId) {
this.condition.apiDefinitionId = this.apiDefinitionId;
}
this.condition.status = "";
this.condition.moduleIds = this.selectNodeIds;
if (this.trashEnable) {
@ -537,6 +548,33 @@ export default {
this.$refs.caseList.open(selectApi, testCase.id);
});
},
addTestCase() {
this.$get('/api/definition/get/' + this.apiDefinitionId, (response) => {
let api = response.data;
let selectApi = api;
let request = {};
if (Object.prototype.toString.call(api.request).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
request = api.request;
} else {
request = JSON.parse(api.request);
}
if (!request.hashTree) {
request.hashTree = [];
}
selectApi.url = request.path;
this.$refs.caseList.add(selectApi);
});
},
handleCopy(row) {
this.$get('/api/testcase/findById/' + row.id, (response) => {
let data = response.data;
let uuid = getUUID();
let apiCaseRequest = JSON.parse(data.request);
apiCaseRequest.id = uuid;
let obj = {name: "copy_" + data.name, apiDefinitionId: row.apiDefinitionId, priority: data.priority, active: true, tags: data.tags, request: apiCaseRequest, uuid: uuid};
this.$refs.caseList.copy(obj);
});
},
handleDeleteBatch() {
this.$alert(this.$t('api_test.definition.request.delete_case_confirm') + "", '', {
confirmButtonText: this.$t('commons.confirm'),
@ -594,8 +632,6 @@ export default {
}
});
});
},
handleEditBatch() {
if (this.currentProtocol == 'HTTP') {
@ -640,7 +676,6 @@ export default {
return;
},
deleteToGc(apiCase) {
let obj = {};
obj.projectId = this.projectId;
obj.selectAllDate = false;