diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java index b30a290eeb..8c28f72bbc 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.Setter; import java.util.List; +import java.util.Map; @Getter @Setter @@ -24,7 +25,7 @@ public class ApiBatchRequest extends ApiDefinitionWithBLOBs { */ private boolean isSelectAllDate; - private List filters; + private Map> filters; private String name; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionBatchProcessingRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionBatchProcessingRequest.java index 834a98831a..44a17ab1c6 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionBatchProcessingRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionBatchProcessingRequest.java @@ -4,6 +4,7 @@ import lombok.Getter; import lombok.Setter; import java.util.List; +import java.util.Map; /** * 接口定义模块-批量处理请求类 @@ -24,7 +25,7 @@ public class ApiDefinitionBatchProcessingRequest { */ private boolean isSelectAllDate; - private List filters; + private Map> filters; private String name; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionRequest.java index 3073ed8300..0f40f3cc78 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionRequest.java @@ -23,7 +23,7 @@ public class ApiDefinitionRequest { private String planId; private boolean recent = false; private List orders; - private List filters; + private Map> filters; private Map combine; private List ids; private boolean isSelectThisWeedData = false; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiDefinitionRequest.java index ef017c8bd2..0dad6ff49f 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiDefinitionRequest.java @@ -6,7 +6,6 @@ import io.metersphere.base.domain.Schedule; import lombok.Getter; import lombok.Setter; -import java.util.ArrayList; import java.util.List; @Setter @@ -49,5 +48,5 @@ public class SaveApiDefinitionRequest { private List bodyUploadIds; - private List tags = new ArrayList<>(); + private String tags; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiTestCaseRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiTestCaseRequest.java index a04a8bd01e..34815ceee7 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiTestCaseRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiTestCaseRequest.java @@ -4,7 +4,6 @@ import io.metersphere.api.dto.definition.request.MsTestElement; import lombok.Getter; import lombok.Setter; -import java.util.ArrayList; import java.util.List; @Setter @@ -37,5 +36,5 @@ public class SaveApiTestCaseRequest { private List bodyUploadIds; - private List tags = new ArrayList<>(); + private String tags; } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 247da9e765..5e27a4e8c8 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -29,7 +29,6 @@ import io.metersphere.base.mapper.ext.ExtApiScenarioMapper; import io.metersphere.base.mapper.ext.ExtTestPlanMapper; import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.ApiRunMode; -import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.*; import io.metersphere.i18n.Translator; @@ -235,7 +234,7 @@ public class ApiDefinitionService { test.setResponse(JSONObject.toJSONString(request.getResponse())); test.setEnvironmentId(request.getEnvironmentId()); test.setUserId(request.getUserId()); - test.setTags(JSON.toJSONString(new HashSet<>(request.getTags()))); + test.setTags(request.getTags()); apiDefinitionMapper.updateByPrimaryKeySelective(test); return test; @@ -266,7 +265,7 @@ public class ApiDefinitionService { test.setUserId(request.getUserId()); } test.setDescription(request.getDescription()); - test.setTags(JSON.toJSONString(new HashSet<>(request.getTags()))); + test.setTags(request.getTags()); apiDefinitionMapper.insert(test); return test; } @@ -342,10 +341,11 @@ public class ApiDefinitionService { /** * 内部构建HashTree 定时任务发起的执行 + * * @param request * @return */ - public String run(RunDefinitionRequest request,ApiTestCaseWithBLOBs item) { + public String run(RunDefinitionRequest request, ApiTestCaseWithBLOBs item) { MsTestPlan testPlan = new MsTestPlan(); testPlan.setHashTree(new LinkedList<>()); HashTree jmeterHashTree = new ListedHashTree(); @@ -362,12 +362,14 @@ public class ApiDefinitionService { // 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取 if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) { LinkedList elements = mapper.readValue(element.getString("hashTree"), - new TypeReference>() {}); + new TypeReference>() { + }); scenario.setHashTree(elements); } if (StringUtils.isNotEmpty(element.getString("variables"))) { LinkedList variables = mapper.readValue(element.getString("variables"), - new TypeReference>() {}); + new TypeReference>() { + }); scenario.setVariables(variables); } group.setEnableCookieShare(scenario.isEnableCookieShare()); @@ -572,9 +574,9 @@ public class ApiDefinitionService { apiDefinitionMapper.deleteByExample(example); } - private List getAllApiIdsByFontedSelect(List filter, String name, List moduleIds, String projectId, List unSelectIds) { + private List getAllApiIdsByFontedSelect(Map> filters, String name, List moduleIds, String projectId, List unSelectIds) { ApiDefinitionRequest request = new ApiDefinitionRequest(); - request.setFilters(filter); + request.setFilters(filters); request.setName(name); request.setModuleIds(moduleIds); request.setProjectId(projectId); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index 0ef72ec5d0..bf62372aba 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -225,7 +225,7 @@ public class ApiTestCaseService { test.setPriority(request.getPriority()); test.setUpdateTime(System.currentTimeMillis()); test.setDescription(request.getDescription()); - test.setTags(JSON.toJSONString(new HashSet<>(request.getTags()))); + test.setTags(request.getTags()); apiTestCaseMapper.updateByPrimaryKeySelective(test); return test; } @@ -247,7 +247,7 @@ public class ApiTestCaseService { test.setUpdateTime(System.currentTimeMillis()); test.setDescription(request.getDescription()); test.setNum(getNextNum(request.getApiDefinitionId())); - test.setTags(JSON.toJSONString(new HashSet<>(request.getTags()))); + test.setTags(request.getTags()); apiTestCaseMapper.insert(test); return test; } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml index ee3a5eaa1f..0fe7d1398b 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml @@ -243,9 +243,17 @@ - and api_definition.status in - - #{value} + + + + + and api_definition.status in + + #{value} + + + + diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.java index 590e9605d7..29bf5bc474 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.java @@ -8,5 +8,5 @@ import java.util.List; public interface ExtTestPlanLoadCaseMapper { List selectIdsNotInPlan(@Param("projectId") String projectId, @Param("planId") String planId); - List selectTestPlanLoadCaseList(@Param("planId") String planId); + List selectTestPlanLoadCaseList(@Param("planId") String planId, @Param("projectId") String projectId); } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.xml index e99558c432..7b2f666cbf 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.xml @@ -11,11 +11,25 @@ ) \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/track/controller/TestPlanLoadCaseController.java b/backend/src/main/java/io/metersphere/track/controller/TestPlanLoadCaseController.java index 28dc2ee23b..ab1730626c 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestPlanLoadCaseController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestPlanLoadCaseController.java @@ -52,4 +52,9 @@ public class TestPlanLoadCaseController { public Boolean isExistReport(@RequestBody LoadCaseReportRequest request) { return testPlanLoadCaseService.isExistReport(request); } + + @PostMapping("/batch/delete") + public void batchDelete(@RequestBody List ids) { + testPlanLoadCaseService.batchDelete(ids); + } } diff --git a/backend/src/main/java/io/metersphere/track/dto/TestPlanLoadCaseDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestPlanLoadCaseDTO.java index 3e08fed138..572532baf0 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestPlanLoadCaseDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestPlanLoadCaseDTO.java @@ -9,4 +9,5 @@ import lombok.Setter; public class TestPlanLoadCaseDTO extends TestPlanLoadCase { private String userName; private String caseName; + private String projectName; } diff --git a/backend/src/main/java/io/metersphere/track/request/testcase/EditTestCaseRequest.java b/backend/src/main/java/io/metersphere/track/request/testcase/EditTestCaseRequest.java index 37d58ec62e..3da65becc6 100644 --- a/backend/src/main/java/io/metersphere/track/request/testcase/EditTestCaseRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testcase/EditTestCaseRequest.java @@ -16,5 +16,4 @@ public class EditTestCaseRequest extends TestCaseWithBLOBs { * 复制测试用例后,要进行复制的文件Id list */ private List fileIds = new ArrayList<>(); - private List caseTags = new ArrayList<>(); } diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java index cd263edad7..9237735195 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -585,7 +585,6 @@ public class TestCaseService { throw new IllegalArgumentException(Translator.get("file_cannot_be_null")); } - request.setTags(JSON.toJSONString(new HashSet<>(request.getCaseTags()))); final TestCaseWithBLOBs testCaseWithBLOBs = addTestCase(request); // 复制用例时传入文件ID进行复制 @@ -642,7 +641,6 @@ public class TestCaseService { }); } - request.setTags(JSON.toJSONString(new HashSet<>(request.getCaseTags()))); editTestCase(request); return request.getId(); } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java index caa4ce1e6e..f300203be7 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java @@ -1,6 +1,7 @@ package io.metersphere.track.service; import io.metersphere.base.domain.*; +import io.metersphere.base.mapper.LoadTestMapper; import io.metersphere.base.mapper.LoadTestReportMapper; import io.metersphere.base.mapper.TestPlanLoadCaseMapper; import io.metersphere.base.mapper.ext.ExtTestPlanLoadCaseMapper; @@ -20,6 +21,7 @@ import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; @Service @Transactional(rollbackFor = Exception.class) @@ -35,6 +37,8 @@ public class TestPlanLoadCaseService { private SqlSessionFactory sqlSessionFactory; @Resource private LoadTestReportMapper loadTestReportMapper; + @Resource + private LoadTestMapper loadTestMapper; public List relevanceList(LoadCaseRequest request) { List ids = extTestPlanLoadCaseMapper.selectIdsNotInPlan(request.getProjectId(), request.getTestPlanId()); @@ -45,7 +49,7 @@ public class TestPlanLoadCaseService { } public List list(LoadCaseRequest request) { - return extTestPlanLoadCaseMapper.selectTestPlanLoadCaseList(request.getTestPlanId()); + return extTestPlanLoadCaseMapper.selectTestPlanLoadCaseList(request.getTestPlanId(), request.getProjectId()); } public void relevanceCase(LoadCaseRequest request) { @@ -96,4 +100,26 @@ public class TestPlanLoadCaseService { } return true; } + + public void deleteByRelevanceProjectIds(String id, List relevanceProjectIds) { + LoadTestExample loadTestExample = new LoadTestExample(); + loadTestExample.createCriteria().andProjectIdIn(relevanceProjectIds); + List loadTests = loadTestMapper.selectByExample(loadTestExample); + TestPlanLoadCaseExample testPlanLoadCaseExample = new TestPlanLoadCaseExample(); + TestPlanLoadCaseExample.Criteria criteria = testPlanLoadCaseExample.createCriteria().andTestPlanIdEqualTo(id); + if (!CollectionUtils.isEmpty(loadTests)) { + List ids = loadTests.stream().map(LoadTest::getId).collect(Collectors.toList()); + criteria.andLoadCaseIdNotIn(ids); + } + testPlanLoadCaseMapper.deleteByExample(testPlanLoadCaseExample); + } + + public void batchDelete(List ids) { + if (CollectionUtils.isEmpty(ids)) { + return; + } + TestPlanLoadCaseExample example = new TestPlanLoadCaseExample(); + example.createCriteria().andIdIn(ids); + testPlanLoadCaseMapper.deleteByExample(example); + } } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index 6c2354c5fc..24521392db 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -87,6 +87,8 @@ public class TestPlanService { private TestPlanApiCaseService testPlanApiCaseService; @Resource private TestPlanScenarioCaseService testPlanScenarioCaseService; + @Resource + private TestPlanLoadCaseService testPlanLoadCaseService; public synchronized void addTestPlan(AddTestPlanRequest testPlan) { if (getTestPlanByName(testPlan.getName()).size() > 0) { @@ -234,6 +236,7 @@ public class TestPlanService { } testPlanApiCaseService.deleteByRelevanceProjectIds(testPlan.getId(), relevanceProjectIds); testPlanScenarioCaseService.deleteByRelevanceProjectIds(testPlan.getId(), relevanceProjectIds); + testPlanLoadCaseService.deleteByRelevanceProjectIds(testPlan.getId(), relevanceProjectIds); } } diff --git a/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue b/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue index 24c5ac8f2d..4387c8a728 100644 --- a/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue +++ b/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue @@ -24,26 +24,7 @@ - - {{ tag }} - - - - + +
@@ -57,15 +38,15 @@
- - - - - - + + + + + + @@ -112,10 +93,12 @@ import MsSqlBasisParameters from "../request/database/BasisParameters"; import MsTcpBasisParameters from "../request/tcp/BasisParameters"; import MsDubboBasisParameters from "../request/dubbo/BasisParameters"; import MsApiExtendBtns from "../reference/ApiExtendBtns"; +import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag"; export default { name: "ApiCaseItem", components: { + MsInputTag, MsTag, MsTipButton, MsApiRequestForm, @@ -139,8 +122,6 @@ export default { visible: false, condition: {}, isShowInput: false, - inputVisible: false, - inputValue: '' } }, props: { @@ -213,21 +194,25 @@ export default { } }, saveTestCase(row) { + let tmp = JSON.parse(JSON.stringify(row)); this.isShowInput = false; - if (this.validate(row)) { + if (this.validate(tmp)) { return; } - let bodyFiles = this.getBodyUploadFiles(row); - row.projectId = getCurrentProjectID(); - row.active = true; - row.request.path = this.api.path; - row.request.method = this.api.method; - row.apiDefinitionId = row.apiDefinitionId || this.api.id; + let bodyFiles = this.getBodyUploadFiles(tmp); + tmp.projectId = getCurrentProjectID(); + tmp.active = true; + tmp.request.path = this.api.path; + tmp.request.method = this.api.method; + tmp.apiDefinitionId = tmp.apiDefinitionId || this.api.id; let url = "/api/testcase/create"; - if (row.id) { + if (tmp.id) { url = "/api/testcase/update"; } - this.$fileUpload(url, null, bodyFiles, row, () => { + if (tmp.tags instanceof Array) { + tmp.tags = JSON.stringify(tmp.tags); + } + this.$fileUpload(url, null, bodyFiles, tmp, () => { this.$success(this.$t('commons.save_success')); this.$emit('refresh'); }); @@ -293,28 +278,6 @@ export default { } return bodyUploadFiles; }, - handleClose(tag) { - this.apiCase.tags.splice(this.apiCase.tags.indexOf(tag), 1); - this.saveTestCase(this.apiCase) - }, - - showTagInput() { - this.inputVisible = true; - this.$nextTick(_ => { - this.$refs.saveTagInput.$refs.input.focus(); - }); - }, - - handleInputConfirm() { - let inputValue = this.inputValue; - if (inputValue) { - this.apiCase.tags.push(inputValue); - this.saveTestCase(this.apiCase) - } - this.inputVisible = false; - this.inputValue = ''; - } - } } @@ -356,22 +319,4 @@ export default { .is-selected { background: #EFF7FF; } - -.el-tag + .el-tag { - margin-left: 10px; -} - -.button-new-tag { - margin-left: 10px; - height: 20px; - /*line-height: 30px;*/ - padding-top: 0; - padding-bottom: 0; -} - -.input-new-tag { - width: 90px; - margin-left: 10px; - vertical-align: bottom; -} diff --git a/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue b/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue index 973b4b923a..6b94fda754 100644 --- a/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue +++ b/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue @@ -177,9 +177,7 @@ export default { this.addCase(); } this.apiCaseList.forEach(apiCase => { - if (!apiCase.tags) { - apiCase.tags = []; - } else { + if (apiCase.tags && apiCase.tags.length > 0) { apiCase.tags = JSON.parse(apiCase.tags); } }) diff --git a/frontend/src/business/components/api/definition/components/complete/BasisApi.vue b/frontend/src/business/components/api/definition/components/complete/BasisApi.vue index 439bb55c58..8dc7951e7e 100644 --- a/frontend/src/business/components/api/definition/components/complete/BasisApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/BasisApi.vue @@ -17,8 +17,9 @@
- {{$t('api_test.definition.select_comp.no_data')}}, - {{$t('api_test.definition.select_comp.add_data')}} + {{ $t('api_test.definition.select_comp.no_data') }}, + + {{ $t('api_test.definition.select_comp.add_data') }}
@@ -54,27 +55,7 @@ - - {{ tag }} - - - - + - + @@ -94,111 +75,69 @@ diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteDubboApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteDubboApi.vue index fb8a41a3ce..88d9af53d7 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteDubboApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteDubboApi.vue @@ -6,87 +6,91 @@
- {{$t('commons.save')}} - {{$t('commons.test')}} + {{ $t('commons.save') }} + {{ $t('commons.test') }}
-

{{$t('test_track.plan_view.base_info')}}

+

{{ $t('test_track.plan_view.base_info') }}


- + -

{{$t('api_test.definition.request.req_param')}}

+

{{ $t('api_test.definition.request.req_param') }}

diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue index 5b39e8d319..85e7a65921 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue @@ -77,27 +77,7 @@ - - {{ tag }} - - - - + - + @@ -134,10 +114,11 @@ import {WORKSPACE_ID} from '../../../../../../common/js/constants'; import {API_STATUS, REQ_METHOD} from "../../model/JsonData"; import MsJsr233Processor from "../processor/Jsr233Processor"; import {KeyValue} from "../../model/ApiTestModel"; +import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag"; export default { name: "MsAddCompleteHttpApi", - components: {MsResponseText, MsApiRequestForm, MsJsr233Processor}, + components: {MsResponseText, MsApiRequestForm, MsJsr233Processor, MsInputTag}, data() { let validateURL = (rule, value, callback) => { if (!this.httpForm.path.startsWith("/") || this.httpForm.path.match(/\s/) != null) { @@ -165,8 +146,6 @@ export default { currentModule: {}, reqOptions: REQ_METHOD, options: API_STATUS, - inputVisible: false, - inputValue: '' } }, props: {moduleOptions: {}, request: {}, response: {}, basisData: {}}, @@ -192,6 +171,9 @@ export default { this.request.path = this.httpForm.path; this.request.method = this.httpForm.method; this.httpForm.request.useEnvironment = undefined; + if (this.httpForm.tags instanceof Array) { + this.httpForm.tags = JSON.stringify(this.httpForm.tags); + } }, saveApi() { this.$refs['httpForm'].validate((valid) => { @@ -243,26 +225,6 @@ export default { this.$error(this.$t('api_test.request.url_invalid'), 2000); } }, - - handleClose(tag) { - this.httpForm.tags.splice(this.httpForm.tags.indexOf(tag), 1); - }, - - showInput() { - this.inputVisible = true; - this.$nextTick(_ => { - this.$refs.saveTagInput.$refs.input.focus(); - }); - }, - - handleInputConfirm() { - let inputValue = this.inputValue; - if (inputValue) { - this.httpForm.tags.push(inputValue); - } - this.inputVisible = false; - this.inputValue = ''; - } }, created() { @@ -270,11 +232,6 @@ export default { if (!this.basisData.environmentId) { this.basisData.environmentId = ""; } - if (!this.basisData.tags) { - this.basisData.tags = []; - } else { - this.basisData.tags = JSON.parse(this.basisData.tags); - } this.httpForm = JSON.parse(JSON.stringify(this.basisData)); } @@ -314,22 +271,4 @@ export default { .ms-left-buttion { margin: 6px 0px 8px 30px; } - -.el-tag + .el-tag { - margin-left: 10px; -} - -.button-new-tag { - margin-left: 10px; - height: 20px; - /*line-height: 30px;*/ - padding-top: 0; - padding-bottom: 0; -} - -.input-new-tag { - width: 90px; - margin-left: 10px; - vertical-align: bottom; -} diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteSQLApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteSQLApi.vue index 4ca16a2d0b..94e434e7b4 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteSQLApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteSQLApi.vue @@ -5,84 +5,88 @@
- {{$t('commons.save')}} - {{$t('commons.test')}} + {{ $t('commons.save') }} + {{ $t('commons.test') }}
-

{{$t('test_track.plan_view.base_info')}}

+

{{ $t('test_track.plan_view.base_info') }}


- + -

{{$t('api_test.definition.request.req_param')}}

+

{{ $t('api_test.definition.request.req_param') }}

diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteTCPApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteTCPApi.vue index 6d26a4da03..4148d999e2 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteTCPApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteTCPApi.vue @@ -5,22 +5,23 @@
- {{$t('commons.save')}} - {{$t('commons.test')}} + {{ $t('commons.save') }} + {{ $t('commons.test') }}
-

{{$t('test_track.plan_view.base_info')}}

+

{{ $t('test_track.plan_view.base_info') }}


- + -

{{$t('api_test.definition.request.req_param')}}

+

{{ $t('api_test.definition.request.req_param') }}

@@ -28,62 +29,65 @@ diff --git a/frontend/src/business/components/api/definition/components/list/ApiList.vue b/frontend/src/business/components/api/definition/components/list/ApiList.vue index c42137f85b..281c299d10 100644 --- a/frontend/src/business/components/api/definition/components/list/ApiList.vue +++ b/frontend/src/business/components/api/definition/components/list/ApiList.vue @@ -10,6 +10,8 @@ @@ -27,18 +29,21 @@ - - + + + column-key="status" + sortable="custom" + :filters="statusFilters" + :label="$t('api_test.definition.api_status')"> @@ -66,10 +71,9 @@ @@ -128,14 +132,16 @@ import MsBottomContainer from "../BottomContainer"; import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn"; import MsBatchEdit from "../basis/BatchEdit"; import {API_METHOD_COLOUR, API_STATUS, REQ_METHOD} from "../../model/JsonData"; -import {getCurrentProjectID} from "@/common/js/utils"; +import {_filter, _sort, getCurrentProjectID} from "@/common/js/utils"; import {WORKSPACE_ID} from '@/common/js/constants'; import ApiListContainer from "./ApiListContainer"; import MsTableSelectAll from "../../../../common/components/table/MsTableSelectAll"; +import ApiStatus from "@/business/components/api/definition/components/list/ApiStatus"; export default { name: "ApiList", components: { + ApiStatus, MsTableSelectAll, ApiListContainer, MsTableButton, @@ -168,6 +174,12 @@ export default { {id: 'method', name: this.$t('api_test.definition.api_type')}, {id: 'userId', name: this.$t('api_test.definition.api_principal')}, ], + statusFilters: [ + {text: this.$t('test_track.plan.plan_status_prepare'), value: 'Prepare'}, + {text: this.$t('test_track.plan.plan_status_running'), value: 'Underway'}, + {text: this.$t('test_track.plan.plan_status_completed'), value: 'Completed'}, + {text: this.$t('test_track.plan.plan_status_trash'), value: 'Trash'}, + ], valueArr: { status: API_STATUS, method: REQ_METHOD, @@ -208,6 +220,7 @@ export default { }, }, created: function () { + this.condition.filters = {status: ["Prepare", "Underway", "Completed"]}; this.initTable(); this.getMaintainerOptions(); }, @@ -220,8 +233,12 @@ export default { }, trashEnable() { if (this.trashEnable) { - this.initTable(); + this.condition.filters = {status: ["Trash"]}; + this.condition.moduleIds = []; + } else { + this.condition.filters = {status: ["Prepare", "Underway", "Completed"]}; } + this.initTable(); } }, methods: { @@ -235,14 +252,8 @@ export default { this.unSelection = []; this.selectDataCounts = 0; - this.condition.filters = ["Prepare", "Underway", "Completed"]; this.condition.moduleIds = this.selectNodeIds; - if (this.trashEnable) { - this.condition.filters = ["Trash"]; - this.condition.moduleIds = []; - } - this.condition.projectId = getCurrentProjectID(); if (this.currentProtocol != null) { this.condition.protocol = this.currentProtocol; @@ -256,15 +267,6 @@ export default { case 'thisWeekCount': this.condition.selectThisWeedData = true; break; - case 'Prepare': - this.condition.filters = [this.selectDataRange]; - break; - case 'Completed': - this.condition.filters = [this.selectDataRange]; - break; - case 'Underway': - this.condition.filters = [this.selectDataRange]; - break; case 'uncoverage': this.condition.apiCaseCoverage = 'uncoverage'; break; @@ -278,9 +280,9 @@ export default { this.tableData = response.data.listObject; this.unSelection = response.data.listObject.map(s => s.id); - this.tableData.forEach(row => { - if (row.tags) { - row.showTags = JSON.parse(); + this.tableData.forEach(item => { + if (item.tags && item.tags.length > 0) { + item.tags = JSON.parse(item.tags); } }) }); @@ -344,9 +346,13 @@ export default { this.$emit('editApi', row); }, reductionApi(row) { - row.request = null; - row.response = null; - let rows = [row]; + let tmp = JSON.parse(JSON.stringify(row)); + tmp.request = null; + tmp.response = null; + if (tmp.tags instanceof Array) { + tmp.tags = JSON.stringify(tmp.tags); + } + let rows = [tmp]; this.$post('/api/definition/reduction/', rows, () => { this.$success(this.$t('commons.save_success')); this.search(); @@ -497,7 +503,19 @@ export default { let rowArray = Array.from(rowSets) let ids = rowArray.map(s => s.id); return ids; - } + }, + sort(column) { + // 每次只对一个字段排序 + if (this.condition.orders) { + this.condition.orders = []; + } + _sort(column, this.condition); + this.initTable(); + }, + filter(filters) { + _filter(filters, this.condition); + this.initTable(); + }, }, } diff --git a/frontend/src/business/components/api/definition/components/list/ApiStatus.vue b/frontend/src/business/components/api/definition/components/list/ApiStatus.vue new file mode 100644 index 0000000000..5b5cfe132d --- /dev/null +++ b/frontend/src/business/components/api/definition/components/list/ApiStatus.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/frontend/src/business/components/track/case/components/TestCaseEdit.vue b/frontend/src/business/components/track/case/components/TestCaseEdit.vue index 68bc2fbb8c..ff9667f901 100644 --- a/frontend/src/business/components/track/case/components/TestCaseEdit.vue +++ b/frontend/src/business/components/track/case/components/TestCaseEdit.vue @@ -69,27 +69,7 @@ - - {{ tag }} - - - - + - + @@ -298,10 +278,11 @@ import TestCaseAttachment from "@/business/components/track/case/components/Test import {getCurrentProjectID} from "../../../../../common/js/utils"; import {buildNodePath} from "../../../api/definition/model/NodeTree"; import CaseComment from "@/business/components/track/case/components/CaseComment"; +import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag"; export default { name: "TestCaseEdit", - components: {CaseComment, MsDialogFooter, TestCaseAttachment}, + components: {MsInputTag, CaseComment, MsDialogFooter, TestCaseAttachment}, data() { return { result: {}, @@ -323,7 +304,6 @@ export default { result: '' }], remark: '', - caseTags: [] }, moduleOptions: [], maintainerOptions: [], @@ -355,8 +335,6 @@ export default { {value: 'manual', label: this.$t('test_track.case.manual')} ], testCase: {}, - inputVisible: false, - inputValue: '' }; }, props: { @@ -387,7 +365,7 @@ export default { open(testCase) { this.testCase = {}; if (testCase) { - testCase.caseTags = JSON.parse(testCase.tags); + testCase.tags = JSON.parse(testCase.tags); // 复制 不查询评论 this.testCase = testCase.isCopy ? {} : testCase; } @@ -425,7 +403,6 @@ export default { this.form.type = 'functional'; this.form.method = 'manual'; this.form.maintainer = user.id; - this.form.caseTags = []; } this.getSelectOptions(); @@ -538,6 +515,10 @@ export default { if (param.method != 'auto') { param.testId = null; } + if (this.form.tags instanceof Array) { + this.form.tags = JSON.stringify(this.form.tags); + } + param.tags = this.form.tags; return param; }, getOption(param) { @@ -641,7 +622,6 @@ export default { desc: '', result: '' }]; - this.caseTags = []; this.uploadList = []; this.fileList = []; this.tableData = []; @@ -729,26 +709,6 @@ export default { /// todo: 是否需要对文件内容和大小做限制 return file.size > 0; }, - - handleClose(tag) { - this.form.caseTags.splice(this.form.caseTags.indexOf(tag), 1); - }, - - showInput() { - this.inputVisible = true; - this.$nextTick(_ => { - this.$refs.saveTagInput.$refs.input.focus(); - }); - }, - - handleInputConfirm() { - let inputValue = this.inputValue; - if (inputValue) { - this.form.caseTags.push(inputValue); - } - this.inputVisible = false; - this.inputValue = ''; - } } } @@ -788,21 +748,4 @@ export default { height: calc(100vh - 120px); } -.el-tag + .el-tag { - margin-left: 10px; -} - -.button-new-tag { - margin-left: 10px; - height: 20px; - /*line-height: 30px;*/ - padding-top: 0; - padding-bottom: 0; -} - -.input-new-tag { - width: 90px; - margin-left: 10px; - vertical-align: bottom; -} diff --git a/frontend/src/business/components/track/case/components/TestCaseList.vue b/frontend/src/business/components/track/case/components/TestCaseList.vue index d22ec68d2b..42e4bcd735 100644 --- a/frontend/src/business/components/track/case/components/TestCaseList.vue +++ b/frontend/src/business/components/track/case/components/TestCaseList.vue @@ -113,10 +113,9 @@ @@ -319,8 +318,10 @@ export default { this.tableData = data.listObject; // this.selectIds.clear(); this.selectRows.clear(); - this.tableData.forEach(row => { - row.showTags = JSON.parse(row.tags); + this.tableData.forEach(item => { + if (item.tags && item.tags.length > 0) { + item.tags = JSON.parse(item.tags); + } }) }); } diff --git a/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiCaseList.vue index 2355476d20..5e9dde2718 100644 --- a/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiCaseList.vue @@ -62,10 +62,9 @@ @@ -265,8 +264,10 @@ export default { this.result = this.$post('/test/plan/api/case/list/' + this.currentPage + "/" + this.pageSize, this.condition, response => { this.total = response.data.itemCount; this.tableData = response.data.listObject; - this.tableData.forEach(row => { - row.showTags = JSON.parse(row.tags); + this.tableData.forEach(item => { + if (item.tags && item.tags.length > 0) { + item.tags = JSON.parse(item.tags); + } }) }); }, @@ -479,7 +480,4 @@ export default { margin-right: 20px; } -.el-tag { - margin-left: 10px; -} diff --git a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoad.vue b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoad.vue index fd76aa1724..433feddc02 100644 --- a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoad.vue +++ b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoad.vue @@ -12,7 +12,7 @@ class="table-list" @refresh="refresh" :plan-id="planId" - :select-node-ids="selectNodeIds" + :select-project-id="selectProjectId" :select-parent-nodes="selectParentNodes" @relevanceCase="openTestCaseRelevanceDialog" ref="testPlanLoadCaseList"/> @@ -46,6 +46,7 @@ export default { result: {}, selectNodeIds: [], selectParentNodes: [], + selectProjectId: "", treeNodes: [], } }, @@ -74,8 +75,7 @@ export default { this.$refs.testCaseLoadRelevance.open(); }, nodeChange(node, nodeIds, pNodes) { - this.selectNodeIds = nodeIds; - this.selectParentNodes = pNodes; + this.selectProjectId = node.key; // 切换node后,重置分页数 this.$refs.testPlanLoadCaseList.currentPage = 1; this.$refs.testPlanLoadCaseList.pageSize = 10; @@ -84,6 +84,8 @@ export default { if (this.planId) { this.result = this.$get("/case/node/list/plan/" + this.planId, response => { this.treeNodes = response.data; + // 性能测试与模块无关,过滤项目下模块 + this.treeNodes.map(node => node.children = null); }); } }, diff --git a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue index 7c2adc1752..b099b6095a 100644 --- a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue @@ -30,12 +30,11 @@ :label="$t('commons.name')" show-overflow-tooltip> - - - - - - + + { + this.selectRows = new Set(); + let param = {}; + param.testPlanId = this.planId; + if (this.selectProjectId && this.selectProjectId !== 'root') { + param.projectId = this.selectProjectId; + } + this.$post("/test/plan/load/case/list/" + this.currentPage + "/" + this.pageSize, param, response => { let data = response.data; this.total = data.itemCount; this.tableData = data.listObject; @@ -200,7 +205,19 @@ export default { // // }, handleDeleteBatch() { - + this.$alert(this.$t('test_track.plan_view.confirm_cancel_relevance') + "?", '', { + confirmButtonText: this.$t('commons.confirm'), + callback: (action) => { + if (action === 'confirm') { + let ids = Array.from(this.selectRows).map(row => row.id); + this.result = this.$post('/test/plan/load/case/batch/delete', ids, () => { + this.selectRows.clear(); + this.initTable(); + this.$success(this.$t('test_track.cancel_relevance_success')); + }); + } + } + }) }, handleRunBatch() { @@ -216,7 +233,7 @@ export default { }) }, handleDelete(loadCase) { - this.$get('/test/plan/load/case/delete/' + loadCase.id, () => { + this.result = this.$get('/test/plan/load/case/delete/' + loadCase.id, () => { this.$success(this.$t('test_track.cancel_relevance_success')); this.$emit('refresh'); this.initTable(); diff --git a/frontend/src/common/css/main.css b/frontend/src/common/css/main.css index c14a241985..4b3a23ab1e 100644 --- a/frontend/src/common/css/main.css +++ b/frontend/src/common/css/main.css @@ -161,7 +161,7 @@ html,body { overflow: visible; } -.ms-select-all .el-icon-arrow-down { +.ms-select-all th:nth-child(2) .el-icon-arrow-down { position: absolute; display: inline-block; top: -7px; diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index b4689bdc94..51ea943bd3 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -1089,6 +1089,7 @@ export default { plan_status_prepare: "Not started", plan_status_running: "Starting", plan_status_completed: "Completed", + plan_status_trash: "Trashed", planned_start_time: "Scheduled Start Time", planned_end_time: "Scheduled End Time", actual_start_time: "Actual Start Time", diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 2f5777bb35..1efd1b99f4 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -1090,6 +1090,7 @@ export default { plan_status_prepare: "未开始", plan_status_running: "进行中", plan_status_completed: "已完成", + plan_status_trash: "废弃", planned_start_time: "计划开始", planned_end_time: "计划结束", actual_start_time: "实际开始", diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 5fe40cc555..11ed3503f5 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -1090,6 +1090,7 @@ export default { plan_status_prepare: "未開始", plan_status_running: "進行中", plan_status_completed: "已完成", + plan_status_trash: "廢棄", planned_start_time: "計劃開始", planned_end_time: "計劃結束", actual_start_time: "實際開始",