feat(接口测试): 接口列表支持批量复制指定版本的case/mock数据
--story=1010822 --user=宋天阳 接口列表支持批量复制指定版本的case/mock数据 https://www.tapd.cn/55049933/s/1322714
This commit is contained in:
parent
693dc9bbd0
commit
48e52d6d3a
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.api.dto.definition;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class BatchDataCopyRequest {
|
||||
private List<String> ids;
|
||||
private boolean copyCase;
|
||||
private boolean copyMock;
|
||||
private String versionId;
|
||||
|
||||
private ApiDefinitionRequest condition;
|
||||
}
|
|
@ -139,6 +139,13 @@ public class ApiDefinitionController {
|
|||
apiDefinitionService.deleteByParams(request);
|
||||
}
|
||||
|
||||
@PostMapping("/copy/by/version")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_EDIT_API)
|
||||
@MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.ids)", title = "#request.name", content = "#msClass.getLogDetails(#request.ids)", msClass = ApiDefinitionService.class)
|
||||
public void copyByVersion(@RequestBody BatchDataCopyRequest request) {
|
||||
apiDefinitionService.copyCaseOrMockByVersion(request);
|
||||
}
|
||||
|
||||
@PostMapping("/move-gc")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_DELETE_API)
|
||||
@MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.GC, beforeEvent = "#msClass.getLogDetails(#ids)", msClass = ApiDefinitionService.class)
|
||||
|
|
|
@ -87,6 +87,12 @@ public class MockConfigService {
|
|||
return extMockExpectConfigMapper.selectByApiId(apiId);
|
||||
}
|
||||
|
||||
public List<MockExpectConfig> selectSimpleMockExpectConfigByMockConfigId(String mockConfigId) {
|
||||
MockExpectConfigExample example = new MockExpectConfigExample();
|
||||
example.createCriteria().andMockConfigIdEqualTo(mockConfigId);
|
||||
return mockExpectConfigMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public List<MockConfigImportDTO> selectMockExpectConfigByApiIdIn(List<String> apiIds) {
|
||||
if (CollectionUtils.isNotEmpty(apiIds)) {
|
||||
List<MockConfigImportDTO> returnDTO = new ArrayList<>();
|
||||
|
@ -263,15 +269,22 @@ public class MockConfigService {
|
|||
return mockExpectConfigMapper.selectByPrimaryKey(model.getId());
|
||||
}
|
||||
|
||||
private String getMockExpectId(String mockConfigId) {
|
||||
List<String> savedExpectNumber = extMockExpectConfigMapper.selectExlectNumByMockConfigId(mockConfigId);
|
||||
public String getMockExpectId(String mockConfigId) {
|
||||
List<String> savedExpectNumber = this.selectExpectNumberByConfigId(mockConfigId);
|
||||
String apiNum = extMockExpectConfigMapper.selectApiNumberByMockConfigId(mockConfigId);
|
||||
return this.getMockExpectId(apiNum, savedExpectNumber);
|
||||
}
|
||||
|
||||
public List<String> selectExpectNumberByConfigId(String mockConfigId) {
|
||||
return extMockExpectConfigMapper.selectExlectNumByMockConfigId(mockConfigId);
|
||||
}
|
||||
|
||||
public String getMockExpectId(String apiNum, List<String> savedExpectNumber) {
|
||||
if (StringUtils.isEmpty(apiNum)) {
|
||||
apiNum = StringUtils.EMPTY;
|
||||
} else {
|
||||
apiNum = apiNum + "_";
|
||||
}
|
||||
|
||||
int index = 1;
|
||||
for (String expectNum : savedExpectNumber) {
|
||||
if (StringUtils.startsWith(expectNum, apiNum)) {
|
||||
|
@ -1153,7 +1166,7 @@ public class MockConfigService {
|
|||
}
|
||||
|
||||
|
||||
private MockConfig selectMockConfigByApiId(String apiId) {
|
||||
public MockConfig selectMockConfigByApiId(String apiId) {
|
||||
MockConfigExample example = new MockConfigExample();
|
||||
example.createCriteria().andApiIdEqualTo(apiId);
|
||||
List<MockConfig> mockConfigList = this.mockConfigMapper.selectByExample(example);
|
||||
|
|
|
@ -50,6 +50,7 @@ import io.metersphere.service.ext.ExtApiScheduleService;
|
|||
import io.metersphere.service.ext.ExtFileAssociationService;
|
||||
import io.metersphere.service.plan.TestPlanApiCaseService;
|
||||
import io.metersphere.service.scenario.ApiScenarioService;
|
||||
import io.metersphere.utils.BatchProcessingUtil;
|
||||
import io.metersphere.xpack.api.service.ApiCaseBatchSyncService;
|
||||
import io.metersphere.xpack.api.service.ApiDefinitionSyncService;
|
||||
import io.metersphere.xpack.quota.service.QuotaService;
|
||||
|
@ -133,6 +134,9 @@ public class ApiDefinitionService {
|
|||
@Lazy
|
||||
@Resource
|
||||
private ApiModuleService apiModuleService;
|
||||
@Lazy
|
||||
@Resource
|
||||
private MockConfigService mockConfigService;
|
||||
@Resource
|
||||
private BaseEnvironmentService apiTestEnvironmentService;
|
||||
@Lazy
|
||||
|
@ -2143,4 +2147,217 @@ public class ApiDefinitionService {
|
|||
allSourceIdCount = apiExecutionInfoService.countSourceIdByProjectIdIsNull();
|
||||
}
|
||||
}
|
||||
|
||||
public void copyCaseOrMockByVersion(BatchDataCopyRequest request) {
|
||||
if (!request.isCopyCase() && !request.isCopyMock()) {
|
||||
return;
|
||||
}
|
||||
if (request.getCondition() == null) {
|
||||
return;
|
||||
}
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(), (query) -> extApiDefinitionMapper.selectIds(query));
|
||||
// ServiceUtils.getSelectAllIds(request, request.getCondition(), (query) -> extApiDefinitionMapper.selectIds(query));
|
||||
|
||||
if (StringUtils.isBlank(request.getVersionId()) || CollectionUtils.isEmpty(request.getCondition().getIds())) {
|
||||
MSException.throwException(Translator.get("invalid_parameter"));
|
||||
}
|
||||
request.setIds(request.getCondition().getIds());
|
||||
|
||||
//函数是批量操作,可能会出现数据太多导致的sql过长错误,采用批量处理
|
||||
BatchProcessingUtil.batchProcessingByDataCopy(request, this::batchCopyCaseOrMockByVersion);
|
||||
|
||||
}
|
||||
|
||||
public void batchCopyCaseOrMockByVersion(BatchDataCopyRequest request) {
|
||||
|
||||
if (sqlSessionFactory != null && CollectionUtils.isNotEmpty(request.getIds())) {
|
||||
Map<String, ApiDefinition> refIdMap = new HashMap<>();
|
||||
List<ApiDefinition> apiDefinitionList = this.selectByIds(request.getIds());
|
||||
apiDefinitionList.forEach(item -> {
|
||||
//过滤到自身的引用
|
||||
if (!StringUtils.equals(item.getVersionId(), request.getVersionId())) {
|
||||
refIdMap.put(item.getRefId(), item);
|
||||
}
|
||||
});
|
||||
if (MapUtils.isNotEmpty(refIdMap)) {
|
||||
ApiDefinitionExample apiExample = new ApiDefinitionExample();
|
||||
apiExample.createCriteria().andStatusNotEqualTo(ApiTestDataStatus.TRASH.getValue()).andRefIdIn(new ArrayList<>(refIdMap.keySet())).andVersionIdEqualTo(request.getVersionId());
|
||||
List<ApiDefinition> versionApiList = apiDefinitionMapper.selectByExample(apiExample);
|
||||
Map<String, String> sourceApiIdRefIdMap = new HashMap<>();
|
||||
versionApiList.forEach(item -> sourceApiIdRefIdMap.put(item.getId(), item.getRefId()));
|
||||
if (MapUtils.isEmpty(sourceApiIdRefIdMap)) {
|
||||
return;
|
||||
}
|
||||
SqlSession batchSqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
if (request.isCopyCase()) {
|
||||
this.copyCaseByVersion(request.getIds(), sourceApiIdRefIdMap, refIdMap, batchSqlSession);
|
||||
}
|
||||
if (request.isCopyMock()) {
|
||||
this.copyMockByVersion(sourceApiIdRefIdMap, refIdMap, batchSqlSession);
|
||||
}
|
||||
batchSqlSession.flushStatements();
|
||||
if (sqlSessionFactory != null) {
|
||||
SqlSessionUtils.closeSqlSession(batchSqlSession, sqlSessionFactory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyMockByVersion(Map<String, String> sourceApiIdRefIdMap, Map<String, ApiDefinition> refIdMap, SqlSession batchSqlSession) {
|
||||
long timeStamp = System.currentTimeMillis();
|
||||
MockConfigExample mockConfigExample = new MockConfigExample();
|
||||
mockConfigExample.createCriteria().andApiIdIn(new ArrayList<>(sourceApiIdRefIdMap.keySet()));
|
||||
List<MockConfig> mockConfigList = mockConfigMapper.selectByExample(mockConfigExample);
|
||||
if (CollectionUtils.isNotEmpty(mockConfigList)) {
|
||||
List<String> mockIdList = mockConfigList.stream().map(MockConfig::getId).collect(Collectors.toList());
|
||||
MockExpectConfigExample mockExpectConfigExample = new MockExpectConfigExample();
|
||||
mockExpectConfigExample.createCriteria().andMockConfigIdIn(mockIdList);
|
||||
List<MockExpectConfigWithBLOBs> mockExpectConfigWithBLOBsList = mockExpectConfigMapper.selectByExampleWithBLOBs(mockExpectConfigExample);
|
||||
Map<String, List<MockExpectConfigWithBLOBs>> mockConfigIdExpectMap = mockExpectConfigWithBLOBsList.stream().collect(Collectors.groupingBy(MockExpectConfigWithBLOBs::getMockConfigId));
|
||||
|
||||
List<MockConfig> saveMockList = new ArrayList<>();
|
||||
|
||||
List<MockExpectConfigWithBLOBs> saveMockExpectList = new ArrayList<>();
|
||||
List<MockExpectConfigWithBLOBs> updateMockExpectList = new ArrayList<>();
|
||||
|
||||
mockConfigList.forEach(item -> {
|
||||
String oldApiId = item.getApiId();
|
||||
String refId = sourceApiIdRefIdMap.get(oldApiId);
|
||||
if (StringUtils.isNotBlank(refId)) {
|
||||
ApiDefinition api = refIdMap.get(refId);
|
||||
if (api != null) {
|
||||
MockConfig baseMockConfig = mockConfigService.selectMockConfigByApiId(api.getId());
|
||||
String mockConfigId = UUID.randomUUID().toString();
|
||||
|
||||
Map<String, MockExpectConfig> oldMockExpectConfig = new HashMap<>();
|
||||
//已经存储的mock期望编号
|
||||
List<String> saveExpectNumList = new ArrayList<>();
|
||||
|
||||
if (baseMockConfig == null) {
|
||||
MockConfig mockConfig = new MockConfig();
|
||||
BeanUtils.copyBean(mockConfig, item);
|
||||
mockConfig.setApiId(api.getId());
|
||||
mockConfig.setId(mockConfigId);
|
||||
mockConfig.setCreateTime(timeStamp);
|
||||
mockConfig.setUpdateTime(timeStamp);
|
||||
saveMockList.add(mockConfig);
|
||||
} else {
|
||||
mockConfigId = baseMockConfig.getId();
|
||||
saveExpectNumList = mockConfigService.selectExpectNumberByConfigId(mockConfigId);
|
||||
List<MockExpectConfig> oldMockExpectList = mockConfigService.selectSimpleMockExpectConfigByMockConfigId(mockConfigId);
|
||||
oldMockExpectList.forEach(mockExpectConfig -> {
|
||||
oldMockExpectConfig.put(StringUtils.trim(mockExpectConfig.getName()), mockExpectConfig);
|
||||
});
|
||||
}
|
||||
List<MockExpectConfigWithBLOBs> mockExpectConfigList = mockConfigIdExpectMap.get(item.getId());
|
||||
if (CollectionUtils.isNotEmpty(mockExpectConfigList)) {
|
||||
String finalMockConfigId = mockConfigId;
|
||||
List<String> finalSaveExpectNumList = saveExpectNumList;
|
||||
mockExpectConfigList.forEach(mockExpectConfigWithBLOBs -> {
|
||||
MockExpectConfig oldExpect = oldMockExpectConfig.get(StringUtils.trim(mockExpectConfigWithBLOBs.getName()));
|
||||
MockExpectConfigWithBLOBs expectConfigWithBLOBs = new MockExpectConfigWithBLOBs();
|
||||
BeanUtils.copyBean(expectConfigWithBLOBs, mockExpectConfigWithBLOBs);
|
||||
if (oldExpect == null) {
|
||||
String newMockExpectNum = mockConfigService.getMockExpectId(String.valueOf(api.getNum()), finalSaveExpectNumList);
|
||||
finalSaveExpectNumList.add(newMockExpectNum);
|
||||
|
||||
expectConfigWithBLOBs.setId(UUID.randomUUID().toString());
|
||||
expectConfigWithBLOBs.setExpectNum(newMockExpectNum);
|
||||
expectConfigWithBLOBs.setCreateTime(timeStamp);
|
||||
expectConfigWithBLOBs.setUpdateTime(timeStamp);
|
||||
expectConfigWithBLOBs.setMockConfigId(finalMockConfigId);
|
||||
saveMockExpectList.add(expectConfigWithBLOBs);
|
||||
} else {
|
||||
expectConfigWithBLOBs.setId(oldExpect.getId());
|
||||
expectConfigWithBLOBs.setCreateTime(oldExpect.getCreateTime());
|
||||
expectConfigWithBLOBs.setUpdateTime(timeStamp);
|
||||
updateMockExpectList.add(expectConfigWithBLOBs);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (CollectionUtils.isNotEmpty(saveMockList)) {
|
||||
MockConfigMapper mockConfigBatchMapper = batchSqlSession.getMapper(MockConfigMapper.class);
|
||||
saveMockList.forEach(mockConfigBatchMapper::insert);
|
||||
}
|
||||
MockExpectConfigMapper mockExpectConfigBatchMapper = batchSqlSession.getMapper(MockExpectConfigMapper.class);
|
||||
if (CollectionUtils.isNotEmpty(saveMockExpectList)) {
|
||||
saveMockExpectList.forEach(mockExpectConfigBatchMapper::insert);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateMockExpectList)) {
|
||||
updateMockExpectList.forEach(mockExpectConfigBatchMapper::updateByPrimaryKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyCaseByVersion(List<String> chooseApiIdList, Map<String, String> sourceApiIdRefIdMap, Map<String, ApiDefinition> refIdMap, SqlSession batchSqlSession) {
|
||||
long timeStamp = System.currentTimeMillis();
|
||||
List<ApiTestCaseWithBLOBs> sourceApiCaseList = apiTestCaseService.selectCasesBydApiIds(new ArrayList<>(sourceApiIdRefIdMap.keySet()));
|
||||
List<ApiTestCase> caseInChooseApi = apiTestCaseService.selectSimpleCasesBydApiIds(chooseApiIdList);
|
||||
Map<String, Map<String, ApiTestCase>> apiIdOldCaseMap = new HashMap<>();
|
||||
caseInChooseApi.forEach(item -> {
|
||||
String caseName = StringUtils.trim(item.getName());
|
||||
if (StringUtils.isNotBlank(caseName)) {
|
||||
if (apiIdOldCaseMap.containsKey(item.getApiDefinitionId())) {
|
||||
apiIdOldCaseMap.get(item.getApiDefinitionId()).put(caseName, item);
|
||||
} else {
|
||||
apiIdOldCaseMap.put(item.getApiDefinitionId(), new HashMap<>() {{
|
||||
this.put(caseName, item);
|
||||
}});
|
||||
}
|
||||
}
|
||||
});
|
||||
List<ApiTestCaseWithBLOBs> saveCaseList = new ArrayList<>();
|
||||
List<ApiTestCaseWithBLOBs> updateCaseList = new ArrayList<>();
|
||||
Map<String, Integer> lastCaseNumMap = new LinkedHashMap<>();
|
||||
sourceApiCaseList.forEach(item -> {
|
||||
String oldApiId = item.getApiDefinitionId();
|
||||
String refId = sourceApiIdRefIdMap.get(oldApiId);
|
||||
if (StringUtils.isNotBlank(refId)) {
|
||||
ApiDefinition api = refIdMap.get(refId);
|
||||
if (api != null) {
|
||||
//通过用例名称检查是否需要覆盖
|
||||
ApiTestCase oldCase = null;
|
||||
if (apiIdOldCaseMap.containsKey(api.getId())) {
|
||||
oldCase = apiIdOldCaseMap.get(api.getId()).get(StringUtils.trim(item.getName()));
|
||||
}
|
||||
ApiTestCaseWithBLOBs newCase = new ApiTestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(newCase, item);
|
||||
newCase.setApiDefinitionId(api.getId());
|
||||
newCase.setVersionId(api.getVersionId());
|
||||
if (oldCase == null) {
|
||||
int lastCaseNum = 0;
|
||||
if (lastCaseNumMap.containsKey(api.getId())) {
|
||||
lastCaseNum = lastCaseNumMap.get(api.getId());
|
||||
} else {
|
||||
lastCaseNum = apiTestCaseService.getNextNum(api.getId());
|
||||
}
|
||||
int caseNum = apiTestCaseService.getNextNum(lastCaseNum);
|
||||
newCase.setNum(caseNum);
|
||||
newCase.setId(UUID.randomUUID().toString());
|
||||
newCase.setCreateTime(timeStamp);
|
||||
newCase.setUpdateTime(timeStamp);
|
||||
|
||||
lastCaseNumMap.put(api.getId(), caseNum);
|
||||
saveCaseList.add(newCase);
|
||||
} else {
|
||||
newCase.setId(oldCase.getId());
|
||||
newCase.setNum(oldCase.getNum());
|
||||
newCase.setCreateTime(oldCase.getCreateTime());
|
||||
newCase.setUpdateTime(timeStamp);
|
||||
updateCaseList.add(newCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ApiTestCaseMapper apiTestCaseBatchMapper = batchSqlSession.getMapper(ApiTestCaseMapper.class);
|
||||
if (CollectionUtils.isNotEmpty(saveCaseList)) {
|
||||
saveCaseList.forEach(apiTestCaseBatchMapper::insert);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateCaseList)) {
|
||||
updateCaseList.forEach(apiTestCaseBatchMapper::updateByPrimaryKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -480,15 +480,19 @@ public class ApiTestCaseService {
|
|||
|
||||
public int getNextNum(String definitionId) {
|
||||
ApiTestCase apiTestCase = extApiTestCaseMapper.getNextNum(definitionId);
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(definitionId);
|
||||
if (apiTestCase == null) {
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(definitionId);
|
||||
int n = apiDefinitionWithBLOBs.getNum();
|
||||
return n * 1000 + 1;
|
||||
} else {
|
||||
return Optional.of(apiTestCase.getNum() + 1).orElse(apiDefinitionWithBLOBs.getNum() * 1000 + 1);
|
||||
return this.getNextNum(apiTestCase.getNum());
|
||||
}
|
||||
}
|
||||
|
||||
public int getNextNum(Integer lastApiCaseNum) {
|
||||
return Optional.of(lastApiCaseNum + 1).orElse(lastApiCaseNum * 1000 + 1);
|
||||
}
|
||||
|
||||
public int getNextNum(String definitionId, Integer definitionNum, String projectId) {
|
||||
ApiTestCase apiTestCase = extApiTestCaseMapper.getNextNum(definitionId);
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(definitionId);
|
||||
|
@ -607,6 +611,12 @@ public class ApiTestCaseService {
|
|||
return apiTestCaseMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public List<ApiTestCase> selectSimpleCasesBydApiIds(List<String> apiIds) {
|
||||
ApiTestCaseExample example = new ApiTestCaseExample();
|
||||
example.createCriteria().andApiDefinitionIdIn(apiIds).andStatusNotEqualTo("Trash");
|
||||
return apiTestCaseMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public Map<String, String> getRequest(ApiTestCaseRequest request) {
|
||||
List<ApiTestCaseInfo> list = extApiTestCaseMapper.getRequest(request);
|
||||
return list.stream().collect(Collectors.toMap(ApiTestCaseWithBLOBs::getId, ApiTestCaseWithBLOBs::getRequest));
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package io.metersphere.utils;
|
||||
|
||||
import io.metersphere.api.dto.definition.BatchDataCopyRequest;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 批量处理工具
|
||||
*/
|
||||
public class BatchProcessingUtil {
|
||||
|
||||
private static final int BATCH_PROCESS_QUANTITY = 1000;
|
||||
|
||||
public static void batchProcessingByDataCopy(BatchDataCopyRequest paramRequest, Consumer<BatchDataCopyRequest> func) {
|
||||
List<String> paramList = paramRequest.getIds();
|
||||
if (CollectionUtils.isNotEmpty(paramList)) {
|
||||
BatchDataCopyRequest queryRequest = new BatchDataCopyRequest();
|
||||
BeanUtils.copyBean(queryRequest, paramRequest);
|
||||
int unProcessingCount = paramList.size();
|
||||
while (paramList.size() > BATCH_PROCESS_QUANTITY) {
|
||||
List<String> processingList = new ArrayList<>();
|
||||
for (int i = 0; i < BATCH_PROCESS_QUANTITY; i++) {
|
||||
processingList.add(paramList.get(i));
|
||||
}
|
||||
//函数处理
|
||||
queryRequest.setIds(processingList);
|
||||
func.accept(queryRequest);
|
||||
|
||||
paramList.removeAll(processingList);
|
||||
if (paramList.size() == unProcessingCount) {
|
||||
//如果剩余数量没有发生变化,则跳出循环。防止出现死循环的情况
|
||||
break;
|
||||
} else {
|
||||
unProcessingCount = paramList.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(paramList)) {
|
||||
//剩余待处理数据进行处理
|
||||
queryRequest.setIds(paramList);
|
||||
func.accept(queryRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { fileDownload, fileUpload } from '@/api/base-network';
|
||||
import { fileUpload } from '@/api/base-network';
|
||||
import { get, post } from 'metersphere-frontend/src/plugins/request';
|
||||
|
||||
export function getRelationshipCountApi(id) {
|
||||
|
@ -137,6 +137,10 @@ export function removeToGcByParams(params) {
|
|||
return post('/api/definition/move-gc-batch', params);
|
||||
}
|
||||
|
||||
export function copyDataByVersion(params) {
|
||||
return post('/api/definition/copy/by/version', params);
|
||||
}
|
||||
|
||||
export function removeToGcByIds(params) {
|
||||
return post('/api/definition/move-gc', params);
|
||||
}
|
||||
|
|
|
@ -225,6 +225,8 @@
|
|||
:data-count="$refs.table ? $refs.table.selectDataCounts : 0"
|
||||
:typeArr="typeArr"
|
||||
:value-arr="valueArr" />
|
||||
<!--从指定版本复制数据-->
|
||||
<version-selector @handleSave="handleCopyDataFromVersion" ref="versionSelector" />
|
||||
<!--高级搜索-->
|
||||
<ms-table-adv-search-bar :condition.sync="condition" :showLink="false" ref="searchBar" @search="search" />
|
||||
<case-batch-move @refresh="initTable" @moveSave="moveSave" ref="testCaseBatchMove" />
|
||||
|
@ -239,6 +241,7 @@
|
|||
import {
|
||||
batchCopyByParams,
|
||||
batchEditByParams,
|
||||
copyDataByVersion,
|
||||
definitionReduction,
|
||||
delDefinition,
|
||||
delDefinitionByRefId,
|
||||
|
@ -292,6 +295,7 @@ import { getGraphByCondition } from '@/api/graph';
|
|||
import ListItemDeleteConfirm from 'metersphere-frontend/src/components/ListItemDeleteConfirm';
|
||||
import MsSearch from 'metersphere-frontend/src/components/search/MsSearch';
|
||||
import { buildNodePath } from 'metersphere-frontend/src/model/NodeTree';
|
||||
import VersionSelector from '@/business/definition/components/version/VersionSelector';
|
||||
|
||||
export default {
|
||||
name: 'ApiList',
|
||||
|
@ -316,6 +320,7 @@ export default {
|
|||
MsTable,
|
||||
MsTableColumn,
|
||||
MsSearch,
|
||||
VersionSelector,
|
||||
MsApiReportStatus: () => import('../../../automation/report/ApiReportStatus'),
|
||||
MxRelationshipGraphDrawer: () => import('metersphere-frontend/src/components/graph/MxRelationshipGraphDrawer'),
|
||||
},
|
||||
|
@ -357,6 +362,12 @@ export default {
|
|||
handleClick: this.handleBatchCopy,
|
||||
permissions: ['PROJECT_API_DEFINITION:READ+CREATE_API'],
|
||||
},
|
||||
{
|
||||
name: this.$t('api_definition.copy_data_from_other_version'),
|
||||
isXPack: true,
|
||||
handleClick: this.batchCopyDataFromVersion,
|
||||
permissions: ['PROJECT_API_DEFINITION:READ+EDIT_API'],
|
||||
},
|
||||
{
|
||||
name: this.$t('test_track.case.generate_dependencies'),
|
||||
isXPack: true,
|
||||
|
@ -646,6 +657,11 @@ export default {
|
|||
this.isMoveBatch = false;
|
||||
this.$refs.testCaseBatchMove.open(this.moduleTree, this.$refs.table.selectIds, this.moduleOptionsNew);
|
||||
},
|
||||
batchCopyDataFromVersion() {
|
||||
if (this.$refs.versionSelector) {
|
||||
this.$refs.versionSelector.open(this.projectId);
|
||||
}
|
||||
},
|
||||
closeCaseModel() {
|
||||
//关闭案例弹窗
|
||||
if (this.$refs.caseList) {
|
||||
|
@ -849,7 +865,7 @@ export default {
|
|||
this.search();
|
||||
},
|
||||
search() {
|
||||
this.$EventBus.$emit("apiConditionBus", this.condition)
|
||||
this.$EventBus.$emit('apiConditionBus', this.condition);
|
||||
this.changeSelectDataRangeAll();
|
||||
this.initTable();
|
||||
},
|
||||
|
@ -1181,6 +1197,35 @@ export default {
|
|||
return '';
|
||||
}
|
||||
},
|
||||
//从指定版本拷贝数据
|
||||
handleCopyDataFromVersion(selectVersionId, copyCase, copyMock) {
|
||||
let copyParam = {};
|
||||
// let param = {};
|
||||
// if (vueObj.selectRows) {
|
||||
// param.ids = selectIds ? selectIds : Array.from(vueObj.selectRows).map(row => row.id);
|
||||
// } else {
|
||||
// param.ids = selectIds;
|
||||
// }
|
||||
// param.projectId = projectId ? projectId : getCurrentProjectID();
|
||||
// param.condition = vueObj.condition;
|
||||
// return param;
|
||||
|
||||
// copyParam.versionId = selectVersionId;
|
||||
copyParam.copyCase = copyCase;
|
||||
copyParam.copyMock = copyMock;
|
||||
copyParam.versionId = selectVersionId;
|
||||
copyParam.condition = this.condition;
|
||||
copyParam.condition.ids = this.$refs.table.selectIds;
|
||||
copyParam.condition.protocol = this.currentProtocol;
|
||||
|
||||
copyDataByVersion(copyParam).then(() => {
|
||||
this.$success(this.$t('commons.copy_success'));
|
||||
if (this.$refs.versionSelector) {
|
||||
this.$refs.versionSelector.handleClose();
|
||||
}
|
||||
this.initTable();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<template>
|
||||
<ms-edit-dialog
|
||||
:visible.sync="visible"
|
||||
width="300px"
|
||||
:title="$t('commons.delete_all_version')"
|
||||
:with-footer="false"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose">
|
||||
<el-row>
|
||||
<div v-loading="loading">
|
||||
<el-row>
|
||||
<el-select v-model="versionId" size="small" :placeholder="$t('project.version.please_input_version')">
|
||||
<el-option v-for="v in versionData" :key="v.id" :label="v.name" :value="v.id" />
|
||||
</el-select>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 10px">
|
||||
<el-checkbox v-model="selectCase" v-permission="['PROJECT_API_DEFINITION:READ+CREATE_CASE']">{{ $t('commons.api_case') }}</el-checkbox>
|
||||
<el-checkbox v-model="selectMock">{{ $t('commons.mock') }}</el-checkbox>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
<template v-slot:footer>
|
||||
<el-button type="primary" :loading="saving" size="small" @click="save" @keydown.enter.native.prevent>{{
|
||||
$t('commons.save')
|
||||
}}</el-button>
|
||||
</template>
|
||||
</ms-edit-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsEditDialog from '@/business/commons/MsEditDialog';
|
||||
import { getProjectVersions } from '@/api/xpack';
|
||||
export default {
|
||||
name: 'VersionSelector',
|
||||
components: { MsEditDialog },
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
visible: false,
|
||||
saving:false,
|
||||
versionId: '',
|
||||
versionData: [],
|
||||
selectCase: true,
|
||||
selectMock: true,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
tips: String,
|
||||
projectId: String,
|
||||
},
|
||||
methods: {
|
||||
open(projectId) {
|
||||
this.saving = false;
|
||||
this.selectMock = true;
|
||||
this.selectCase = true;
|
||||
this.versionId = '';
|
||||
this.versionData = [];
|
||||
this.visible = true;
|
||||
this.loading = true;
|
||||
|
||||
getProjectVersions(projectId)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
this.versionData = response.data;
|
||||
} else {
|
||||
this.versionData = [];
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleClose() {
|
||||
this.saving = false;
|
||||
this.$emit('handleClose');
|
||||
this.visible = false;
|
||||
},
|
||||
save() {
|
||||
if (!this.versionId || this.versionId === '') {
|
||||
this.$error(this.$t('project.version.please_input_version'));
|
||||
} else {
|
||||
this.saving = true;
|
||||
this.$emit('handleSave', this.versionId,this.selectCase,this.selectMock);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -18,6 +18,7 @@ const message = {
|
|||
type: 'Type',
|
||||
default_value: 'Default value',
|
||||
},
|
||||
copy_data_from_other_version: 'Copy data from other version',
|
||||
body: {
|
||||
json_format_error: 'JSON format error',
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@ const message = {
|
|||
type: '类型',
|
||||
default_value: '默认值',
|
||||
},
|
||||
copy_data_from_other_version: '复制版本数据',
|
||||
body: {
|
||||
json_format_error: 'JSON格式错误',
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@ const message = {
|
|||
type: '類型',
|
||||
default_value: '默認值',
|
||||
},
|
||||
copy_data_from_other_version: '複製版本數據',
|
||||
body: {
|
||||
json_format_error: 'JSON格式錯誤',
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue