feat(接口自动化): 完善回收站功能
This commit is contained in:
parent
0660600aab
commit
1f59d12f7b
|
@ -22,7 +22,6 @@ import io.metersphere.commons.constants.APITestStatus;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.constants.ReportTriggerMode;
|
import io.metersphere.commons.constants.ReportTriggerMode;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
import io.metersphere.track.dto.TestPlanDTO;
|
import io.metersphere.track.dto.TestPlanDTO;
|
||||||
|
@ -34,13 +33,11 @@ import org.apache.ibatis.session.SqlSession;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.apache.jorphan.collections.HashTree;
|
import org.apache.jorphan.collections.HashTree;
|
||||||
import org.apache.jorphan.collections.ListedHashTree;
|
import org.apache.jorphan.collections.ListedHashTree;
|
||||||
import org.aspectj.util.FileUtil;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.*;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -51,6 +48,8 @@ public class ApiAutomationService {
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioMapper apiScenarioMapper;
|
private ApiScenarioMapper apiScenarioMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
private ApiDefinitionService apiDefinitionService;
|
||||||
|
@Resource
|
||||||
private ExtApiScenarioMapper extApiScenarioMapper;
|
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiTagMapper apiTagMapper;
|
private ApiTagMapper apiTagMapper;
|
||||||
|
@ -126,13 +125,13 @@ public class ApiAutomationService {
|
||||||
apiScenarioMapper.insert(scenario);
|
apiScenarioMapper.insert(scenario);
|
||||||
|
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
createBodyFiles(bodyUploadIds, bodyFiles);
|
apiDefinitionService.createBodyFiles(bodyUploadIds, bodyFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles) {
|
public void update(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles) {
|
||||||
checkNameExist(request);
|
checkNameExist(request);
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
List<String> bodyUploadIds = request.getBodyUploadIds();
|
||||||
createBodyFiles(bodyUploadIds, bodyFiles);
|
apiDefinitionService.createBodyFiles(bodyUploadIds, bodyFiles);
|
||||||
|
|
||||||
final ApiScenario scenario = new ApiScenario();
|
final ApiScenario scenario = new ApiScenario();
|
||||||
scenario.setId(request.getId());
|
scenario.setId(request.getId());
|
||||||
|
@ -177,7 +176,7 @@ public class ApiAutomationService {
|
||||||
|
|
||||||
private void checkNameExist(SaveApiScenarioRequest request) {
|
private void checkNameExist(SaveApiScenarioRequest request) {
|
||||||
ApiScenarioExample example = new ApiScenarioExample();
|
ApiScenarioExample example = new ApiScenarioExample();
|
||||||
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId());
|
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId()).andStatusNotEqualTo("Trash").andIdNotEqualTo(request.getId());
|
||||||
if (apiScenarioMapper.countByExample(example) > 0) {
|
if (apiScenarioMapper.countByExample(example) > 0) {
|
||||||
MSException.throwException(Translator.get("automation_name_already_exists"));
|
MSException.throwException(Translator.get("automation_name_already_exists"));
|
||||||
}
|
}
|
||||||
|
@ -194,26 +193,6 @@ public class ApiAutomationService {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createBodyFiles(List<String> bodyUploadIds, List<MultipartFile> bodyFiles) {
|
|
||||||
if (!bodyUploadIds.isEmpty() && !bodyFiles.isEmpty()) {
|
|
||||||
File testDir = new File(BODY_FILE_DIR);
|
|
||||||
if (!testDir.exists()) {
|
|
||||||
testDir.mkdirs();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < bodyUploadIds.size(); i++) {
|
|
||||||
MultipartFile item = bodyFiles.get(i);
|
|
||||||
File file = new File(BODY_FILE_DIR + "/" + bodyUploadIds.get(i) + "_" + item.getOriginalFilename());
|
|
||||||
try (InputStream in = item.getInputStream(); OutputStream out = new FileOutputStream(file)) {
|
|
||||||
file.createNewFile();
|
|
||||||
FileUtil.copyStream(in, out);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
MSException.throwException(Translator.get("upload_fail"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteTag(String id) {
|
public void deleteTag(String id) {
|
||||||
List<ApiScenario> list = extApiScenarioMapper.selectByTagId(id);
|
List<ApiScenario> list = extApiScenarioMapper.selectByTagId(id);
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
|
@ -297,7 +276,7 @@ public class ApiAutomationService {
|
||||||
*/
|
*/
|
||||||
public String run(RunDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
public String run(RunDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
createBodyFiles(bodyUploadIds, bodyFiles);
|
apiDefinitionService.createBodyFiles(bodyUploadIds, bodyFiles);
|
||||||
EnvironmentConfig envConfig = null;
|
EnvironmentConfig envConfig = null;
|
||||||
if (request.getEnvironmentId() != null) {
|
if (request.getEnvironmentId() != null) {
|
||||||
ApiTestEnvironmentWithBLOBs environment = environmentService.get(request.getEnvironmentId());
|
ApiTestEnvironmentWithBLOBs environment = environmentService.get(request.getEnvironmentId());
|
||||||
|
|
|
@ -25,7 +25,7 @@ import io.metersphere.commons.utils.ServiceUtils;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
import io.metersphere.service.FileService;
|
import io.metersphere.service.FileService;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.ibatis.session.ExecutorType;
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
|
@ -33,13 +33,15 @@ import org.apache.jorphan.collections.HashTree;
|
||||||
import org.aspectj.util.FileUtil;
|
import org.aspectj.util.FileUtil;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import sun.security.util.Cache;
|
import sun.security.util.Cache;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -103,15 +105,17 @@ public class ApiDefinitionService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(SaveApiDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
public void update(SaveApiDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
||||||
|
if (request.getRequest() != null) {
|
||||||
deleteFileByTestId(request.getRequest().getId());
|
deleteFileByTestId(request.getRequest().getId());
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
}
|
||||||
|
List<String> bodyUploadIds = request.getBodyUploadIds();
|
||||||
request.setBodyUploadIds(null);
|
request.setBodyUploadIds(null);
|
||||||
updateTest(request);
|
updateTest(request);
|
||||||
createBodyFiles(bodyUploadIds, bodyFiles);
|
createBodyFiles(bodyUploadIds, bodyFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createBodyFiles(List<String> bodyUploadIds, List<MultipartFile> bodyFiles) {
|
public void createBodyFiles(List<String> bodyUploadIds, List<MultipartFile> bodyFiles) {
|
||||||
if (bodyUploadIds.size() > 0) {
|
if (CollectionUtils.isNotEmpty(bodyUploadIds) && CollectionUtils.isNotEmpty(bodyFiles)) {
|
||||||
File testDir = new File(BODY_FILE_DIR);
|
File testDir = new File(BODY_FILE_DIR);
|
||||||
if (!testDir.exists()) {
|
if (!testDir.exists()) {
|
||||||
testDir.mkdirs();
|
testDir.mkdirs();
|
||||||
|
@ -139,10 +143,9 @@ public class ApiDefinitionService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteBatch(List<String> apiIds) {
|
public void deleteBatch(List<String> apiIds) {
|
||||||
// 简单处理后续优化
|
ApiDefinitionExample example = new ApiDefinitionExample();
|
||||||
apiIds.forEach(item -> {
|
example.createCriteria().andIdIn(apiIds);
|
||||||
delete(item);
|
apiDefinitionMapper.deleteByExample(example);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeToGc(List<String> apiIds) {
|
public void removeToGc(List<String> apiIds) {
|
||||||
|
@ -160,14 +163,14 @@ public class ApiDefinitionService {
|
||||||
private void checkNameExist(SaveApiDefinitionRequest request) {
|
private void checkNameExist(SaveApiDefinitionRequest request) {
|
||||||
ApiDefinitionExample example = new ApiDefinitionExample();
|
ApiDefinitionExample example = new ApiDefinitionExample();
|
||||||
if (request.getProtocol().equals(RequestType.HTTP)) {
|
if (request.getProtocol().equals(RequestType.HTTP)) {
|
||||||
example.createCriteria().andMethodEqualTo(request.getMethod())
|
example.createCriteria().andMethodEqualTo(request.getMethod()).andStatusNotEqualTo("Trash")
|
||||||
.andProtocolEqualTo(request.getProtocol()).andPathEqualTo(request.getPath())
|
.andProtocolEqualTo(request.getProtocol()).andPathEqualTo(request.getPath())
|
||||||
.andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId());
|
.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"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
example.createCriteria().andProtocolEqualTo(request.getProtocol())
|
example.createCriteria().andProtocolEqualTo(request.getProtocol()).andStatusNotEqualTo("Trash")
|
||||||
.andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId())
|
.andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId())
|
||||||
.andIdNotEqualTo(request.getId());
|
.andIdNotEqualTo(request.getId());
|
||||||
if (apiDefinitionMapper.countByExample(example) > 0) {
|
if (apiDefinitionMapper.countByExample(example) > 0) {
|
||||||
|
@ -176,7 +179,6 @@ public class ApiDefinitionService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ApiDefinition updateTest(SaveApiDefinitionRequest request) {
|
private ApiDefinition updateTest(SaveApiDefinitionRequest request) {
|
||||||
checkNameExist(request);
|
checkNameExist(request);
|
||||||
final ApiDefinitionWithBLOBs test = new ApiDefinitionWithBLOBs();
|
final ApiDefinitionWithBLOBs test = new ApiDefinitionWithBLOBs();
|
||||||
|
|
|
@ -47,11 +47,16 @@
|
||||||
show-overflow-tooltip/>
|
show-overflow-tooltip/>
|
||||||
<el-table-column :label="$t('commons.operating')" width="200px" v-if="!referenced">
|
<el-table-column :label="$t('commons.operating')" width="200px" v-if="!referenced">
|
||||||
<template v-slot:default="{row}">
|
<template v-slot:default="{row}">
|
||||||
|
<div v-if="currentModule!=undefined && currentModule.id === 'gc'">
|
||||||
|
<el-button type="text" @click="reductionApi(row)">恢复</el-button>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
<el-button type="text" @click="edit(row)">{{ $t('api_test.automation.edit') }}</el-button>
|
<el-button type="text" @click="edit(row)">{{ $t('api_test.automation.edit') }}</el-button>
|
||||||
<el-button type="text" @click="execute(row)">{{ $t('api_test.automation.execute') }}</el-button>
|
<el-button type="text" @click="execute(row)">{{ $t('api_test.automation.execute') }}</el-button>
|
||||||
<el-button type="text" @click="copy(row)">{{ $t('api_test.automation.copy') }}</el-button>
|
<el-button type="text" @click="copy(row)">{{ $t('api_test.automation.copy') }}</el-button>
|
||||||
<el-button type="text" @click="remove(row)">{{ $t('api_test.automation.remove') }}</el-button>
|
<el-button type="text" @click="remove(row)">{{ $t('api_test.automation.remove') }}</el-button>
|
||||||
<ms-scenario-extend-buttons :row="row"/>
|
<ms-scenario-extend-buttons :row="row"/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
@ -202,6 +207,13 @@
|
||||||
edit(row) {
|
edit(row) {
|
||||||
this.$emit('edit', row);
|
this.$emit('edit', row);
|
||||||
},
|
},
|
||||||
|
reductionApi(row) {
|
||||||
|
let obj = {id: row.id, projectId: row.projectId, name: row.name, status: 'Underway'}
|
||||||
|
this.$fileUpload("/api/automation/update", null, [], obj, () => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.search();
|
||||||
|
})
|
||||||
|
},
|
||||||
execute(row) {
|
execute(row) {
|
||||||
this.infoDb = false;
|
this.infoDb = false;
|
||||||
let url = "/api/automation/run";
|
let url = "/api/automation/run";
|
||||||
|
|
|
@ -240,7 +240,7 @@
|
||||||
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('api_test.automation.api_list_import')" :modal="false" size="90%">
|
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('api_test.automation.api_list_import')" :modal="false" size="90%">
|
||||||
<ms-api-definition :visible="true" :currentRow="currentRow"/>
|
<ms-api-definition :visible="true" :currentRow="currentRow"/>
|
||||||
<!--<el-button style="float: right;margin: 20px" type="primary" @click="copyApi('REF')">{{$t('api_test.scenario.reference')}}</el-button>-->
|
<!--<el-button style="float: right;margin: 20px" type="primary" @click="copyApi('REF')">{{$t('api_test.scenario.reference')}}</el-button>-->
|
||||||
<el-button style="float: right;margin: 20px 0px 0px " type="primary" @click="copyApi('Copy')">{{ $t('commons.copy') }}</el-button>
|
<el-button style="float: right;margin: 0px 20px 0px" type="primary" @click="copyApi('Copy')">{{ $t('commons.copy') }}</el-button>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
<!--自定义接口-->
|
<!--自定义接口-->
|
||||||
|
@ -326,6 +326,7 @@
|
||||||
userId: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
userId: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||||
apiScenarioModuleId: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
apiScenarioModuleId: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
||||||
status: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
status: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
||||||
|
principal: [{required: true, message: this.$t('api_test.definition.request.responsible'), trigger: 'change'}],
|
||||||
},
|
},
|
||||||
environments: [],
|
environments: [],
|
||||||
tags: [],
|
tags: [],
|
||||||
|
@ -684,11 +685,13 @@
|
||||||
this.path = "/api/automation/update";
|
this.path = "/api/automation/update";
|
||||||
if (response.data.scenarioDefinition != null) {
|
if (response.data.scenarioDefinition != null) {
|
||||||
let obj = JSON.parse(response.data.scenarioDefinition);
|
let obj = JSON.parse(response.data.scenarioDefinition);
|
||||||
|
if (obj) {
|
||||||
this.currentEnvironmentId = obj.environmentId;
|
this.currentEnvironmentId = obj.environmentId;
|
||||||
this.currentScenario.variables = obj.variables;
|
this.currentScenario.variables = obj.variables;
|
||||||
this.scenarioDefinition = obj.hashTree;
|
this.scenarioDefinition = obj.hashTree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -77,7 +77,8 @@
|
||||||
<el-button type="text" @click="handleTestCase(scope.row)">用例</el-button>
|
<el-button type="text" @click="handleTestCase(scope.row)">用例</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<el-button type="text" @click="editApi(scope.row)">编辑</el-button>
|
<el-button type="text" @click="reductionApi(scope.row)" v-if="currentModule!=undefined && currentModule.id === 'gc'">恢复</el-button>
|
||||||
|
<el-button type="text" @click="editApi(scope.row)" v-else>编辑</el-button>
|
||||||
<el-button type="text" @click="handleTestCase(scope.row)">用例</el-button>
|
<el-button type="text" @click="handleTestCase(scope.row)">用例</el-button>
|
||||||
<el-button type="text" @click="handleDelete(scope.row)" style="color: #F56C6C">删除</el-button>
|
<el-button type="text" @click="handleDelete(scope.row)" style="color: #F56C6C">删除</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -256,6 +257,15 @@
|
||||||
editApi(row) {
|
editApi(row) {
|
||||||
this.$emit('editApi', row);
|
this.$emit('editApi', row);
|
||||||
},
|
},
|
||||||
|
reductionApi(row) {
|
||||||
|
row.status = 'Underway';
|
||||||
|
row.request = null;
|
||||||
|
row.response = null;
|
||||||
|
this.$fileUpload("/api/definition/update", null, [], row, () => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.search();
|
||||||
|
});
|
||||||
|
},
|
||||||
handleDeleteBatch() {
|
handleDeleteBatch() {
|
||||||
if (this.currentModule != undefined && this.currentModule.id == "gc") {
|
if (this.currentModule != undefined && this.currentModule.id == "gc") {
|
||||||
this.$alert(this.$t('api_test.definition.request.delete_confirm') + "?", '', {
|
this.$alert(this.$t('api_test.definition.request.delete_confirm') + "?", '', {
|
||||||
|
|
Loading…
Reference in New Issue