feat: 接口定义和场景支持批量复制

This commit is contained in:
chenjianxing 2021-12-29 14:57:19 +08:00 committed by fit2-zhao
parent ec267cf8c9
commit 2c65f7110b
10 changed files with 119 additions and 100 deletions

View File

@ -247,6 +247,13 @@ public class ApiAutomationController {
apiAutomationService.bathEdit(request);
}
@PostMapping("/batch/copy")
@RequiresPermissions(value = {PermissionConstants.PROJECT_API_SCENARIO_READ_CREATE, PermissionConstants.PROJECT_API_SCENARIO_READ_COPY}, logical = Logical.OR)
@MsAuditLog(module = "api_automation", type = OperLogConstants.BATCH_ADD, beforeEvent = "#msClass.getLogDetails(#request.ids)", content = "#msClass.getLogDetails(#request.ids)", msClass = ApiAutomationService.class)
public void batchCopy(@RequestBody ApiScenarioBatchRequest request) {
apiAutomationService.batchCopy(request);
}
@PostMapping("/batch/update/env")
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_EDIT)
@MsAuditLog(module = "api_automation", type = OperLogConstants.BATCH_UPDATE, beforeEvent = "#msClass.getLogDetails(#request.ids)", content = "#msClass.getLogDetails(#request.ids)", msClass = ApiAutomationService.class)
@ -296,13 +303,6 @@ public class ApiAutomationController {
return apiAutomationService.batchGenPerformanceTestJmx(request);
}
@PostMapping("/batchCopy")
public BatchOperaResponse batchCopy(@RequestBody ApiScenarioBatchRequest request) {
BatchOperaResponse response = apiAutomationService.batchCopy(request);
return response;
}
@PostMapping("/file/download")
public ResponseEntity<byte[]> download(@RequestBody FileOperationRequest fileOperationRequest) {
byte[] bytes = apiAutomationService.loadFileAsBytes(fileOperationRequest);

View File

@ -280,6 +280,13 @@ public class ApiDefinitionController {
apiDefinitionService.editApiByParam(request);
}
@PostMapping("/batch/copy")
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_COPY_API)
@MsAuditLog(module = "api_definition", type = OperLogConstants.BATCH_UPDATE, beforeEvent = "#msClass.getLogDetails(#request)", content = "#msClass.getLogDetails(#request)", msClass = ApiDefinitionService.class)
public void batchCopy(@RequestBody ApiBatchRequest request) {
apiDefinitionService.batchCopy(request);
}
@PostMapping("/relevance")
@MsAuditLog(module = "track_test_plan", type = OperLogConstants.ASSOCIATE_CASE, content = "#msClass.getLogDetails(#request)", msClass = ApiDefinitionService.class)
public void testPlanRelevance(@RequestBody ApiCaseRelevanceRequest request) {

View File

@ -1748,65 +1748,35 @@ public class ApiAutomationService {
}
}
public BatchOperaResponse batchCopy(ApiScenarioBatchRequest batchRequest) {
public void batchCopy(ApiScenarioBatchRequest request) {
ServiceUtils.getSelectAllIds(batchRequest, batchRequest.getCondition(),
ServiceUtils.getSelectAllIds(request, request.getCondition(),
(query) -> extApiScenarioMapper.selectIdsByQuery(query));
List<ApiScenarioWithBLOBs> apiScenarioList = extApiScenarioMapper.selectIds(batchRequest.getIds());
StringBuffer stringBuffer = new StringBuffer();
for (ApiScenarioWithBLOBs apiModel : apiScenarioList) {
long time = System.currentTimeMillis();
ApiScenarioWithBLOBs newModel = apiModel;
newModel.setId(UUID.randomUUID().toString());
newModel.setName("copy_" + apiModel.getName());
newModel.setCreateTime(time);
newModel.setUpdateTime(time);
newModel.setNum(getNextNum(newModel.getProjectId()));
List<String> ids = request.getIds();
if (CollectionUtils.isEmpty(ids)) return;
List<ApiScenarioWithBLOBs> apiScenarioList = extApiScenarioMapper.selectIds(ids);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiScenarioMapper mapper = sqlSession.getMapper(ApiScenarioMapper.class);
Long nextOrder = ServiceUtils.getNextOrder(request.getProjectId(), extApiScenarioMapper::getLastOrder);
int nextNum = getNextNum(request.getProjectId());
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andNameEqualTo(newModel.getName()).
andProjectIdEqualTo(newModel.getProjectId()).andStatusNotEqualTo("Trash").andIdNotEqualTo(newModel.getId());
if (apiScenarioMapper.countByExample(example) > 0) {
stringBuffer.append(newModel.getName() + ";");
continue;
} else {
boolean insertFlag = true;
if (StringUtils.isNotBlank(newModel.getCustomNum())) {
insertFlag = false;
String projectId = newModel.getProjectId();
Project project = projectMapper.selectByPrimaryKey(projectId);
if (project != null) {
Boolean customNum = project.getScenarioCustomNum();
// 未开启自定义ID
if (!customNum) {
insertFlag = true;
newModel.setCustomNum(null);
} else {
boolean isCustomNumExist = true;
try {
isCustomNumExist = this.isCustomNumExist(newModel);
} catch (Exception e) {
}
insertFlag = !isCustomNumExist;
}
}
}
if (insertFlag) {
apiScenarioMapper.insert(newModel);
apiScenarioReferenceIdService.saveByApiScenario(newModel);
}
try {
for (int i = 0; i < apiScenarioList.size(); i++) {
ApiScenarioWithBLOBs api = apiScenarioList.get(i);
api.setId(UUID.randomUUID().toString());
api.setName(ServiceUtils.getCopyName(api.getName()));
api.setApiScenarioModuleId(request.getApiScenarioModuleId());
api.setModulePath(request.getModulePath());
api.setOrder(nextOrder += ServiceUtils.ORDER_STEP);
api.setNum(nextNum++);
mapper.insert(api);
if (i % 50 == 0)
sqlSession.flushStatements();
}
sqlSession.flushStatements();
} finally {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
BatchOperaResponse result = new BatchOperaResponse();
if (stringBuffer.length() == 0) {
result.result = true;
} else {
result.result = false;
result.errorMsg = stringBuffer.substring(0, stringBuffer.length() - 1);
}
return result;
}
public DeleteCheckResult checkBeforeDelete(ApiScenarioBatchRequest request) {

View File

@ -1782,4 +1782,41 @@ public class ApiDefinitionService {
example.createCriteria().andRefIdEqualTo(refId).andVersionIdEqualTo(version);
apiDefinitionMapper.deleteByExample(example);
}
public List<ApiDefinitionWithBLOBs> getByIds(List<String> ids) {
ApiDefinitionExample example = new ApiDefinitionExample();
example.createCriteria().andIdIn(ids);
return apiDefinitionMapper.selectByExampleWithBLOBs(example);
}
public void batchCopy(ApiBatchRequest request) {
ServiceUtils.getSelectAllIds(request, request.getCondition(),
(query) -> extApiDefinitionMapper.selectIds(query));
List<String> ids = request.getIds();
if (CollectionUtils.isEmpty(ids)) return;
List<ApiDefinitionWithBLOBs> apis = getByIds(ids);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiDefinitionMapper mapper = sqlSession.getMapper(ApiDefinitionMapper.class);
Long nextOrder = ServiceUtils.getNextOrder(request.getProjectId(), extApiDefinitionMapper::getLastOrder);
int nextNum = getNextNum(request.getProjectId());
try {
for (int i = 0; i < apis.size(); i++) {
ApiDefinitionWithBLOBs api = apis.get(i);
api.setId(UUID.randomUUID().toString());
api.setName(ServiceUtils.getCopyName(api.getName()));
api.setModuleId(request.getModuleId());
api.setModulePath(request.getModulePath());
api.setOrder(nextOrder += ServiceUtils.ORDER_STEP);
api.setNum(nextNum++);
mapper.insert(api);
if (i % 50 == 0)
sqlSession.flushStatements();
}
sqlSession.flushStatements();
} finally {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
}

View File

@ -16,10 +16,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionUtils;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
@ -239,4 +236,8 @@ public class ServiceUtils {
SqlSessionFactory sqlSessionFactory = CommonBeanFactory.getBean(SqlSessionFactory.class);
return sqlSessionFactory.openSession(ExecutorType.BATCH);
}
public static String getCopyName(String name) {
return "copy_" + name + "_" + UUID.randomUUID().toString().substring(0, 4);
}
}

View File

@ -314,10 +314,8 @@ public class TestCaseController {
}
@PostMapping("/batch/copy")
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_CASE_READ_EDIT)
@MsAuditLog(module = "track_test_case", type = OperLogConstants.BATCH_UPDATE, beforeEvent = "#msClass.getLogDetails(#request.ids)", content = "#msClass.getLogDetails(#request.ids)", msClass = TestCaseService.class)
@SendNotice(taskType = NoticeConstants.TaskType.TRACK_TEST_CASE_TASK, target = "#targetClass.findByBatchRequest(#request)", targetClass = TestCaseService.class,
event = NoticeConstants.Event.CREATE, mailTemplate = "track/TestCaseUpdate", subject = "测试用例通知")
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_CASE_READ_COPY)
@MsAuditLog(module = "track_test_case", type = OperLogConstants.BATCH_ADD, beforeEvent = "#msClass.getLogDetails(#request.ids)", content = "#msClass.getLogDetails(#request.ids)", msClass = TestCaseService.class)
public void copyTestCaseBath(@RequestBody TestCaseBatchRequest request) {
testCaseService.copyTestCaseBath(request);
}

View File

@ -2194,14 +2194,18 @@ public class TestCaseService {
TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class);
Long nextOrder = ServiceUtils.getNextOrder(request.getProjectId(), extTestCaseMapper::getLastOrder);
int nextNum = getNextNum(request.getProjectId());
try {
for (int i = 0; i < testCases.size(); i++) {
TestCaseWithBLOBs testCase = testCases.get(i);
testCase.setId(UUID.randomUUID().toString());
testCase.setName(testCase.getName() + "_" + testCase.getId().substring(0, 5));
testCase.setName(ServiceUtils.getCopyName(testCase.getName()));
testCase.setNodeId(request.getNodeId());
testCase.setNodePath(request.getNodePath());
testCase.setOrder(nextOrder += ServiceUtils.ORDER_STEP);
testCase.setCustomNum(String.valueOf(nextNum));
testCase.setNum(nextNum++);
mapper.insert(testCase);
if (i % 50 == 0)
sqlSession.flushStatements();

View File

@ -403,6 +403,7 @@ export default {
components: API_SCENARIO_CONFIGS
},
scenarioId: "",
isMoveBatch: true,
currentScenario: {},
schedule: {},
tableData: [],
@ -489,16 +490,16 @@ export default {
handleClick: this.handleBatchEdit,
permissions: ['PROJECT_API_SCENARIO:READ+EDIT']
},
{
name: this.$t('api_test.batch_copy'),
handleClick: this.batchCopy,
permissions: ['PROJECT_API_SCENARIO:READ+BATCH_COPY']
},
{
name: this.$t('test_track.case.batch_move_case'),
handleClick: this.handleBatchMove,
permissions: ['PROJECT_API_SCENARIO:READ+MOVE_BATCH']
},
{
name: this.$t('api_test.batch_copy'),
handleClick: this.handleBatchCopy,
permissions: ['PROJECT_API_SCENARIO:READ+BATCH_COPY']
},
{
name: this.$t('api_test.definition.request.batch_delete'),
handleClick: this.handleDeleteBatch,
@ -759,13 +760,21 @@ export default {
}
},
handleBatchMove() {
this.isMoveBatch = true;
this.$refs.testBatchMove.open(this.moduleTree, [], this.moduleOptions);
},
handleBatchCopy() {
this.isMoveBatch = false;
this.$refs.testBatchMove.open(this.moduleTree, this.$refs.scenarioTable.selectIds, this.moduleOptions);
},
moveSave(param) {
this.buildBatchParam(param);
param.apiScenarioModuleId = param.nodeId;
param.modulePath = param.nodePath;
this.$post('/api/automation/batch/edit', param, () => {
let url = '/api/automation/batch/edit';
if (!this.isMoveBatch)
url = '/api/automation/batch/copy';
this.$post(url, param, () => {
this.$success(this.$t('commons.save_success'));
this.$refs.testBatchMove.close();
this.search();
@ -1228,28 +1237,6 @@ export default {
}
});
},
batchCopy() {
this.$alert(this.$t('api_test.definition.request.batch_copy_confirm') + " ", '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
this.infoDb = false;
let param = {};
this.buildBatchParam(param);
this.$post('/api/automation/batchCopy', param, response => {
let copyResult = response.data;
if (copyResult.result) {
this.$success(this.$t('api_test.definition.request.batch_copy_end'));
} else {
this.$error(this.$t('commons.already_exists') + ":" + copyResult.errorMsg);
}
this.search();
});
}
}
});
},
stop(row) {
let url = "/api/automation/stop/" + this.reportId;
this.$get(url, () => {

View File

@ -289,6 +289,7 @@ export default {
enableOrderDrag: true,
selectDataRange: "all",
graphData: [],
isMoveBatch: true,
deletePath: "/test/case/delete",
buttons: [
{
@ -306,6 +307,11 @@ export default {
handleClick: this.handleBatchMove,
permissions: ['PROJECT_API_DEFINITION:READ+EDIT_API']
},
{
name: this.$t('api_test.batch_copy'),
handleClick: this.handleBatchCopy,
permissions: ['PROJECT_API_DEFINITION:READ+CREATE_API']
},
{
name: this.$t('test_track.case.generate_dependencies'),
isXPack: true,
@ -552,8 +558,13 @@ export default {
});
},
handleBatchMove() {
this.isMoveBatch = true;
this.$refs.testCaseBatchMove.open(this.moduleTree, [], this.moduleOptions);
},
handleBatchCopy() {
this.isMoveBatch = false;
this.$refs.testCaseBatchMove.open(this.moduleTree, this.$refs.table.selectIds, this.moduleOptions);
},
closeCaseModel() {
//
if (this.$refs.caseList) {
@ -771,7 +782,10 @@ export default {
param.projectId = this.projectId;
param.condition = this.condition;
param.moduleId = param.nodeId;
this.$post('/api/definition/batch/editByParams', param, () => {
let url = '/api/definition/batch/editByParams';
if (!this.isMoveBatch)
url = '/api/definition/batch/copy';
this.$post(url, param, () => {
this.$success(this.$t('commons.save_success'));
this.$refs.testCaseBatchMove.close();
this.initTable();

View File

@ -346,7 +346,7 @@ export default {
{
name: this.$t('api_test.batch_copy'),
handleClick: this.handleBatchCopy,
permissions: ['PROJECT_TRACK_CASE:READ+EDIT']
permissions: ['PROJECT_TRACK_CASE:READ+COPY']
},
{
name: this.$t('test_track.case.batch_delete_case'),
@ -1079,6 +1079,7 @@ export default {
let url = '/test/case/batch/edit';
if (!this.isMoveBatch)
url = '/test/case/batch/copy';
param.projectId = this.projectId;
this.page.result = this.$post(url, param, () => {
this.$success(this.$t('commons.save_success'));
this.$refs.testBatchMove.close();