feat(用例评审): 新增删除用例评审接口
This commit is contained in:
parent
7e74da5316
commit
3a42e95796
|
@ -112,9 +112,18 @@ public class CaseReviewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("batch/move")
|
@PostMapping("batch/move")
|
||||||
@Operation(summary = "用例管理-用例评审-复制用例评审")
|
@Operation(summary = "用例管理-用例评审-批量移动用例评审")
|
||||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_UPDATE)
|
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_UPDATE)
|
||||||
public void batchMoveCaseReview(@Validated @RequestBody CaseReviewBatchRequest request) {
|
public void batchMoveCaseReview(@Validated @RequestBody CaseReviewBatchRequest request) {
|
||||||
caseReviewService.batchMoveCaseReview(request, SessionUtils.getUserId());
|
caseReviewService.batchMoveCaseReview(request, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/delete/{reviewId}/{projectId}")
|
||||||
|
@Operation(summary = "用例管理-用例评审-删除用例评审")
|
||||||
|
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_DELETE)
|
||||||
|
@SendNotice(taskType = NoticeConstants.TaskType.CASE_REVIEW_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getMainCaseReview(#reviewId)", targetClass = CaseReviewNoticeService.class)
|
||||||
|
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteFunctionalCaseLog(#reviewId)", msClass = CaseReviewLogService.class)
|
||||||
|
public void deleteCaseReview(@PathVariable String reviewId, @PathVariable String projectId) {
|
||||||
|
caseReviewService.deleteCaseReview(reviewId, projectId);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -103,6 +103,32 @@ public class CaseReviewLogService {
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除用例 日志
|
||||||
|
*
|
||||||
|
* @param reviewId reviewId
|
||||||
|
* @return LogDTO
|
||||||
|
*/
|
||||||
|
public LogDTO deleteFunctionalCaseLog(String reviewId) {
|
||||||
|
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(reviewId);
|
||||||
|
if (caseReview != null) {
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
caseReview.getProjectId(),
|
||||||
|
null,
|
||||||
|
caseReview.getId(),
|
||||||
|
null,
|
||||||
|
OperationLogType.DELETE.name(),
|
||||||
|
OperationLogModule.CASE_REVIEW,
|
||||||
|
caseReview.getName());
|
||||||
|
|
||||||
|
dto.setPath("/case/review/delete");
|
||||||
|
dto.setMethod(HttpMethodConstants.DELETE.name());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(caseReview));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<LogDTO> associateCaseLog(CaseReviewAssociateRequest request){
|
public List<LogDTO> associateCaseLog(CaseReviewAssociateRequest request){
|
||||||
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(request.getReviewId());
|
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(request.getReviewId());
|
||||||
if (caseReview ==null) {
|
if (caseReview ==null) {
|
||||||
|
|
|
@ -141,7 +141,7 @@ public class CaseReviewModuleService extends ModuleTreeService {
|
||||||
operationLogService.batchAdd(dtoList);
|
operationLogService.batchAdd(dtoList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CaseReview> deleteModuleByIds(List<String>deleteIds, List<CaseReview>caseReviews, String projectId){
|
public List<CaseReview> deleteModuleByIds(List<String> deleteIds, List<CaseReview> caseReviews, String projectId) {
|
||||||
if (CollectionUtils.isEmpty(deleteIds)) {
|
if (CollectionUtils.isEmpty(deleteIds)) {
|
||||||
return caseReviews;
|
return caseReviews;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ public class CaseReviewModuleService extends ModuleTreeService {
|
||||||
if (CollectionUtils.isNotEmpty(caseReviewList)) {
|
if (CollectionUtils.isNotEmpty(caseReviewList)) {
|
||||||
caseReviews.addAll(caseReviewList);
|
caseReviews.addAll(caseReviewList);
|
||||||
}
|
}
|
||||||
deleteCaseReviewService.deleteCaseReviewResource(deleteIds, projectId);
|
deleteCaseReviewService.deleteCaseReviewResource(deleteIds, projectId, false);
|
||||||
List<String> childrenIds = extCaseReviewModuleMapper.selectChildrenIdsByParentIds(deleteIds);
|
List<String> childrenIds = extCaseReviewModuleMapper.selectChildrenIdsByParentIds(deleteIds);
|
||||||
if (CollectionUtils.isNotEmpty(childrenIds)) {
|
if (CollectionUtils.isNotEmpty(childrenIds)) {
|
||||||
deleteModuleByIds(childrenIds, caseReviews, projectId);
|
deleteModuleByIds(childrenIds, caseReviews, projectId);
|
||||||
|
@ -171,7 +171,6 @@ public class CaseReviewModuleService extends ModuleTreeService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找当前项目下模块每个节点对应的资源统计
|
* 查找当前项目下模块每个节点对应的资源统计
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public Map<String, Long> getModuleCountMap(String projectId, List<ModuleCountDTO> moduleCountDTOList) {
|
public Map<String, Long> getModuleCountMap(String projectId, List<ModuleCountDTO> moduleCountDTOList) {
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,10 @@ public class CaseReviewNoticeService {
|
||||||
return caseReview;
|
return caseReview;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CaseReview getMainCaseReview(String reviewId){
|
||||||
|
return caseReviewMapper.selectByPrimaryKey(reviewId);
|
||||||
|
}
|
||||||
|
|
||||||
public Long getNextPos(String projectId) {
|
public Long getNextPos(String projectId) {
|
||||||
Long pos = extCaseReviewMapper.getPos(projectId);
|
Long pos = extCaseReviewMapper.getPos(projectId);
|
||||||
return (pos == null ? 0 : pos) + 5000;
|
return (pos == null ? 0 : pos) + 5000;
|
||||||
|
|
|
@ -69,6 +69,8 @@ public class CaseReviewService {
|
||||||
private ExtCaseReviewUserMapper extCaseReviewUserMapper;
|
private ExtCaseReviewUserMapper extCaseReviewUserMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private FunctionalCaseMapper functionalCaseMapper;
|
private FunctionalCaseMapper functionalCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private DeleteCaseReviewService deleteCaseReviewService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -516,4 +518,9 @@ public class CaseReviewService {
|
||||||
extCaseReviewMapper.batchMoveModule(request, ids, userId);
|
extCaseReviewMapper.batchMoveModule(request, ids, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteCaseReview(String reviewId, String projectId) {
|
||||||
|
deleteCaseReviewService.deleteCaseReviewResource(List.of(reviewId), projectId, false);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -30,7 +30,7 @@ public class CleanupCaseReviewResourceService implements CleanupProjectResourceS
|
||||||
List<CaseReview> caseReviews = caseReviewMapper.selectByExample(caseReviewExample);
|
List<CaseReview> caseReviews = caseReviewMapper.selectByExample(caseReviewExample);
|
||||||
List<String> ids = caseReviews.stream().map(CaseReview::getId).toList();
|
List<String> ids = caseReviews.stream().map(CaseReview::getId).toList();
|
||||||
if (CollectionUtils.isNotEmpty(ids)) {
|
if (CollectionUtils.isNotEmpty(ids)) {
|
||||||
deleteCaseReviewService.deleteCaseReviewResource(ids, projectId);
|
deleteCaseReviewService.deleteCaseReviewResource(ids, projectId, true);
|
||||||
}
|
}
|
||||||
//删除模块
|
//删除模块
|
||||||
CaseReviewModuleExample caseReviewModuleExample = new CaseReviewModuleExample();
|
CaseReviewModuleExample caseReviewModuleExample = new CaseReviewModuleExample();
|
||||||
|
|
|
@ -28,28 +28,31 @@ public class DeleteCaseReviewService {
|
||||||
@Resource
|
@Resource
|
||||||
private CaseReviewHistoryMapper caseReviewHistoryMapper;
|
private CaseReviewHistoryMapper caseReviewHistoryMapper;
|
||||||
|
|
||||||
public void deleteCaseReviewResource(List<String> ids, String projectId) {
|
public void deleteCaseReviewResource(List<String> ids, String projectId, boolean deleteAll) {
|
||||||
//TODO 删除各种关联关系? 1.关联用例(功能/接口/场景/ui/性能)? 2.评审和评审人 3. 归档的用例 4. 关注人 5.评审历史 6. 操作记录
|
//TODO 删除各种关联关系? 1.关联用例(功能/接口/场景/ui/性能)? 2.评审和评审人 3. 归档的用例 4. 关注人 5.评审历史 6. 操作记录
|
||||||
//1.刪除评审与功能用例关联关系
|
//1.刪除评审与功能用例关联关系
|
||||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
if (deleteAll) {
|
||||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdIn(ids);
|
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||||
caseReviewFunctionalCaseMapper.deleteByExample(caseReviewFunctionalCaseExample);
|
caseReviewFunctionalCaseExample.createCriteria().andReviewIdIn(ids);
|
||||||
//2. 删除评审和评审人
|
caseReviewFunctionalCaseMapper.deleteByExample(caseReviewFunctionalCaseExample);
|
||||||
CaseReviewUserExample caseReviewUserExample = new CaseReviewUserExample();
|
//2. 删除评审和评审人
|
||||||
caseReviewUserExample.createCriteria().andReviewIdIn(ids);
|
CaseReviewUserExample caseReviewUserExample = new CaseReviewUserExample();
|
||||||
caseReviewUserMapper.deleteByExample(caseReviewUserExample);
|
caseReviewUserExample.createCriteria().andReviewIdIn(ids);
|
||||||
//3. 删除归档的用例
|
caseReviewUserMapper.deleteByExample(caseReviewUserExample);
|
||||||
CaseReviewFunctionalCaseArchiveExample archiveExample = new CaseReviewFunctionalCaseArchiveExample();
|
//3. 删除归档的用例
|
||||||
archiveExample.createCriteria().andReviewIdIn(ids);
|
CaseReviewFunctionalCaseArchiveExample archiveExample = new CaseReviewFunctionalCaseArchiveExample();
|
||||||
caseReviewFunctionalCaseArchiveMapper.deleteByExample(archiveExample);
|
archiveExample.createCriteria().andReviewIdIn(ids);
|
||||||
|
caseReviewFunctionalCaseArchiveMapper.deleteByExample(archiveExample);
|
||||||
|
//5.删除评审历史
|
||||||
|
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
|
||||||
|
caseReviewHistoryExample.createCriteria().andReviewIdIn(ids);
|
||||||
|
caseReviewHistoryMapper.deleteByExample(caseReviewHistoryExample);
|
||||||
|
}
|
||||||
//4.删除关注人
|
//4.删除关注人
|
||||||
CaseReviewFollowerExample caseReviewFollowerExample = new CaseReviewFollowerExample();
|
CaseReviewFollowerExample caseReviewFollowerExample = new CaseReviewFollowerExample();
|
||||||
caseReviewFollowerExample.createCriteria().andReviewIdIn(ids);
|
caseReviewFollowerExample.createCriteria().andReviewIdIn(ids);
|
||||||
caseReviewFollowerMapper.deleteByExample(caseReviewFollowerExample);
|
caseReviewFollowerMapper.deleteByExample(caseReviewFollowerExample);
|
||||||
//5.删除评审历史
|
|
||||||
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
|
|
||||||
caseReviewHistoryExample.createCriteria().andReviewIdIn(ids);
|
|
||||||
caseReviewHistoryMapper.deleteByExample(caseReviewHistoryExample);
|
|
||||||
//TODO: 6.删除操作记录
|
//TODO: 6.删除操作记录
|
||||||
//删除评审
|
//删除评审
|
||||||
CaseReviewExample caseReviewExample = new CaseReviewExample();
|
CaseReviewExample caseReviewExample = new CaseReviewExample();
|
||||||
|
|
|
@ -22,12 +22,14 @@ import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class FunctionalCaseNoticeService {
|
public class FunctionalCaseNoticeService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -10,6 +10,7 @@ import io.metersphere.functional.result.CaseManagementResultCode;
|
||||||
import io.metersphere.project.domain.Notification;
|
import io.metersphere.project.domain.Notification;
|
||||||
import io.metersphere.project.domain.NotificationExample;
|
import io.metersphere.project.domain.NotificationExample;
|
||||||
import io.metersphere.project.mapper.NotificationMapper;
|
import io.metersphere.project.mapper.NotificationMapper;
|
||||||
|
import io.metersphere.sdk.constants.SessionConstants;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.system.base.BaseTest;
|
import io.metersphere.system.base.BaseTest;
|
||||||
import io.metersphere.system.controller.handler.ResultHolder;
|
import io.metersphere.system.controller.handler.ResultHolder;
|
||||||
|
@ -23,16 +24,19 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
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 org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.jdbc.Sql;
|
import org.springframework.test.context.jdbc.Sql;
|
||||||
import org.springframework.test.context.jdbc.SqlConfig;
|
import org.springframework.test.context.jdbc.SqlConfig;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@ -55,6 +59,8 @@ public class CaseReviewControllerTests extends BaseTest {
|
||||||
private static final String FOLLOW_CASE_REVIEW = "/case/review/edit/follower";
|
private static final String FOLLOW_CASE_REVIEW = "/case/review/edit/follower";
|
||||||
private static final String CASE_REVIEWER_LIST = "/case/review/user-option/";
|
private static final String CASE_REVIEWER_LIST = "/case/review/user-option/";
|
||||||
private static final String DETAIL_CASE_REVIEW = "/case/review/detail/";
|
private static final String DETAIL_CASE_REVIEW = "/case/review/detail/";
|
||||||
|
private static final String DELETE_CASE_REVIEW = "/case/review/delete/";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -464,7 +470,6 @@ public class CaseReviewControllerTests extends BaseTest {
|
||||||
Assertions.assertNotNull(resultHolder);
|
Assertions.assertNotNull(resultHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(15)
|
@Order(15)
|
||||||
public void testBatchMove() throws Exception {
|
public void testBatchMove() throws Exception {
|
||||||
|
@ -489,8 +494,17 @@ public class CaseReviewControllerTests extends BaseTest {
|
||||||
caseReviews = getCaseReviews("创建评审更新1");
|
caseReviews = getCaseReviews("创建评审更新1");
|
||||||
String moduleIdNewOne = caseReviews.get(0).getModuleId();
|
String moduleIdNewOne = caseReviews.get(0).getModuleId();
|
||||||
Assertions.assertTrue(StringUtils.equals(moduleIdNewOne, moduleIdNew));
|
Assertions.assertTrue(StringUtils.equals(moduleIdNewOne, moduleIdNew));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(16)
|
||||||
|
public void testDelete() throws Exception {
|
||||||
|
List<CaseReview> caseReviews = getCaseReviews("创建评审更新2");
|
||||||
|
delCaseReview(caseReviews.get(0).getId());
|
||||||
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
|
notificationExample.createCriteria().andResourceTypeEqualTo(NoticeConstants.TaskType.CASE_REVIEW_TASK).andResourceIdEqualTo(caseReviews.get(0).getId()).andOperationEqualTo("DELETE");
|
||||||
|
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||||
|
Assertions.assertEquals(1, notifications.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -503,4 +517,13 @@ public class CaseReviewControllerTests extends BaseTest {
|
||||||
map.put("reviewers", Map.of("operator", "in", "value", List.of("admin")));
|
map.put("reviewers", Map.of("operator", "in", "value", List.of("admin")));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void delCaseReview(String reviewId) throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get(DELETE_CASE_REVIEW+reviewId+"/"+projectId).header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
|
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||||
|
.header(SessionConstants.CURRENT_PROJECT, projectId)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,10 @@ Insert into message_task(id, event, receiver, project_robot_id, task_type, test_
|
||||||
VALUES ('case-review_message3', 'DELETE', 'CREATE_USER', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_delete');
|
VALUES ('case-review_message3', 'DELETE', 'CREATE_USER', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_delete');
|
||||||
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message3', 'message.case_review_task_delete');
|
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message3', 'message.case_review_task_delete');
|
||||||
|
|
||||||
|
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||||
|
VALUES ('case-review_message7', 'DELETE', 'gyq_review_test2', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_delete');
|
||||||
|
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message7', 'message.case_review_task_delete');
|
||||||
|
|
||||||
|
|
||||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||||
VALUES ('case-review_message4', 'REVIEW_COMPLETED', 'CREATE_USER', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_review_completed');
|
VALUES ('case-review_message4', 'REVIEW_COMPLETED', 'CREATE_USER', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_review_completed');
|
||||||
|
|
Loading…
Reference in New Issue