refactor(用例评审): 添加监听事件
This commit is contained in:
parent
9fab5ebe34
commit
7fae8fd801
|
@ -1,6 +1,8 @@
|
||||||
package io.metersphere.listener;
|
package io.metersphere.listener;
|
||||||
|
|
||||||
import io.metersphere.api.event.ApiEventSource;
|
import io.metersphere.api.event.ApiEventSource;
|
||||||
|
import io.metersphere.functional.event.CaseEventSource;
|
||||||
|
import io.metersphere.functional.listener.CaseEventListener;
|
||||||
import io.metersphere.plan.listener.ExecEventListener;
|
import io.metersphere.plan.listener.ExecEventListener;
|
||||||
import io.metersphere.sdk.constants.StorageType;
|
import io.metersphere.sdk.constants.StorageType;
|
||||||
import io.metersphere.sdk.file.FileCenter;
|
import io.metersphere.sdk.file.FileCenter;
|
||||||
|
@ -31,22 +33,25 @@ public class AppStartListener implements ApplicationRunner {
|
||||||
// 注册所有监听源
|
// 注册所有监听源
|
||||||
LogUtils.info("初始化接口事件源");
|
LogUtils.info("初始化接口事件源");
|
||||||
ApiEventSource apiEventSource = CommonBeanFactory.getBean(ApiEventSource.class);
|
ApiEventSource apiEventSource = CommonBeanFactory.getBean(ApiEventSource.class);
|
||||||
|
LogUtils.info("初始化用例管理事件源");
|
||||||
|
CaseEventSource caseEventSource = CommonBeanFactory.getBean(CaseEventSource.class);
|
||||||
LogUtils.info("初始化性能测试事件源");
|
LogUtils.info("初始化性能测试事件源");
|
||||||
//LoadEventSource loadEventSource = CommonBeanFactory.getBean(LoadEventSource.class);
|
//LoadEventSource loadEventSource = CommonBeanFactory.getBean(LoadEventSource.class);
|
||||||
//todo: 注册其他事件源
|
//todo: 注册其他事件源
|
||||||
|
|
||||||
|
|
||||||
// 创建监听器对象并注册到多个事件源
|
// 创建监听器对象并注册到多个事件源
|
||||||
ExecEventListener listener = CommonBeanFactory.getBean(ExecEventListener.class);
|
ExecEventListener listener = CommonBeanFactory.getBean(ExecEventListener.class);
|
||||||
apiEventSource.addListener(listener);
|
apiEventSource.addListener(listener);
|
||||||
|
|
||||||
//todo: 注册其他监听器
|
//todo: 注册其他监听器
|
||||||
|
CaseEventListener caseEventListener = CommonBeanFactory.getBean(CaseEventListener.class);
|
||||||
|
caseEventSource.addListener(caseEventListener);
|
||||||
//loadEventSource.addListener(listener);
|
//loadEventSource.addListener(listener);
|
||||||
|
|
||||||
// 触发事件
|
// 触发事件
|
||||||
apiEventSource.fireEvent("API", "Event after removing the listener test.");
|
apiEventSource.fireEvent("API", "Event after removing the listener test.");
|
||||||
//loadEventSource.fireEvent("LOAD","Event after removing the listener.");
|
//loadEventSource.fireEvent("LOAD","Event after removing the listener.");
|
||||||
|
caseEventSource.fireEvent("CASE", "Event after removing the listener test.");
|
||||||
// 加载插件
|
// 加载插件
|
||||||
pluginLoadService.loadPlugins();
|
pluginLoadService.loadPlugins();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,36 @@
|
||||||
package io.metersphere.sdk.listener;
|
package io.metersphere.sdk.listener;
|
||||||
|
|
||||||
public record Event(String module, String message) {
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Event {
|
||||||
|
private String module;
|
||||||
|
private String message;
|
||||||
|
private Map<String, Object> paramMap;
|
||||||
|
|
||||||
|
public Event(String module, String message) {
|
||||||
|
this.module = module;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Event(String module, String message, Map<String, Object> paramMap) {
|
||||||
|
this.module = module;
|
||||||
|
this.message = message;
|
||||||
|
this.paramMap = paramMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String module() {
|
||||||
|
return this.module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String message() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> paramMap() {
|
||||||
|
return this.paramMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package io.metersphere.sdk.listener;
|
package io.metersphere.sdk.listener;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface EventSource {
|
public interface EventSource {
|
||||||
/**
|
/**
|
||||||
* 注册监听
|
* 注册监听
|
||||||
|
@ -10,4 +12,9 @@ public interface EventSource {
|
||||||
* 触发事件
|
* 触发事件
|
||||||
*/
|
*/
|
||||||
void fireEvent(String module, String message);
|
void fireEvent(String module, String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发事件,带有参数
|
||||||
|
*/
|
||||||
|
void fireEvent(String module, String message, Map<String, Object> paramMap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,11 @@ package io.metersphere.api.event;
|
||||||
import io.metersphere.sdk.listener.Event;
|
import io.metersphere.sdk.listener.Event;
|
||||||
import io.metersphere.sdk.listener.EventListener;
|
import io.metersphere.sdk.listener.EventListener;
|
||||||
import io.metersphere.sdk.listener.EventSource;
|
import io.metersphere.sdk.listener.EventSource;
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ApiEventSource implements EventSource {
|
public class ApiEventSource implements EventSource {
|
||||||
private EventListener<Event> listener;
|
private EventListener<Event> listener;
|
||||||
|
@ -19,4 +22,12 @@ public class ApiEventSource implements EventSource {
|
||||||
Event event = new Event("API", message);
|
Event event = new Event("API", message);
|
||||||
listener.onEvent(event);
|
listener.onEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fireEvent(String module, String message, Map<String, Object> paramMap) {
|
||||||
|
Event event = new Event("API", message, paramMap);
|
||||||
|
listener.onEvent(event);
|
||||||
|
LogUtils.info("带有参数的监听事件");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
@ -33,5 +35,7 @@ public class EventSourceTests {
|
||||||
});
|
});
|
||||||
// 触发事件
|
// 触发事件
|
||||||
apiEventSource.fireEvent("API", "Event after removing the listener test.");
|
apiEventSource.fireEvent("API", "Event after removing the listener test.");
|
||||||
|
// 触发事件待参数
|
||||||
|
apiEventSource.fireEvent("API", "Event after removing the listener test.",new HashMap<>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package io.metersphere.functional.constants;
|
||||||
|
|
||||||
|
public interface CaseEvent {
|
||||||
|
|
||||||
|
interface Event {
|
||||||
|
String ASSOCIATE = "associate";
|
||||||
|
String DISASSOCIATE = "disassociate";
|
||||||
|
String BATCH_DISASSOCIATE = "batchDisassociate";
|
||||||
|
String DELETE_FUNCTIONAL_CASE = "deleteFunctionalCase";
|
||||||
|
String DELETE_TRASH_FUNCTIONAL_CASE = "deleteTrashFunctionalCase";
|
||||||
|
String RECOVER_FUNCTIONAL_CASE = "recoverFunctionalCase";
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Param {
|
||||||
|
String REVIEW_ID = "reviewId";
|
||||||
|
String CASE_IDS = "caseIds";
|
||||||
|
String PASS_COUNT = "passCount";
|
||||||
|
String CASE_COUNT = "caseCount";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package io.metersphere.functional.event;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.listener.Event;
|
||||||
|
import io.metersphere.sdk.listener.EventListener;
|
||||||
|
import io.metersphere.sdk.listener.EventSource;
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CaseEventSource implements EventSource {
|
||||||
|
private EventListener<Event> listener;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addListener(EventListener<Event> listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fireEvent(String module, String message) {
|
||||||
|
Event event = new Event("CASE", message);
|
||||||
|
listener.onEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fireEvent(String module, String message, Map<String, Object> paramMap) {
|
||||||
|
Event event = new Event("CASE", message, paramMap);
|
||||||
|
listener.onEvent(event);
|
||||||
|
LogUtils.info("带有参数的监听事件");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,201 @@
|
||||||
|
package io.metersphere.functional.listener;
|
||||||
|
|
||||||
|
import io.metersphere.functional.constants.CaseEvent;
|
||||||
|
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
||||||
|
import io.metersphere.functional.domain.CaseReview;
|
||||||
|
import io.metersphere.functional.domain.CaseReviewFunctionalCase;
|
||||||
|
import io.metersphere.functional.domain.CaseReviewFunctionalCaseExample;
|
||||||
|
import io.metersphere.functional.domain.CaseReviewFunctionalCaseUserExample;
|
||||||
|
import io.metersphere.functional.mapper.CaseReviewFunctionalCaseMapper;
|
||||||
|
import io.metersphere.functional.mapper.CaseReviewFunctionalCaseUserMapper;
|
||||||
|
import io.metersphere.functional.mapper.CaseReviewMapper;
|
||||||
|
import io.metersphere.sdk.listener.Event;
|
||||||
|
import io.metersphere.sdk.listener.EventListener;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CaseEventListener implements EventListener<Event> {
|
||||||
|
@Resource
|
||||||
|
private CaseReviewMapper caseReviewMapper;
|
||||||
|
@Resource
|
||||||
|
private CaseReviewFunctionalCaseUserMapper caseReviewFunctionalCaseUserMapper;
|
||||||
|
@Resource
|
||||||
|
private CaseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper;
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@Override
|
||||||
|
public void onEvent(Event event) {
|
||||||
|
LogUtils.info("CaseEventListener: " + event.module() + ":" + event.message());
|
||||||
|
//批量修改用例评审人
|
||||||
|
//重新提审(批量)/自动重新提审(编辑)
|
||||||
|
//批量修改结果
|
||||||
|
String message = event.message();
|
||||||
|
switch (message) {
|
||||||
|
case CaseEvent.Event.ASSOCIATE -> {
|
||||||
|
updateCaseReviewByAssociate(event);
|
||||||
|
}
|
||||||
|
case CaseEvent.Event.DISASSOCIATE -> {
|
||||||
|
updateCaseReviewByDisAssociate(event);
|
||||||
|
}
|
||||||
|
case CaseEvent.Event.BATCH_DISASSOCIATE -> {
|
||||||
|
updateCaseReviewByBatchDisassociate(event);
|
||||||
|
}
|
||||||
|
case CaseEvent.Event.DELETE_FUNCTIONAL_CASE -> {
|
||||||
|
updateCaseReviewByDeleteFunctionalCase(event);
|
||||||
|
}
|
||||||
|
case CaseEvent.Event.DELETE_TRASH_FUNCTIONAL_CASE -> {
|
||||||
|
updateCaseReviewByDeleteTrashFunctionalCase(event);
|
||||||
|
}
|
||||||
|
case CaseEvent.Event.RECOVER_FUNCTIONAL_CASE -> {
|
||||||
|
updateCaseReviewByRecoverFunctionalCase(event);
|
||||||
|
}
|
||||||
|
default -> LogUtils.info("CaseEventListener: " + event.module() + ":" + event.message());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 功能用例的回收站恢复/批量恢复重新计算用例评审的通过率和用例数
|
||||||
|
*/
|
||||||
|
private void updateCaseReviewByRecoverFunctionalCase(Event event) {
|
||||||
|
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = getCaseReviewFunctionalCases(event);
|
||||||
|
Map<String, List<CaseReviewFunctionalCase>> reviewIdMap = caseReviewFunctionalCases.stream().collect(Collectors.groupingBy(CaseReviewFunctionalCase::getReviewId));
|
||||||
|
reviewIdMap.forEach((reviewId, caseReviewFunctionalCaseList) -> {
|
||||||
|
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(reviewId);
|
||||||
|
List<CaseReviewFunctionalCase> passList = caseReviewFunctionalCases.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getStatus(), FunctionalCaseReviewStatus.PASS.toString())).toList();
|
||||||
|
updateCaseReview(reviewId, caseReview.getCaseCount() + caseReviewFunctionalCaseList.size(), passList.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 功能用例的回收站删除/批量删除重新计算用例评审的通过率和用例数
|
||||||
|
*/
|
||||||
|
private void updateCaseReviewByDeleteTrashFunctionalCase(Event event) {
|
||||||
|
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = getCaseReviewFunctionalCases(event);
|
||||||
|
if (CollectionUtils.isEmpty(caseReviewFunctionalCases)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<String, List<CaseReviewFunctionalCase>> reviewIdMap = caseReviewFunctionalCases.stream().collect(Collectors.groupingBy(CaseReviewFunctionalCase::getReviewId));
|
||||||
|
reviewIdMap.forEach((reviewId, caseReviewFunctionalCaseList) -> {
|
||||||
|
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(reviewId);
|
||||||
|
List<CaseReviewFunctionalCase> passList = caseReviewFunctionalCases.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getStatus(), FunctionalCaseReviewStatus.PASS.toString())).toList();
|
||||||
|
updateCaseReview(reviewId, caseReview.getCaseCount() - caseReviewFunctionalCaseList.size(), passList.size());
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 功能用例的删除/批量删除重新计算用例评审的通过率和用例数
|
||||||
|
*/
|
||||||
|
private void updateCaseReviewByDeleteFunctionalCase(Event event) {
|
||||||
|
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = getCaseReviewFunctionalCases(event);
|
||||||
|
if (CollectionUtils.isEmpty(caseReviewFunctionalCases)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<String, List<CaseReviewFunctionalCase>> reviewIdMap = caseReviewFunctionalCases.stream().collect(Collectors.groupingBy(CaseReviewFunctionalCase::getReviewId));
|
||||||
|
reviewIdMap.forEach((reviewId, caseReviewFunctionalCaseList) -> {
|
||||||
|
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(reviewId);
|
||||||
|
List<CaseReviewFunctionalCase> passList = caseReviewFunctionalCases.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getStatus(), FunctionalCaseReviewStatus.PASS.toString())).toList();
|
||||||
|
updateCaseReview(reviewId, caseReview.getCaseCount() - caseReviewFunctionalCaseList.size(), passList.size());
|
||||||
|
List<String> caseIdList = caseReviewFunctionalCaseList.stream().map(CaseReviewFunctionalCase::getId).toList();
|
||||||
|
deleteReviewFunctionalCaseUser(caseIdList, reviewId);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CaseReviewFunctionalCase> getCaseReviewFunctionalCases(Event event) {
|
||||||
|
Map<String, Object> paramMap = event.paramMap();
|
||||||
|
Object caseIds = paramMap.get(CaseEvent.Param.CASE_IDS);
|
||||||
|
List<String> caseIdList = JSON.parseArray(JSON.toJSONString(caseIds), String.class);
|
||||||
|
CaseReviewFunctionalCaseExample functionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||||
|
functionalCaseExample.createCriteria().andCaseIdIn(caseIdList);
|
||||||
|
return caseReviewFunctionalCaseMapper.selectByExample(functionalCaseExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1.批量取消关联重新计算用例评审的通过率和用例数
|
||||||
|
* 2.删除用例和用例评审人的关系
|
||||||
|
*/
|
||||||
|
private void updateCaseReviewByBatchDisassociate(Event event) {
|
||||||
|
Map<String, Object> paramMap = event.paramMap();
|
||||||
|
String reviewId = paramMap.get(CaseEvent.Param.REVIEW_ID).toString();
|
||||||
|
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(reviewId);
|
||||||
|
Integer oldCaseCount = caseReview.getCaseCount();
|
||||||
|
Object caseIds = paramMap.get(CaseEvent.Param.CASE_IDS);
|
||||||
|
List<String> caseIdList = JSON.parseArray(JSON.toJSONString(caseIds), String.class);
|
||||||
|
int passNumber = Integer.parseInt(paramMap.get(CaseEvent.Param.PASS_COUNT).toString());
|
||||||
|
updateCaseReview(reviewId, oldCaseCount - caseIdList.size(), passNumber);
|
||||||
|
//删除用例和用例评审人的关系
|
||||||
|
deleteCaseReviewFunctionalCaseUser(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1.单独取消关联重新计算用例评审的通过率和用例数
|
||||||
|
* 2.删除用例和用例评审人的关系
|
||||||
|
*/
|
||||||
|
private void updateCaseReviewByDisAssociate(Event event) {
|
||||||
|
updateCaseReviewByAssociate(event);
|
||||||
|
//删除用例和用例评审人的关系
|
||||||
|
deleteCaseReviewFunctionalCaseUser(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除用例和用例评审人的关系
|
||||||
|
*/
|
||||||
|
private void deleteCaseReviewFunctionalCaseUser(Event event) {
|
||||||
|
Map<String, Object> paramMap = event.paramMap();
|
||||||
|
Object caseIds = paramMap.get(CaseEvent.Param.CASE_IDS);
|
||||||
|
List<String> caseIdList = JSON.parseArray(JSON.toJSONString(caseIds), String.class);
|
||||||
|
String reviewId = paramMap.get(CaseEvent.Param.REVIEW_ID).toString();
|
||||||
|
deleteReviewFunctionalCaseUser(caseIdList, reviewId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteReviewFunctionalCaseUser(List<String> caseIdList, String reviewId) {
|
||||||
|
CaseReviewFunctionalCaseUserExample caseReviewFunctionalCaseUserExample = new CaseReviewFunctionalCaseUserExample();
|
||||||
|
caseReviewFunctionalCaseUserExample.createCriteria().andCaseIdIn(caseIdList).andReviewIdEqualTo(reviewId);
|
||||||
|
caseReviewFunctionalCaseUserMapper.deleteByExample(caseReviewFunctionalCaseUserExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联用例(单独/批量)重新计算用例评审的通过率和用例数
|
||||||
|
*/
|
||||||
|
private void updateCaseReviewByAssociate(Event event) {
|
||||||
|
Map<String, Object> paramMap = event.paramMap();
|
||||||
|
String reviewId = paramMap.get(CaseEvent.Param.REVIEW_ID).toString();
|
||||||
|
int caseCount = Integer.parseInt(paramMap.get(CaseEvent.Param.CASE_COUNT).toString());
|
||||||
|
int passNumber = Integer.parseInt(paramMap.get(CaseEvent.Param.PASS_COUNT).toString());
|
||||||
|
updateCaseReview(reviewId, caseCount, passNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新计算用例评审的通过率和用例数
|
||||||
|
*/
|
||||||
|
private void updateCaseReview(String reviewId, int caseCount, int passNumber) {
|
||||||
|
CaseReview caseReview = new CaseReview();
|
||||||
|
caseReview.setId(reviewId);
|
||||||
|
//更新用例数量
|
||||||
|
caseReview.setCaseCount(caseCount);
|
||||||
|
//通过率
|
||||||
|
BigDecimal passCount = BigDecimal.valueOf(passNumber);
|
||||||
|
BigDecimal totalCount = BigDecimal.valueOf(caseReview.getCaseCount());
|
||||||
|
if (totalCount.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
|
caseReview.setPassRate(BigDecimal.ZERO);
|
||||||
|
} else {
|
||||||
|
BigDecimal passRate = passCount.divide(totalCount, 2, RoundingMode.HALF_UP);
|
||||||
|
caseReview.setPassRate(passRate);
|
||||||
|
}
|
||||||
|
caseReviewMapper.updateByPrimaryKeySelective(caseReview);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.functional.mapper;
|
package io.metersphere.functional.mapper;
|
||||||
|
|
||||||
|
import io.metersphere.functional.domain.CaseReviewFunctionalCase;
|
||||||
import io.metersphere.functional.dto.FunctionalCaseReviewDTO;
|
import io.metersphere.functional.dto.FunctionalCaseReviewDTO;
|
||||||
import io.metersphere.functional.dto.ReviewFunctionalCaseDTO;
|
import io.metersphere.functional.dto.ReviewFunctionalCaseDTO;
|
||||||
import io.metersphere.functional.request.BaseReviewCaseBatchRequest;
|
import io.metersphere.functional.request.BaseReviewCaseBatchRequest;
|
||||||
|
@ -27,4 +28,6 @@ public interface ExtCaseReviewFunctionalCaseMapper {
|
||||||
Long getPos(@Param("reviewId") String reviewId);
|
Long getPos(@Param("reviewId") String reviewId);
|
||||||
|
|
||||||
List<String> getIds(@Param("request") BaseReviewCaseBatchRequest request, @Param("userId") String userId, @Param("deleted") boolean deleted);
|
List<String> getIds(@Param("request") BaseReviewCaseBatchRequest request, @Param("userId") String userId, @Param("deleted") boolean deleted);
|
||||||
|
|
||||||
|
List<CaseReviewFunctionalCase> getList(@Param("reviewId") String reviewId, @Param("reviewIds") List<String> reviewIds, @Param("deleted") boolean deleted);
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,4 +286,23 @@
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="getList" resultType="io.metersphere.functional.domain.CaseReviewFunctionalCase">
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
case_review_functional_case crfc
|
||||||
|
LEFT JOIN functional_case fc ON crfc.case_id = fc.id
|
||||||
|
WHERE
|
||||||
|
fc.deleted = #{deleted}
|
||||||
|
<if test="reviewId != null and reviewId != ''">
|
||||||
|
and crfc.review_id = #{reviewId}
|
||||||
|
</if>
|
||||||
|
<if test="reviewIds != null and reviewIds.size() > 0">
|
||||||
|
and crfc.review_id in
|
||||||
|
<foreach collection="reviewIds" item="reviewId" separator="," open="(" close=")">
|
||||||
|
#{reviewId}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.functional.service;
|
package io.metersphere.functional.service;
|
||||||
|
|
||||||
|
|
||||||
|
import io.metersphere.functional.constants.CaseEvent;
|
||||||
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
||||||
import io.metersphere.functional.domain.CaseReviewFunctionalCase;
|
import io.metersphere.functional.domain.CaseReviewFunctionalCase;
|
||||||
import io.metersphere.functional.domain.CaseReviewFunctionalCaseExample;
|
import io.metersphere.functional.domain.CaseReviewFunctionalCaseExample;
|
||||||
|
@ -12,18 +13,18 @@ import io.metersphere.functional.mapper.ExtCaseReviewFunctionalCaseUserMapper;
|
||||||
import io.metersphere.functional.mapper.ExtFunctionalCaseModuleMapper;
|
import io.metersphere.functional.mapper.ExtFunctionalCaseModuleMapper;
|
||||||
import io.metersphere.functional.request.BaseReviewCaseBatchRequest;
|
import io.metersphere.functional.request.BaseReviewCaseBatchRequest;
|
||||||
import io.metersphere.functional.request.ReviewFunctionalCasePageRequest;
|
import io.metersphere.functional.request.ReviewFunctionalCasePageRequest;
|
||||||
|
import io.metersphere.functional.utils.CaseListenerUtils;
|
||||||
import io.metersphere.project.domain.ProjectVersion;
|
import io.metersphere.project.domain.ProjectVersion;
|
||||||
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,8 +90,8 @@ public class CaseReviewFunctionalCaseService {
|
||||||
list.forEach(item -> {
|
list.forEach(item -> {
|
||||||
item.setModuleName(moduleMap.get(item.getModuleId()));
|
item.setModuleName(moduleMap.get(item.getModuleId()));
|
||||||
item.setVersionName(versionMap.get(item.getVersionId()));
|
item.setVersionName(versionMap.get(item.getVersionId()));
|
||||||
item.setReviewers(Arrays.asList(userIdMap.get(item.getId())));
|
item.setReviewers(Collections.singletonList(userIdMap.get(item.getId())));
|
||||||
item.setReviewNames(Arrays.asList(userNameMap.get(item.getId())));
|
item.setReviewNames(Collections.singletonList(userNameMap.get(item.getId())));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
|
@ -106,10 +107,23 @@ public class CaseReviewFunctionalCaseService {
|
||||||
if (CollectionUtils.isNotEmpty(ids)) {
|
if (CollectionUtils.isNotEmpty(ids)) {
|
||||||
CaseReviewFunctionalCaseExample example = new CaseReviewFunctionalCaseExample();
|
CaseReviewFunctionalCaseExample example = new CaseReviewFunctionalCaseExample();
|
||||||
example.createCriteria().andIdIn(ids);
|
example.createCriteria().andIdIn(ids);
|
||||||
|
Map<String, Object> param = getParam(request.getReviewId(), example, ids);
|
||||||
|
CaseListenerUtils.addListener(param, CaseEvent.Event.BATCH_DISASSOCIATE);
|
||||||
caseReviewFunctionalCaseMapper.deleteByExample(example);
|
caseReviewFunctionalCaseMapper.deleteByExample(example);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> getParam(String reviewId, CaseReviewFunctionalCaseExample example, List<String> ids) {
|
||||||
|
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(example);
|
||||||
|
List<String> caseIds = caseReviewFunctionalCases.stream().map(CaseReviewFunctionalCase::getCaseId).toList();
|
||||||
|
List<CaseReviewFunctionalCase> passList = caseReviewFunctionalCases.stream().filter(t -> !ids.contains(t.getId()) && StringUtils.equalsIgnoreCase(t.getStatus(), FunctionalCaseReviewStatus.PASS.toString())).toList();
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS,caseIds);
|
||||||
|
param.put(CaseEvent.Param.REVIEW_ID, reviewId);
|
||||||
|
param.put(CaseEvent.Param.PASS_COUNT,passList.size());
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> doSelectIds(BaseReviewCaseBatchRequest request) {
|
public List<String> doSelectIds(BaseReviewCaseBatchRequest request) {
|
||||||
if (request.isSelectAll()) {
|
if (request.isSelectAll()) {
|
||||||
List<String> ids = extCaseReviewFunctionalCaseMapper.getIds(request, request.getUserId(), false);
|
List<String> ids = extCaseReviewFunctionalCaseMapper.getIds(request, request.getUserId(), false);
|
||||||
|
@ -126,9 +140,9 @@ public class CaseReviewFunctionalCaseService {
|
||||||
/**
|
/**
|
||||||
* 评审详情页面 创建用例并关联
|
* 评审详情页面 创建用例并关联
|
||||||
*
|
*
|
||||||
* @param caseId
|
* @param caseId 功能用例ID
|
||||||
* @param userId
|
* @param userId 当前操作人
|
||||||
* @param reviewId
|
* @param reviewId 评审id
|
||||||
*/
|
*/
|
||||||
public void addCaseReviewFunctionalCase(String caseId, String userId, String reviewId) {
|
public void addCaseReviewFunctionalCase(String caseId, String userId, String reviewId) {
|
||||||
CaseReviewFunctionalCase reviewFunctionalCase = new CaseReviewFunctionalCase();
|
CaseReviewFunctionalCase reviewFunctionalCase = new CaseReviewFunctionalCase();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.functional.service;
|
package io.metersphere.functional.service;
|
||||||
|
|
||||||
|
|
||||||
|
import io.metersphere.functional.constants.CaseEvent;
|
||||||
import io.metersphere.functional.constants.CaseReviewStatus;
|
import io.metersphere.functional.constants.CaseReviewStatus;
|
||||||
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
||||||
import io.metersphere.functional.domain.*;
|
import io.metersphere.functional.domain.*;
|
||||||
|
@ -10,6 +11,7 @@ import io.metersphere.functional.dto.CaseReviewUserDTO;
|
||||||
import io.metersphere.functional.mapper.*;
|
import io.metersphere.functional.mapper.*;
|
||||||
import io.metersphere.functional.request.*;
|
import io.metersphere.functional.request.*;
|
||||||
import io.metersphere.functional.result.CaseManagementResultCode;
|
import io.metersphere.functional.result.CaseManagementResultCode;
|
||||||
|
import io.metersphere.functional.utils.CaseListenerUtils;
|
||||||
import io.metersphere.project.dto.ModuleCountDTO;
|
import io.metersphere.project.dto.ModuleCountDTO;
|
||||||
import io.metersphere.sdk.constants.ApplicationNumScope;
|
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
|
@ -33,8 +35,8 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -71,8 +73,6 @@ public class CaseReviewService {
|
||||||
@Resource
|
@Resource
|
||||||
private DeleteCaseReviewService deleteCaseReviewService;
|
private DeleteCaseReviewService deleteCaseReviewService;
|
||||||
@Resource
|
@Resource
|
||||||
private CaseReviewFunctionalCaseUserMapper caseReviewFunctionalCaseUserMapper;
|
|
||||||
@Resource
|
|
||||||
private ExtCaseReviewFunctionalCaseMapper extCaseReviewFunctionalCaseMapper;
|
private ExtCaseReviewFunctionalCaseMapper extCaseReviewFunctionalCaseMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private CaseReviewModuleService caseReviewModuleService;
|
private CaseReviewModuleService caseReviewModuleService;
|
||||||
|
@ -187,9 +187,7 @@ public class CaseReviewService {
|
||||||
* @return Map
|
* @return Map
|
||||||
*/
|
*/
|
||||||
private Map<String, List<CaseReviewFunctionalCase>> getReviewCaseMap(List<String> reviewIds) {
|
private Map<String, List<CaseReviewFunctionalCase>> getReviewCaseMap(List<String> reviewIds) {
|
||||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = extCaseReviewFunctionalCaseMapper.getList(null, reviewIds, false);
|
||||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdIn(reviewIds);
|
|
||||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
|
||||||
return caseReviewFunctionalCases.stream().collect(Collectors.groupingBy(CaseReviewFunctionalCase::getReviewId));
|
return caseReviewFunctionalCases.stream().collect(Collectors.groupingBy(CaseReviewFunctionalCase::getReviewId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,9 +448,7 @@ public class CaseReviewService {
|
||||||
if (CollectionUtils.isEmpty(functionalCases)) {
|
if (CollectionUtils.isEmpty(functionalCases)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = extCaseReviewFunctionalCaseMapper.getList(caseReviewId, null, false);
|
||||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(caseReviewId);
|
|
||||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
|
||||||
List<String> castIds = caseReviewFunctionalCases.stream().map(CaseReviewFunctionalCase::getCaseId).toList();
|
List<String> castIds = caseReviewFunctionalCases.stream().map(CaseReviewFunctionalCase::getCaseId).toList();
|
||||||
List<String> caseRealIds = caseIds.stream().filter(t -> !castIds.contains(t)).toList();
|
List<String> caseRealIds = caseIds.stream().filter(t -> !castIds.contains(t)).toList();
|
||||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
|
@ -467,19 +463,20 @@ public class CaseReviewService {
|
||||||
} finally {
|
} finally {
|
||||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||||
}
|
}
|
||||||
List<CaseReviewFunctionalCase> passList = caseReviewFunctionalCases.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getStatus(), FunctionalCaseReviewStatus.PASS.toString())).toList();
|
Map<String, Object> param = getParam(caseReviewFunctionalCases, caseReviewExist.getCaseCount() + caseRealIds.size(), caseReviewId);
|
||||||
CaseReview caseReview = new CaseReview();
|
CaseListenerUtils.addListener(param, CaseEvent.Event.ASSOCIATE);
|
||||||
caseReview.setId(caseReviewId);
|
|
||||||
//更新用例数量
|
|
||||||
caseReview.setCaseCount(caseReviewExist.getCaseCount() + caseRealIds.size());
|
|
||||||
//通过率
|
|
||||||
BigDecimal passCount = BigDecimal.valueOf(passList.size());
|
|
||||||
BigDecimal totalCount = BigDecimal.valueOf(caseReview.getCaseCount());
|
|
||||||
BigDecimal passRate = passCount.divide(totalCount, 2, RoundingMode.HALF_UP);
|
|
||||||
caseReview.setPassRate(passRate);
|
|
||||||
caseReviewMapper.updateByPrimaryKeySelective(caseReview);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> getParam(List<CaseReviewFunctionalCase> caseReviewFunctionalCases, int caseReviewExist, String caseReviewId) {
|
||||||
|
List<CaseReviewFunctionalCase> passList = caseReviewFunctionalCases.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getStatus(), FunctionalCaseReviewStatus.PASS.toString())).toList();
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put(CaseEvent.Param.CASE_COUNT, caseReviewExist);
|
||||||
|
param.put(CaseEvent.Param.REVIEW_ID, caseReviewId);
|
||||||
|
param.put(CaseEvent.Param.PASS_COUNT, passList.size());
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public <T> List<String> doSelectIds(T dto, String projectId) {
|
public <T> List<String> doSelectIds(T dto, String projectId) {
|
||||||
BaseFunctionalCaseBatchDTO request = (BaseFunctionalCaseBatchDTO) dto;
|
BaseFunctionalCaseBatchDTO request = (BaseFunctionalCaseBatchDTO) dto;
|
||||||
if (request.isSelectAll()) {
|
if (request.isSelectAll()) {
|
||||||
|
@ -565,30 +562,11 @@ public class CaseReviewService {
|
||||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo(caseId);
|
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo(caseId);
|
||||||
caseReviewFunctionalCaseMapper.deleteByExample(caseReviewFunctionalCaseExample);
|
caseReviewFunctionalCaseMapper.deleteByExample(caseReviewFunctionalCaseExample);
|
||||||
//2.删除用例和用例评审人的关系
|
|
||||||
CaseReviewFunctionalCaseUserExample caseReviewFunctionalCaseUserExample = new CaseReviewFunctionalCaseUserExample();
|
|
||||||
caseReviewFunctionalCaseUserExample.createCriteria().andCaseIdEqualTo(caseId).andReviewIdEqualTo(reviewId);
|
|
||||||
caseReviewFunctionalCaseUserMapper.deleteByExample(caseReviewFunctionalCaseUserExample);
|
|
||||||
|
|
||||||
caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = extCaseReviewFunctionalCaseMapper.getList(reviewId, null, false);
|
||||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId);
|
Map<String, Object> param = getParam(caseReviewFunctionalCases, caseReviewFunctionalCases.size(), reviewId);
|
||||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
param.put(CaseEvent.Param.CASE_IDS, List.of(caseId));
|
||||||
List<CaseReviewFunctionalCase> passList = caseReviewFunctionalCases.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getStatus(), FunctionalCaseReviewStatus.PASS.toString())).toList();
|
CaseListenerUtils.addListener(param, CaseEvent.Event.DISASSOCIATE);
|
||||||
CaseReview caseReview = new CaseReview();
|
|
||||||
caseReview.setId(reviewId);
|
|
||||||
//更新用例数量
|
|
||||||
caseReview.setCaseCount(caseReviewFunctionalCases.size());
|
|
||||||
//通过率
|
|
||||||
BigDecimal passCount = BigDecimal.valueOf(passList.size());
|
|
||||||
BigDecimal totalCount = BigDecimal.valueOf(caseReview.getCaseCount());
|
|
||||||
BigDecimal passRate;
|
|
||||||
if (totalCount.compareTo(BigDecimal.ZERO) == 0) {
|
|
||||||
passRate = BigDecimal.ZERO;
|
|
||||||
} else {
|
|
||||||
passRate = passCount.divide(totalCount, 2, RoundingMode.HALF_UP);
|
|
||||||
}
|
|
||||||
caseReview.setPassRate(passRate);
|
|
||||||
caseReviewMapper.updateByPrimaryKeySelective(caseReview);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Long> moduleCount(CaseReviewPageRequest request) {
|
public Map<String, Long> moduleCount(CaseReviewPageRequest request) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.functional.service;
|
package io.metersphere.functional.service;
|
||||||
|
|
||||||
|
import io.metersphere.functional.constants.CaseEvent;
|
||||||
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
||||||
import io.metersphere.functional.domain.*;
|
import io.metersphere.functional.domain.*;
|
||||||
import io.metersphere.functional.dto.*;
|
import io.metersphere.functional.dto.*;
|
||||||
|
@ -9,6 +10,7 @@ import io.metersphere.functional.mapper.FunctionalCaseFollowerMapper;
|
||||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||||
import io.metersphere.functional.request.*;
|
import io.metersphere.functional.request.*;
|
||||||
import io.metersphere.functional.result.CaseManagementResultCode;
|
import io.metersphere.functional.result.CaseManagementResultCode;
|
||||||
|
import io.metersphere.functional.utils.CaseListenerUtils;
|
||||||
import io.metersphere.project.domain.FileAssociation;
|
import io.metersphere.project.domain.FileAssociation;
|
||||||
import io.metersphere.project.dto.ModuleCountDTO;
|
import io.metersphere.project.dto.ModuleCountDTO;
|
||||||
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||||
|
@ -372,13 +374,21 @@ public class FunctionalCaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handDeleteFunctionalCase(List<String> ids, Boolean deleteAll, String userId) {
|
private void handDeleteFunctionalCase(List<String> ids, Boolean deleteAll, String userId) {
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
if (deleteAll) {
|
if (deleteAll) {
|
||||||
//全部删除 进入回收站
|
//全部删除 进入回收站
|
||||||
List<String> refId = extFunctionalCaseMapper.getRefIds(ids, false);
|
List<String> refId = extFunctionalCaseMapper.getRefIds(ids, false);
|
||||||
|
FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample();
|
||||||
|
functionalCaseExample.createCriteria().andRefIdIn(refId);
|
||||||
|
List<FunctionalCase> functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample);
|
||||||
|
List<String> caseIds = functionalCases.stream().map(FunctionalCase::getId).toList();
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS, caseIds);
|
||||||
extFunctionalCaseMapper.batchDelete(refId, userId);
|
extFunctionalCaseMapper.batchDelete(refId, userId);
|
||||||
} else {
|
} else {
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS, ids);
|
||||||
doDelete(ids, userId);
|
doDelete(ids, userId);
|
||||||
}
|
}
|
||||||
|
CaseListenerUtils.addListener(param, CaseEvent.Event.DELETE_FUNCTIONAL_CASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.functional.service;
|
package io.metersphere.functional.service;
|
||||||
|
|
||||||
|
import io.metersphere.functional.constants.CaseEvent;
|
||||||
import io.metersphere.functional.domain.FunctionalCase;
|
import io.metersphere.functional.domain.FunctionalCase;
|
||||||
import io.metersphere.functional.domain.FunctionalCaseCustomField;
|
import io.metersphere.functional.domain.FunctionalCaseCustomField;
|
||||||
import io.metersphere.functional.domain.FunctionalCaseCustomFieldExample;
|
import io.metersphere.functional.domain.FunctionalCaseCustomFieldExample;
|
||||||
|
@ -8,6 +9,7 @@ import io.metersphere.functional.mapper.ExtFunctionalCaseMapper;
|
||||||
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
|
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
|
||||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||||
import io.metersphere.functional.request.FunctionalCaseBatchRequest;
|
import io.metersphere.functional.request.FunctionalCaseBatchRequest;
|
||||||
|
import io.metersphere.functional.utils.CaseListenerUtils;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.Translator;
|
import io.metersphere.sdk.util.Translator;
|
||||||
import io.metersphere.system.domain.CustomField;
|
import io.metersphere.system.domain.CustomField;
|
||||||
|
@ -15,12 +17,13 @@ import io.metersphere.system.domain.CustomFieldExample;
|
||||||
import io.metersphere.system.mapper.CustomFieldMapper;
|
import io.metersphere.system.mapper.CustomFieldMapper;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author guoyuqi
|
* @author guoyuqi
|
||||||
|
@ -55,10 +58,15 @@ public class FunctionalCaseTrashService {
|
||||||
List<String> ids = getIdsByRefId(functionalCase.getRefId());
|
List<String> ids = getIdsByRefId(functionalCase.getRefId());
|
||||||
//检查自定义字段是否还存在,不存在,删除关联关系(与恢复流程没关系可异步执行)
|
//检查自定义字段是否还存在,不存在,删除关联关系(与恢复流程没关系可异步执行)
|
||||||
delCustomFields(ids);
|
delCustomFields(ids);
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS,ids);
|
||||||
|
CaseListenerUtils.addListener(param, CaseEvent.Event.RECOVER_FUNCTIONAL_CASE);
|
||||||
extFunctionalCaseMapper.recoverCase(ids,userId,System.currentTimeMillis());
|
extFunctionalCaseMapper.recoverCase(ids,userId,System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查自定义字段是否还存在,不存在,删除关联关系(与恢复流程没关系可异步执行)
|
||||||
|
*/
|
||||||
public void delCustomFields(List<String> ids) {
|
public void delCustomFields(List<String> ids) {
|
||||||
doDeleteCustomFields(ids);
|
doDeleteCustomFields(ids);
|
||||||
}
|
}
|
||||||
|
@ -102,6 +110,9 @@ public class FunctionalCaseTrashService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<String> ids = getIdsByRefId(functionalCase.getRefId());
|
List<String> ids = getIdsByRefId(functionalCase.getRefId());
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS,ids);
|
||||||
|
CaseListenerUtils.addListener(param, CaseEvent.Event.DELETE_TRASH_FUNCTIONAL_CASE);
|
||||||
deleteFunctionalCaseService.deleteFunctionalCaseResource(ids, functionalCase.getProjectId());
|
deleteFunctionalCaseService.deleteFunctionalCaseResource(ids, functionalCase.getProjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +145,13 @@ public class FunctionalCaseTrashService {
|
||||||
refIds = functionalCases.stream().map(FunctionalCase::getRefId).distinct().toList();
|
refIds = functionalCases.stream().map(FunctionalCase::getRefId).distinct().toList();
|
||||||
}
|
}
|
||||||
if (CollectionUtils.isNotEmpty(refIds)) {
|
if (CollectionUtils.isNotEmpty(refIds)) {
|
||||||
|
FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample();
|
||||||
|
functionalCaseExample.createCriteria().andRefIdIn(refIds);
|
||||||
|
List<FunctionalCase> functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample);
|
||||||
|
List<String> ids = functionalCases.stream().map(FunctionalCase::getId).toList();
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS,ids);
|
||||||
|
CaseListenerUtils.addListener(param, CaseEvent.Event.RECOVER_FUNCTIONAL_CASE);
|
||||||
extFunctionalCaseMapper.recoverCaseByRefIds(refIds, userId, System.currentTimeMillis());
|
extFunctionalCaseMapper.recoverCaseByRefIds(refIds, userId, System.currentTimeMillis());
|
||||||
delCustomFieldsByRefIds(refIds);
|
delCustomFieldsByRefIds(refIds);
|
||||||
}
|
}
|
||||||
|
@ -175,6 +193,9 @@ public class FunctionalCaseTrashService {
|
||||||
deleteByRefIds(request, refIds);
|
deleteByRefIds(request, refIds);
|
||||||
}else {
|
}else {
|
||||||
//只删除当前选择的数据
|
//只删除当前选择的数据
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS,ids);
|
||||||
|
CaseListenerUtils.addListener(param, CaseEvent.Event.DELETE_TRASH_FUNCTIONAL_CASE);
|
||||||
deleteFunctionalCaseService.deleteFunctionalCaseResource(ids, request.getProjectId());
|
deleteFunctionalCaseService.deleteFunctionalCaseResource(ids, request.getProjectId());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -189,6 +210,9 @@ public class FunctionalCaseTrashService {
|
||||||
deleteByRefIds(request, refIds);
|
deleteByRefIds(request, refIds);
|
||||||
} else {
|
} else {
|
||||||
//只删除当前选择的数据
|
//只删除当前选择的数据
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS,request.getSelectIds());
|
||||||
|
CaseListenerUtils.addListener(param, CaseEvent.Event.DELETE_TRASH_FUNCTIONAL_CASE);
|
||||||
deleteFunctionalCaseService.deleteFunctionalCaseResource(request.getSelectIds(), request.getProjectId());
|
deleteFunctionalCaseService.deleteFunctionalCaseResource(request.getSelectIds(), request.getProjectId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,6 +223,9 @@ public class FunctionalCaseTrashService {
|
||||||
functionalCaseExample.createCriteria().andRefIdIn(refIds).andDeletedEqualTo(true);
|
functionalCaseExample.createCriteria().andRefIdIn(refIds).andDeletedEqualTo(true);
|
||||||
List<FunctionalCase> functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample);
|
List<FunctionalCase> functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample);
|
||||||
List<String> deleteIds = functionalCases.stream().map(FunctionalCase::getId).toList();
|
List<String> deleteIds = functionalCases.stream().map(FunctionalCase::getId).toList();
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put(CaseEvent.Param.CASE_IDS,deleteIds);
|
||||||
|
CaseListenerUtils.addListener(param, CaseEvent.Event.DELETE_TRASH_FUNCTIONAL_CASE);
|
||||||
deleteFunctionalCaseService.deleteFunctionalCaseResource(deleteIds, request.getProjectId());
|
deleteFunctionalCaseService.deleteFunctionalCaseResource(deleteIds, request.getProjectId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import io.metersphere.system.uid.IDGenerator;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.beanutils.BeanMap;
|
import org.apache.commons.beanutils.BeanMap;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -51,7 +50,6 @@ public class ReviewFunctionalCaseService {
|
||||||
private ExtCaseReviewHistoryMapper extCaseReviewHistoryMapper;
|
private ExtCaseReviewHistoryMapper extCaseReviewHistoryMapper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 评审功能用例
|
* 评审功能用例
|
||||||
*
|
*
|
||||||
|
@ -66,7 +64,7 @@ public class ReviewFunctionalCaseService {
|
||||||
String functionalCaseStatus = getFunctionalCaseStatus(request);
|
String functionalCaseStatus = getFunctionalCaseStatus(request);
|
||||||
extCaseReviewFunctionalCaseMapper.updateStatus(request.getCaseId(), request.getReviewId(), functionalCaseStatus);
|
extCaseReviewFunctionalCaseMapper.updateStatus(request.getCaseId(), request.getReviewId(), functionalCaseStatus);
|
||||||
//更新用例评审状态(判断所有用例是否结束,false:进行中,true:已完成)
|
//更新用例评审状态(判断所有用例是否结束,false:进行中,true:已完成)
|
||||||
boolean completed = updateCaseReviewStatus(request.getCaseId(), request.getReviewId());
|
boolean completed = updateCaseReviewStatus(request.getReviewId());
|
||||||
//检查是否有@,发送@通知
|
//检查是否有@,发送@通知
|
||||||
if (StringUtils.isNotBlank(request.getNotifier())) {
|
if (StringUtils.isNotBlank(request.getNotifier())) {
|
||||||
List<String> relatedUsers = Arrays.asList(request.getNotifier().split(";"));
|
List<String> relatedUsers = Arrays.asList(request.getNotifier().split(";"));
|
||||||
|
@ -120,11 +118,10 @@ public class ReviewFunctionalCaseService {
|
||||||
/**
|
/**
|
||||||
* 更新用例评审自身的状态
|
* 更新用例评审自身的状态
|
||||||
*
|
*
|
||||||
* @param caseId 功能用例Id
|
|
||||||
* @param reviewId 用例评审Id
|
* @param reviewId 用例评审Id
|
||||||
* @return completed
|
* @return completed
|
||||||
*/
|
*/
|
||||||
private boolean updateCaseReviewStatus(String caseId, String reviewId) {
|
private boolean updateCaseReviewStatus(String reviewId) {
|
||||||
boolean completed = false;
|
boolean completed = false;
|
||||||
List<String> statusList = new ArrayList<>();
|
List<String> statusList = new ArrayList<>();
|
||||||
statusList.add(FunctionalCaseReviewStatus.UN_REVIEWED.toString());
|
statusList.add(FunctionalCaseReviewStatus.UN_REVIEWED.toString());
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package io.metersphere.functional.utils;
|
||||||
|
|
||||||
|
import io.metersphere.functional.event.CaseEventSource;
|
||||||
|
import io.metersphere.functional.listener.CaseEventListener;
|
||||||
|
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CaseListenerUtils {
|
||||||
|
|
||||||
|
public static void addListener(Map<String, Object> param, String message) {
|
||||||
|
CaseEventSource caseEventSource = CommonBeanFactory.getBean(CaseEventSource.class);
|
||||||
|
CaseEventListener caseEventListener = CommonBeanFactory.getBean(CaseEventListener.class);
|
||||||
|
if (caseEventSource != null) {
|
||||||
|
caseEventSource.addListener(event -> {
|
||||||
|
assert caseEventListener != null;
|
||||||
|
caseEventListener.onEvent(event);
|
||||||
|
});
|
||||||
|
caseEventSource.fireEvent("CASE_MANAGEMENT", message, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -301,6 +301,8 @@ public class CaseReviewControllerTests extends BaseTest {
|
||||||
List<String> userIdList = caseReviewFunctionalCaseUsers.stream().map(CaseReviewFunctionalCaseUser::getUserId).toList();
|
List<String> userIdList = caseReviewFunctionalCaseUsers.stream().map(CaseReviewFunctionalCaseUser::getUserId).toList();
|
||||||
Assertions.assertTrue(userIdList.contains("gyq_review_test"));
|
Assertions.assertTrue(userIdList.contains("gyq_review_test"));
|
||||||
Assertions.assertTrue(userIdList.contains("gyq_review_test2"));
|
Assertions.assertTrue(userIdList.contains("gyq_review_test2"));
|
||||||
|
List<CaseReview> caseReviews2 = getCaseReviews("创建评审更新1");
|
||||||
|
Assertions.assertTrue( caseReviews.get(0).getCaseCount()<caseReviews2.get(0).getCaseCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -96,6 +96,7 @@ public class CaseReviewFunctionalCaseControllerTests extends BaseTest {
|
||||||
this.requestPostWithOkAndReturn(BATCH_DELETE_URL, request);
|
this.requestPostWithOkAndReturn(BATCH_DELETE_URL, request);
|
||||||
request.setSelectIds(new ArrayList<>());
|
request.setSelectIds(new ArrayList<>());
|
||||||
request.setSelectAll(true);
|
request.setSelectAll(true);
|
||||||
|
request.setExcludeIds(Arrays.asList("TEST_FUNCTIONAL_CASE_ID_1"));
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put("customs", Arrays.asList(new LinkedHashMap() {{
|
map.put("customs", Arrays.asList(new LinkedHashMap() {{
|
||||||
put("id", "TEST_FIELD_ID");
|
put("id", "TEST_FIELD_ID");
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package io.metersphere.functional.controller;
|
||||||
|
|
||||||
|
import io.metersphere.functional.event.CaseEventSource;
|
||||||
|
import io.metersphere.sdk.listener.Event;
|
||||||
|
import io.metersphere.sdk.listener.EventListener;
|
||||||
|
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
public class EventSourceTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(0)
|
||||||
|
public void eventSourceTest() throws Exception {
|
||||||
|
// 注册所有监听源
|
||||||
|
LogUtils.info("初始化用例管理事件源");
|
||||||
|
CaseEventSource caseEventSource = CommonBeanFactory.getBean(CaseEventSource.class);
|
||||||
|
assert caseEventSource != null;
|
||||||
|
caseEventSource.addListener(new EventListener<Event>() {
|
||||||
|
@Override
|
||||||
|
public void onEvent(Event event) {
|
||||||
|
LogUtils.info("ExecEventListener: " + event.module() + ":" + event.message());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 触发事件
|
||||||
|
caseEventSource.fireEvent("CASE", "Event after removing the listener test.");
|
||||||
|
// 触发事件待参数
|
||||||
|
caseEventSource.fireEvent("CASE", "Event after removing the listener test.",new HashMap<>());
|
||||||
|
}
|
||||||
|
}
|
|
@ -196,6 +196,8 @@ public class FunctionalCaseTrashControllerTests extends BaseTest {
|
||||||
Assertions.assertNull(functionalCase4);
|
Assertions.assertNull(functionalCase4);
|
||||||
FunctionalCaseComment functionalCaseComment = functionalCaseCommentMapper.selectByPrimaryKey("trash_comment_id");
|
FunctionalCaseComment functionalCaseComment = functionalCaseCommentMapper.selectByPrimaryKey("trash_comment_id");
|
||||||
Assertions.assertNull(functionalCaseComment);
|
Assertions.assertNull(functionalCaseComment);
|
||||||
|
this.requestGetWithOk(URL_CASE_DELETE + "Trash_TEST_FUNCTIONAL_CASE_ID_GYQ");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,14 @@ VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID_f', 7, 'Trash_TEST_MOUDLE_ID_1', 'project
|
||||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||||
VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID_g', 8, 'Trash_TEST_MOUDLE_ID_1', 'project-case-trash-test-2', '100001', 'copy_测试多版本g', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'Trash_TEST_FUNCTIONAL_CASE_ID_f', 'UN_EXECUTED',true, b'0', b'1', 'gyq', 'gyq', '', 1698058347559, 1698058347559, NULL);
|
VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID_g', 8, 'Trash_TEST_MOUDLE_ID_1', 'project-case-trash-test-2', '100001', 'copy_测试多版本g', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'Trash_TEST_FUNCTIONAL_CASE_ID_f', 'UN_EXECUTED',true, b'0', b'1', 'gyq', 'gyq', '', 1698058347559, 1698058347559, NULL);
|
||||||
|
|
||||||
|
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||||
|
VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID_GYQ', 100, 'Trash_TEST_MOUDLE_ID', 'project-case-trash-test', '100001', '回收站测信', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'Trash_TEST_FUNCTIONAL_CASE_ID_GYQ', 'UN_EXECUTED', true, b'0', b'0', 'gyq', 'gyq', '', 1698058347559, 1698058347559, NULL);
|
||||||
|
|
||||||
|
INSERT INTO case_review_functional_case(id, review_id, case_id, status, create_time, create_user, update_time, pos)
|
||||||
|
VALUES ('Gyq_Review_Case_Id','Gyq_review_id', 'Trash_TEST_FUNCTIONAL_CASE_ID', 'PASS', 1698058347559, 'admin',1698058347559, 0);
|
||||||
|
|
||||||
|
INSERT INTO case_review(id, num, name, module_id, project_id, status, review_pass_rule, pos, start_time, end_time, case_count, pass_rate, tags, description, create_time, create_user, update_time, update_user)
|
||||||
|
VALUES ('Gyq_review_id', 10001, '用例评审1', 'Trash_TEST_MOUDLE_ID_1', 'project-case-trash-test', 'COMPLETE' , 'SINGLE', 0, 1698058347559, 1698058347559, 1, 100.00, null, null, 1698058347559, 'admin', 1698058347559, 'admin');
|
||||||
|
|
||||||
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID', 'gyq_custom_id1', '22');
|
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID', 'gyq_custom_id1', '22');
|
||||||
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID', 'gyq_custom_id2', '33');
|
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID', 'gyq_custom_id2', '33');
|
||||||
|
|
Loading…
Reference in New Issue