feat(接口定义): 按照不同协议处理

This commit is contained in:
fit2-zhao 2020-11-23 18:15:09 +08:00
parent 816482d16d
commit f8475dca0c
15 changed files with 109 additions and 49 deletions

View File

@ -16,6 +16,7 @@ public class ApiDefinitionRequest {
private String projectId; private String projectId;
private String moduleId; private String moduleId;
private List<String> moduleIds; private List<String> moduleIds;
private String protocol;
private String name; private String name;
private String workspaceId; private String workspaceId;
private String userId; private String userId;

View File

@ -11,6 +11,8 @@ public class ApiDefinitionResult extends ApiDefinition {
private String projectName; private String projectName;
private String url;
private String userName; private String userName;
private String caseTotal; private String caseTotal;

View File

@ -20,7 +20,7 @@ public class SaveApiDefinitionRequest {
private String name; private String name;
private String url; private String protocol;
private String moduleId; private String moduleId;

View File

@ -141,7 +141,7 @@ public class ApiDefinitionService {
private void checkNameExist(SaveApiDefinitionRequest request) { private void checkNameExist(SaveApiDefinitionRequest request) {
ApiDefinitionExample example = new ApiDefinitionExample(); ApiDefinitionExample example = new ApiDefinitionExample();
example.createCriteria().andUrlEqualTo(request.getUrl()).andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId()); example.createCriteria().andProtocolEqualTo(request.getProtocol()).andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId());
if (apiDefinitionMapper.countByExample(example) > 0) { if (apiDefinitionMapper.countByExample(example) > 0) {
MSException.throwException(Translator.get("api_definition_url_not_repeating")); MSException.throwException(Translator.get("api_definition_url_not_repeating"));
} }
@ -160,7 +160,7 @@ public class ApiDefinitionService {
test.setModulePath(request.getModulePath()); test.setModulePath(request.getModulePath());
test.setModuleId(request.getModuleId()); test.setModuleId(request.getModuleId());
test.setMethod(request.getMethod()); test.setMethod(request.getMethod());
test.setUrl(request.getUrl()); test.setProtocol(request.getProtocol());
test.setDescription(request.getDescription()); test.setDescription(request.getDescription());
test.setResponse(JSONObject.toJSONString(request.getResponse())); test.setResponse(JSONObject.toJSONString(request.getResponse()));
test.setEnvironmentId(request.getEnvironmentId()); test.setEnvironmentId(request.getEnvironmentId());
@ -175,7 +175,7 @@ public class ApiDefinitionService {
final ApiDefinition test = new ApiDefinition(); final ApiDefinition test = new ApiDefinition();
test.setId(request.getId()); test.setId(request.getId());
test.setName(request.getName()); test.setName(request.getName());
test.setUrl(request.getUrl()); test.setProtocol(request.getProtocol());
test.setMethod(request.getMethod()); test.setMethod(request.getMethod());
test.setModuleId(request.getModuleId()); test.setModuleId(request.getModuleId());
test.setProjectId(request.getProjectId()); test.setProjectId(request.getProjectId());

View File

@ -14,7 +14,7 @@ public class ApiDefinition implements Serializable {
private String method; private String method;
private String url; private String protocol;
private String environmentId; private String environmentId;

View File

@ -264,8 +264,8 @@ public class ApiDefinitionExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andUrlEqualTo(String value) { public Criteria andProtocolEqualTo(String value) {
addCriterion("url =", value, "url"); addCriterion("protocol =", value, "protocol");
return (Criteria) this; return (Criteria) this;
} }

View File

@ -7,7 +7,7 @@
<result column="module_id" jdbcType="VARCHAR" property="moduleId"/> <result column="module_id" jdbcType="VARCHAR" property="moduleId"/>
<result column="module_path" jdbcType="VARCHAR" property="modulePath"/> <result column="module_path" jdbcType="VARCHAR" property="modulePath"/>
<result column="name" jdbcType="VARCHAR" property="name"/> <result column="name" jdbcType="VARCHAR" property="name"/>
<result column="url" jdbcType="VARCHAR" property="url"/> <result column="protocol" jdbcType="VARCHAR" property="protocol"/>
<result column="method" jdbcType="VARCHAR" property="method"/> <result column="method" jdbcType="VARCHAR" property="method"/>
<result column="description" jdbcType="VARCHAR" property="description"/> <result column="description" jdbcType="VARCHAR" property="description"/>
<result column="status" jdbcType="VARCHAR" property="status"/> <result column="status" jdbcType="VARCHAR" property="status"/>
@ -80,7 +80,7 @@
</where> </where>
</sql> </sql>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, project_id, name,module_id,module_path,url ,method ,description, status, user_id, create_time, update_time id, project_id, name,module_id,module_path,protocol ,method ,description, status, user_id, create_time, update_time
</sql> </sql>
<sql id="Blob_Column_List"> <sql id="Blob_Column_List">
request request
@ -204,7 +204,7 @@
<select id="list" resultType="io.metersphere.api.dto.definition.ApiDefinitionResult"> <select id="list" resultType="io.metersphere.api.dto.definition.ApiDefinitionResult">
select api_definition.id, api_definition.project_id, select api_definition.id, api_definition.project_id,
api_definition.name,api_definition.url,api_definition.module_id,api_definition.module_path,api_definition.method, api_definition.name,api_definition.protocol,api_definition.module_id,api_definition.module_path,api_definition.method,
api_definition.description,api_definition.request,api_definition.response,api_definition.environment_id, api_definition.description,api_definition.request,api_definition.response,api_definition.environment_id,
api_definition.status, api_definition.user_id, api_definition.create_time, api_definition.update_time, project.name as api_definition.status, api_definition.user_id, api_definition.create_time, api_definition.update_time, project.name as
project_name, user.name as user_name project_name, user.name as user_name
@ -222,6 +222,9 @@
<if test="request.name != null"> <if test="request.name != null">
and api_definition.name like CONCAT('%', #{request.name},'%') and api_definition.name like CONCAT('%', #{request.name},'%')
</if> </if>
<if test="request.protocol != null">
AND api_definition.protocol = #{request.protocol}
</if>
<if test="request.workspaceId != null"> <if test="request.workspaceId != null">
AND project.workspace_id = #{request.workspaceId} AND project.workspace_id = #{request.workspaceId}
</if> </if>
@ -303,10 +306,10 @@
</delete> </delete>
<insert id="insert" parameterType="io.metersphere.base.domain.ApiDefinition"> <insert id="insert" parameterType="io.metersphere.base.domain.ApiDefinition">
insert into api_definition (id, project_id, name, url,module_id,module_path,method, insert into api_definition (id, project_id, name, protocol,module_id,module_path,method,
description, status, user_id,create_time, update_time, request,response,environment_id ) description, status, user_id,create_time, update_time, request,response,environment_id )
values values
(#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{url,jdbcType=VARCHAR}, #{moduleId,jdbcType=VARCHAR},#{modulePath,jdbcType=VARCHAR},#{method,jdbcType=VARCHAR}, (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{protocol,jdbcType=VARCHAR}, #{moduleId,jdbcType=VARCHAR},#{modulePath,jdbcType=VARCHAR},#{method,jdbcType=VARCHAR},
#{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{request,jdbcType=LONGVARCHAR},#{response,jdbcType=LONGVARCHAR},#{environmentId,jdbcType=VARCHAR} #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{request,jdbcType=LONGVARCHAR},#{response,jdbcType=LONGVARCHAR},#{environmentId,jdbcType=VARCHAR}
) )
@ -333,8 +336,8 @@
<if test="moduleId != null"> <if test="moduleId != null">
module_id = #{moduleId,jdbcType=BIGINT}, module_id = #{moduleId,jdbcType=BIGINT},
</if> </if>
<if test="url != null"> <if test="protocol != null">
url = #{url,jdbcType=LONGVARCHAR}, protocol = #{protocol,jdbcType=LONGVARCHAR},
</if> </if>
<if test="method != null"> <if test="method != null">
method = #{method,jdbcType=VARCHAR}, method = #{method,jdbcType=VARCHAR},
@ -378,7 +381,7 @@
user_id = #{userId,jdbcType=VARCHAR}, user_id = #{userId,jdbcType=VARCHAR},
module_id = #{moduleId,jdbcType=VARCHAR}, module_id = #{moduleId,jdbcType=VARCHAR},
module_path = #{modulePath,jdbcType=VARCHAR}, module_path = #{modulePath,jdbcType=VARCHAR},
url = #{url,jdbcType=VARCHAR}, protocol = #{protocol,jdbcType=VARCHAR},
method = #{method,jdbcType=VARCHAR}, method = #{method,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT}, update_time = #{updateTime,jdbcType=BIGINT},
@ -392,7 +395,7 @@
set project_id = #{projectId,jdbcType=VARCHAR}, set project_id = #{projectId,jdbcType=VARCHAR},
name = #{name,jdbcType=VARCHAR}, name = #{name,jdbcType=VARCHAR},
module_id = #{moduleId,jdbcType=VARCHAR}, module_id = #{moduleId,jdbcType=VARCHAR},
url = #{url,jdbcType=VARCHAR}, protocol = #{protocol,jdbcType=VARCHAR},
module_path = #{modulePath,jdbcType=VARCHAR}, module_path = #{modulePath,jdbcType=VARCHAR},
method = #{method,jdbcType=VARCHAR}, method = #{method,jdbcType=VARCHAR},
description = #{description,jdbcType=VARCHAR}, description = #{description,jdbcType=VARCHAR},

View File

@ -2,8 +2,8 @@
<ms-container> <ms-container>
<ms-aside-container> <ms-aside-container>
<ms-node-tree @selectModule="selectModule" @getApiModuleTree="initTree" @changeProject="changeProject" <ms-node-tree @selectModule="selectModule" @getApiModuleTree="initTree" @changeProject="changeProject" @changeProtocol="changeProtocol"
@refresh="refresh"/> @refresh="refresh" @saveAsEdit="editApi"/>
</ms-aside-container> </ms-aside-container>
<ms-main-container> <ms-main-container>
@ -28,6 +28,7 @@
<ms-api-list <ms-api-list
v-if="item.type === 'list'" v-if="item.type === 'list'"
:current-project="currentProject" :current-project="currentProject"
:current-protocol="currentProtocol"
:current-module="currentModule" :current-module="currentModule"
@editApi="editApi" @editApi="editApi"
@handleCase="handleCase" @handleCase="handleCase"
@ -37,6 +38,7 @@
<div v-else-if="item.type=== 'add'"> <div v-else-if="item.type=== 'add'">
<ms-api-config @runTest="runTest" @saveApi="saveApi" :current-api="currentApi" <ms-api-config @runTest="runTest" @saveApi="saveApi" :current-api="currentApi"
:currentProject="currentProject" :currentProject="currentProject"
:currentProtocol="currentProtocol"
:moduleOptions="moduleOptions" ref="apiConfig"/> :moduleOptions="moduleOptions" ref="apiConfig"/>
</div> </div>
@ -88,6 +90,7 @@
isHide: true, isHide: true,
apiDefaultTab: 'default', apiDefaultTab: 'default',
currentProject: null, currentProject: null,
currentProtocol: null,
currentModule: null, currentModule: null,
currentApi: {}, currentApi: {},
moduleOptions: {}, moduleOptions: {},
@ -103,7 +106,7 @@
methods: { methods: {
handleCommand(e) { handleCommand(e) {
if (e === "add") { if (e === "add") {
this.currentApi = {status: "Underway", method: "GET", userId: getCurrentUser().id}; this.currentApi = {status: "Underway", method: "GET", userId: getCurrentUser().id, url: "", protocol: this.currentProtocol};
this.handleTabsEdit(this.$t('api_test.definition.request.title'), e); this.handleTabsEdit(this.$t('api_test.definition.request.title'), e);
} }
else if (e === "test") { else if (e === "test") {
@ -189,6 +192,9 @@
}, },
changeProject(data) { changeProject(data) {
this.currentProject = data; this.currentProject = data;
},
changeProtocol(data) {
this.currentProtocol = data;
} }
} }
} }

View File

@ -20,7 +20,7 @@
</template> </template>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<div class="variable-combine">{{api.url}}</div> <div class="variable-combine">{{api.url ===undefined ? "暂无路径" : api.url}}</div>
</el-col> </el-col>
<el-col :span="2"> <el-col :span="2">
<div>{{$t('test_track.plan_view.case_count')}}5</div> <div>{{$t('test_track.plan_view.case_count')}}5</div>

View File

@ -32,10 +32,10 @@
currentApi: {}, currentApi: {},
moduleOptions: {}, moduleOptions: {},
currentProject: {}, currentProject: {},
protocol: String, currentProtocol: String,
}, },
created() { created() {
switch (this.protocol) { switch (this.currentProtocol) {
case Request.TYPES.SQL: case Request.TYPES.SQL:
this.request = createComponent("SQL"); this.request = createComponent("SQL");
break; break;
@ -56,6 +56,7 @@
} }
if (this.currentApi != null && this.currentApi.id != null) { if (this.currentApi != null && this.currentApi.id != null) {
this.reqUrl = "/api/definition/update"; this.reqUrl = "/api/definition/update";
this.currentApi.url = this.request.path.value;
} else { } else {
this.reqUrl = "/api/definition/create"; this.reqUrl = "/api/definition/create";
this.currentApi.id = getUUID().substring(0, 8); this.currentApi.id = getUUID().substring(0, 8);

View File

@ -44,10 +44,10 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <!--<el-table-column-->
prop="url" <!--prop="url"-->
:label="$t('api_test.definition.api_path')" <!--:label="$t('api_test.definition.api_path')"-->
show-overflow-tooltip/> <!--show-overflow-tooltip/>-->
<el-table-column <el-table-column
prop="userName" prop="userName"
@ -144,6 +144,7 @@
}, },
props: { props: {
currentProject: Object, currentProject: Object,
currentProtocol: String,
currentModule: Object currentModule: Object
}, },
created: function () { created: function () {
@ -155,6 +156,9 @@
}, },
currentModule() { currentModule() {
this.initApiTable(); this.initApiTable();
},
currentProtocol() {
this.initApiTable();
} }
}, },
methods: { methods: {
@ -169,6 +173,9 @@
if (this.currentProject != null) { if (this.currentProject != null) {
this.condition.projectId = this.currentProject.id; this.condition.projectId = this.currentProject.id;
} }
if (this.currentProtocol != null) {
this.condition.protocol = this.currentProtocol;
}
this.result = this.$post("/api/definition/list/" + this.currentPage + "/" + this.pageSize, this.condition, response => { this.result = this.$post("/api/definition/list/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
this.total = response.data.itemCount; this.total = response.data.itemCount;
this.tableData = response.data.listObject; this.tableData = response.data.listObject;
@ -238,6 +245,8 @@
}, },
handleTestCase(testCase) { handleTestCase(testCase) {
this.selectApi = testCase; this.selectApi = testCase;
let request = JSON.parse(testCase.request);
this.selectApi.url = request.path.value;
this.isHide = false; this.isHide = false;
}, },
handleDelete(testCase) { handleDelete(testCase) {

View File

@ -6,7 +6,7 @@
:title="$t('test_track.project')" :title="$t('test_track.project')"
@dataChange="changeProject" style="margin-bottom: 20px"/> @dataChange="changeProject" style="margin-bottom: 20px"/>
<el-select style="width: 100px ;height: 30px" size="small" v-model="value"> <el-select style="width: 100px ;height: 30px" size="small" v-model="value" @change="changeProtocol">
<el-option <el-option
v-for="item in options" v-for="item in options"
:key="item.value" :key="item.value"
@ -80,7 +80,7 @@
</span> </span>
</el-tree> </el-tree>
<ms-add-basis-http-api ref="httpApi"></ms-add-basis-http-api> <ms-add-basis-http-api :current-protocol="value" ref="httpApi"></ms-add-basis-http-api>
</div> </div>
@ -373,6 +373,9 @@
refresh(data) { refresh(data) {
this.$emit('refresh', data); this.$emit('refresh', data);
}, },
saveAsEdit(data) {
this.$emit('saveAsEdit', data);
},
filterNode(value, data) { filterNode(value, data) {
if (!value) return true; if (!value) return true;
return data.name.indexOf(value) !== -1; return data.name.indexOf(value) !== -1;
@ -402,6 +405,9 @@
if (data.id) { if (data.id) {
this.expandedNode.splice(this.expandedNode.indexOf(data.id), 1); this.expandedNode.splice(this.expandedNode.indexOf(data.id), 1);
} }
},
changeProtocol() {
this.$emit('changeProtocol', this.value);
} }
} }
} }

View File

@ -7,7 +7,7 @@
<el-input v-model="httpForm.name" autocomplete="off" :placeholder="$t('commons.name')"/> <el-input v-model="httpForm.name" autocomplete="off" :placeholder="$t('commons.name')"/>
</el-form-item> </el-form-item>
<el-form-item :label="$t('api_report.request')" prop="url"> <el-form-item :label="$t('api_report.request')" prop="url" v-if="currentProtocol==='HTTP'">
<el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="httpForm.url" <el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="httpForm.url"
class="ms-http-input" size="small"> class="ms-http-input" size="small">
<el-select v-model="httpForm.method" slot="prepend" style="width: 100px" size="small"> <el-select v-model="httpForm.method" slot="prepend" style="width: 100px" size="small">
@ -15,6 +15,8 @@
</el-select> </el-select>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId"> <el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId">
<el-select v-model="httpForm.userId" <el-select v-model="httpForm.userId"
:placeholder="$t('api_test.definition.request.responsible')" filterable size="small" :placeholder="$t('api_test.definition.request.responsible')" filterable size="small"
@ -39,8 +41,14 @@
<template v-slot:footer> <template v-slot:footer>
<ms-dialog-footer <ms-dialog-footer
@cancel="httpVisible = false" @cancel="httpVisible = false"
@confirm="saveApi"/> :isShow="true"
title="编辑详情"
@saveAsEdit="saveApi(true)"
@confirm="saveApi">
</ms-dialog-footer>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
@ -55,7 +63,12 @@
export default { export default {
name: "MsAddBasisHttpApi", name: "MsAddBasisHttpApi",
components: {MsDialogFooter}, components: {MsDialogFooter},
props: {}, props: {
currentProtocol: {
type: String,
default: "HTTP"
},
},
data() { data() {
return { return {
httpForm: {}, httpForm: {},
@ -76,7 +89,7 @@
} }
}, },
methods: { methods: {
saveApi() { saveApi(saveAs) {
this.$refs['httpForm'].validate((valid) => { this.$refs['httpForm'].validate((valid) => {
if (valid) { if (valid) {
let bodyFiles = []; let bodyFiles = [];
@ -84,8 +97,10 @@
this.httpForm.bodyUploadIds = []; this.httpForm.bodyUploadIds = [];
this.httpForm.projectId = this.projectId; this.httpForm.projectId = this.projectId;
this.httpForm.id = getUUID().substring(0, 8); this.httpForm.id = getUUID().substring(0, 8);
this.httpForm.protocol = this.currentProtocol;
let header = createComponent("HeaderManager"); let header = createComponent("HeaderManager");
let request = createComponent("HTTPSamplerProxy"); let request = createComponent("HTTPSamplerProxy");
request.path.value = this.httpForm.url;
request.hashTree = [header]; request.hashTree = [header];
this.httpForm.request = request; this.httpForm.request = request;
if (this.currentModule != null) { if (this.currentModule != null) {
@ -94,7 +109,13 @@
} }
this.result = this.$fileUpload(url, null, bodyFiles, this.httpForm, () => { this.result = this.$fileUpload(url, null, bodyFiles, this.httpForm, () => {
this.httpVisible = false; this.httpVisible = false;
if (saveAs) {
this.httpForm.request = JSON.stringify(request);
console.log(this.httpForm)
this.$parent.saveAsEdit(this.httpForm);
} else {
this.$parent.refresh(this.currentModule); this.$parent.refresh(this.currentModule);
}
}); });
} else { } else {
return false; return false;

View File

@ -24,7 +24,7 @@
<el-form-item :label="$t('api_report.request')" prop="url"> <el-form-item :label="$t('api_report.request')" prop="url">
<el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="httpForm.url" <el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="httpForm.url"
class="ms-http-input" size="small" style="margin-top: 5px"> class="ms-http-input" size="small" style="margin-top: 5px">
<el-select v-model="httpForm.request.method.value" slot="prepend" style="width: 100px" size="small"> <el-select v-model="request.method.value" slot="prepend" style="width: 100px" size="small">
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/> <el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
</el-select> </el-select>
</el-input> </el-input>
@ -127,7 +127,7 @@
}, },
setParameter() { setParameter() {
this.httpForm.modulePath = this.getPath(this.httpForm.moduleId); this.httpForm.modulePath = this.getPath(this.httpForm.moduleId);
this.httpForm.request.path.value = this.httpForm.url; this.request.path.value = this.httpForm.url;
this.httpForm.request.useEnvironment = undefined; this.httpForm.request.useEnvironment = undefined;
}, },
saveApi() { saveApi() {
@ -153,7 +153,7 @@
return item.id === id ? item.path : ""; return item.id === id ? item.path : "";
}); });
return path[0].path; return path[0].path;
} },
}, },
created() { created() {

View File

@ -3,6 +3,7 @@
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="cancel">{{$t('commons.cancel')}}</el-button> <el-button @click="cancel">{{$t('commons.cancel')}}</el-button>
<el-button type="primary" @click="confirm" @keydown.enter.native.prevent>{{$t('commons.confirm')}}</el-button> <el-button type="primary" @click="confirm" @keydown.enter.native.prevent>{{$t('commons.confirm')}}</el-button>
<el-button type="primary" v-if="isShow" @click="saveAsEdit" @keydown.enter.native.prevent>{{title}}</el-button>
</div> </div>
</template> </template>
@ -10,12 +11,22 @@
<script> <script>
export default { export default {
name: "MsDialogFooter", name: "MsDialogFooter",
props: {
isShow: {
type: Boolean,
default: false,
},
title:String,
},
methods: { methods: {
cancel() { cancel() {
this.$emit("cancel"); this.$emit("cancel");
}, },
confirm() { confirm() {
this.$emit("confirm"); this.$emit("confirm");
},
saveAsEdit() {
this.$emit("saveAsEdit");
} }
} }
} }