feat(功能用例): 获取评论接口
This commit is contained in:
parent
588da5a530
commit
7eabb3fe89
|
@ -213,6 +213,7 @@ public class PermissionConstants {
|
|||
/*------ start: FUNCTIONAL_CASE ------*/
|
||||
public static final String FUNCTIONAL_CASE_READ = "FUNCTIONAL_CASE:READ";
|
||||
public static final String FUNCTIONAL_CASE_READ_ADD = "FUNCTIONAL_CASE:READ+ADD";
|
||||
public static final String FUNCTIONAL_CASE_COMMENT_READ = "FUNCTIONAL_CASE_COMMENT:READ";
|
||||
public static final String FUNCTIONAL_CASE_READ_UPDATE = "FUNCTIONAL_CASE:READ+UPDATE";
|
||||
public static final String FUNCTIONAL_CASE_COMMENT_READ_ADD = "FUNCTIONAL_CASE_COMMENT:READ+ADD";
|
||||
public static final String FUNCTIONAL_CASE_COMMENT_READ_DELETE = "FUNCTIONAL_CASE_COMMENT:READ+DELETE";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.metersphere.functional.controller;
|
||||
|
||||
import io.metersphere.functional.dto.CaseReviewDto;
|
||||
import io.metersphere.functional.dto.CaseReviewDTO;
|
||||
import io.metersphere.functional.service.CaseReviewService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -18,7 +18,7 @@ public class CaseReviewController {
|
|||
|
||||
|
||||
@GetMapping("/get/{id}")
|
||||
public CaseReviewDto get(@PathVariable String id) {
|
||||
public CaseReviewDTO get(@PathVariable String id) {
|
||||
return caseReviewService.get(id);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.functional.controller;
|
||||
|
||||
import io.metersphere.functional.domain.FunctionalCaseComment;
|
||||
import io.metersphere.functional.dto.FunctionalCaseCommentDTO;
|
||||
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
||||
import io.metersphere.functional.service.FunctionalCaseCommentService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
|
@ -13,6 +14,8 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "用例管理-功能用例-用例评论")
|
||||
@RestController
|
||||
@RequestMapping("/functional/case/comment")
|
||||
|
@ -34,4 +37,11 @@ public class FunctionalCaseCommentController {
|
|||
public void deleteComment(@PathVariable String commentId) {
|
||||
functionalCaseCommentService.deleteComment(commentId);
|
||||
}
|
||||
|
||||
@GetMapping("/get/list/{caseId}")
|
||||
@Operation(summary = "用例管理-功能用例-用例评论-获取用例评论")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_COMMENT_READ)
|
||||
public List<FunctionalCaseCommentDTO> getCommentList(@PathVariable String caseId) {
|
||||
return functionalCaseCommentService.getCommentList(caseId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@ package io.metersphere.functional.dto;
|
|||
|
||||
import io.metersphere.functional.domain.CaseReview;
|
||||
|
||||
public class CaseReviewDto extends CaseReview {
|
||||
public class CaseReviewDTO extends CaseReview {
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package io.metersphere.functional.dto;
|
||||
|
||||
import io.metersphere.functional.domain.FunctionalCaseComment;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class FunctionalCaseCommentDTO extends FunctionalCaseComment {
|
||||
|
||||
@Schema(description = "评论的人名")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "被回复的人名")
|
||||
private String replyUserName;
|
||||
|
||||
@Schema(description = "被回复的人头像")
|
||||
private String replyUserLogo;
|
||||
|
||||
@Schema(description = "该条评论下的所有回复数据")
|
||||
private List<FunctionalCaseCommentDTO> replies;
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package io.metersphere.functional.service;
|
||||
|
||||
|
||||
import io.metersphere.functional.dto.CaseReviewDto;
|
||||
import io.metersphere.functional.dto.CaseReviewDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
|
@ -13,8 +13,8 @@ import org.springframework.stereotype.Service;
|
|||
public class CaseReviewService {
|
||||
|
||||
|
||||
public CaseReviewDto get(String id) {
|
||||
CaseReviewDto caseReviewDto = new CaseReviewDto();
|
||||
public CaseReviewDTO get(String id) {
|
||||
CaseReviewDTO caseReviewDto = new CaseReviewDTO();
|
||||
return caseReviewDto;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,20 @@
|
|||
package io.metersphere.functional.service;
|
||||
|
||||
|
||||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.functional.domain.FunctionalCaseComment;
|
||||
import io.metersphere.functional.domain.FunctionalCaseCommentExample;
|
||||
import io.metersphere.functional.dto.CommentEnum;
|
||||
import io.metersphere.functional.dto.FunctionalCaseCommentDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseDTO;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseCommentMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.User;
|
||||
import io.metersphere.system.domain.UserExample;
|
||||
import io.metersphere.system.mapper.UserMapper;
|
||||
import io.metersphere.system.notice.NoticeModel;
|
||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||
|
@ -22,8 +26,13 @@ import org.apache.commons.beanutils.BeanMap;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author guoyuqi
|
||||
|
@ -55,7 +64,7 @@ public class FunctionalCaseCommentService {
|
|||
* @return FunctionalCaseComment
|
||||
*/
|
||||
public FunctionalCaseComment saveComment(FunctionalCaseCommentRequest functionalCaseCommentRequest, String userId) {
|
||||
checkCase(functionalCaseCommentRequest);
|
||||
checkCase(functionalCaseCommentRequest.getCaseId());
|
||||
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest, userId);
|
||||
if (StringUtils.equals(functionalCaseCommentRequest.getEvent(), NoticeConstants.Event.REPLY)) {
|
||||
return saveCommentWidthNotice(functionalCaseCommentRequest, functionalCaseComment, userId);
|
||||
|
@ -85,8 +94,8 @@ public class FunctionalCaseCommentService {
|
|||
return functionalCaseComment;
|
||||
}
|
||||
|
||||
private void checkCase(FunctionalCaseCommentRequest functionalCaseCommentRequest) {
|
||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
|
||||
private void checkCase(String caseId) {
|
||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(caseId);
|
||||
if (functionalCase == null) {
|
||||
throw new MSException(Translator.get("case_comment.case_is_null"));
|
||||
}
|
||||
|
@ -198,4 +207,84 @@ public class FunctionalCaseCommentService {
|
|||
functionalCaseCommentExample.createCriteria().andIdIn(commentIds);
|
||||
functionalCaseCommentMapper.deleteByExample(functionalCaseCommentExample);
|
||||
}
|
||||
|
||||
public List<FunctionalCaseCommentDTO> getCommentList(String caseId) {
|
||||
checkCase(caseId);
|
||||
//查询出当前用例下的所有数据
|
||||
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||
functionalCaseCommentExample.createCriteria().andCaseIdEqualTo(caseId);
|
||||
List<FunctionalCaseComment> functionalCaseComments = functionalCaseCommentMapper.selectByExampleWithBLOBs(functionalCaseCommentExample);
|
||||
List<String> userIds = getUserIds(functionalCaseComments);
|
||||
Map<String, User> userMap = getUserMap(userIds);
|
||||
return buildData(functionalCaseComments, userMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装需要返回前端的数据结构
|
||||
* @param functionalCaseComments 查出来的所有当前用例的评论信息
|
||||
* @param userMap 用户信息
|
||||
*/
|
||||
private List<FunctionalCaseCommentDTO> buildData(List<FunctionalCaseComment> functionalCaseComments, Map<String, User> userMap) {
|
||||
List<FunctionalCaseCommentDTO>list = new ArrayList<>();
|
||||
List<FunctionalCaseComment> rootList = functionalCaseComments.stream().filter(t -> StringUtils.isBlank(t.getParentId())).toList();
|
||||
List<FunctionalCaseComment> replyList = functionalCaseComments.stream().filter(t -> StringUtils.isNotBlank(t.getParentId())).toList();
|
||||
Map<String, List<FunctionalCaseComment>> commentMap = replyList.stream().collect(Collectors.groupingBy(FunctionalCaseComment::getParentId));
|
||||
for (FunctionalCaseComment functionalCaseComment : rootList) {
|
||||
FunctionalCaseCommentDTO functionalCaseCommentDTO = new FunctionalCaseCommentDTO();
|
||||
BeanUtils.copyBean(functionalCaseCommentDTO,functionalCaseComment);
|
||||
functionalCaseCommentDTO.setUserName(userMap.get(functionalCaseComment.getCreateUser()).getName());
|
||||
List<FunctionalCaseComment> replyComments = commentMap.get(functionalCaseComment.getId());
|
||||
if (CollectionUtils.isNotEmpty(replyComments)) {
|
||||
List<FunctionalCaseCommentDTO> replies = getReplies(userMap, functionalCaseComment, replyComments);
|
||||
functionalCaseCommentDTO.setReplies(replies);
|
||||
}
|
||||
list.add(functionalCaseCommentDTO);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<FunctionalCaseCommentDTO> getReplies(Map<String, User> userMap, FunctionalCaseComment functionalCaseComment, List<FunctionalCaseComment> replyComments) {
|
||||
List<FunctionalCaseCommentDTO> replies = new ArrayList<>();
|
||||
for (FunctionalCaseComment replyComment : replyComments) {
|
||||
FunctionalCaseCommentDTO functionalCaseCommentDTOReply = new FunctionalCaseCommentDTO();
|
||||
BeanUtils.copyBean(functionalCaseCommentDTOReply,replyComment);
|
||||
functionalCaseCommentDTOReply.setUserName(userMap.get(replyComment.getCreateUser()).getName());
|
||||
if (StringUtils.isBlank(replyComment.getReplyUser())) {
|
||||
functionalCaseCommentDTOReply.setReplyUserName(userMap.get(functionalCaseComment.getCreateUser()).getName());
|
||||
} else {
|
||||
functionalCaseCommentDTOReply.setReplyUserName(userMap.get(replyComment.getReplyUser()).getName());
|
||||
}
|
||||
replies.add(functionalCaseCommentDTOReply);
|
||||
}
|
||||
return replies.stream().sorted(Comparator.comparing(FunctionalCaseComment::getCreateTime).reversed()).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据userIds 获取user信息
|
||||
* @param userIds userIds
|
||||
* @return Map<String, User>
|
||||
*/
|
||||
private Map<String, User> getUserMap(List<String> userIds) {
|
||||
UserExample userExample = new UserExample();
|
||||
userExample.createCriteria().andIdIn(userIds);
|
||||
List<User> users = userMapper.selectByExample(userExample);
|
||||
return users.stream().collect(Collectors.toMap(User::getId, item -> item));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取评论里所有人员信息
|
||||
* @param functionalCaseComments 评论集合
|
||||
* @return List<String>userIds
|
||||
*/
|
||||
private static List<String> getUserIds(List<FunctionalCaseComment> functionalCaseComments) {
|
||||
List<String> userIds = new ArrayList<>(functionalCaseComments.stream().flatMap(functionalCaseComment -> Stream.of(functionalCaseComment.getCreateUser(), functionalCaseComment.getReplyUser())).toList());
|
||||
List<String> notifierList = functionalCaseComments.stream().map(FunctionalCaseComment::getNotifier).filter(StringUtils::isNotBlank).toList();
|
||||
for (String notifierStr : notifierList) {
|
||||
List<String> notifiers = Arrays.asList(notifierStr.split(";"));
|
||||
userIds.addAll(notifiers);
|
||||
}
|
||||
userIds = userIds.stream().distinct().toList();
|
||||
return userIds;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.jayway.jsonpath.JsonPath;
|
|||
import io.metersphere.functional.domain.FunctionalCaseComment;
|
||||
import io.metersphere.functional.domain.FunctionalCaseCommentExample;
|
||||
import io.metersphere.functional.domain.FunctionalCaseCustomField;
|
||||
import io.metersphere.functional.dto.FunctionalCaseCommentDTO;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseCommentMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
|
||||
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
||||
|
@ -61,6 +62,7 @@ public class FunctionalCaseCommentControllerTests {
|
|||
|
||||
public static final String SAVE_URL = "/functional/case/comment/save";
|
||||
public static final String DELETE_URL = "/functional/case/comment/delete/";
|
||||
public static final String GET_URL = "/functional/case/comment/get/list/";
|
||||
|
||||
|
||||
private static String sessionId;
|
||||
|
@ -345,6 +347,33 @@ public class FunctionalCaseCommentControllerTests {
|
|||
|
||||
@Test
|
||||
@Order(13)
|
||||
public void getCommentSuccess() throws Exception {
|
||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(GET_URL + "xiaomeinvGTest").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();
|
||||
String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
|
||||
List<FunctionalCaseCommentDTO> list = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), FunctionalCaseCommentDTO.class);
|
||||
System.out.println(JSON.toJSONString(list));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(14)
|
||||
public void getCommentFalse() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(GET_URL + "xiaomeinvGTestNo").header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||
.header(SessionConstants.CURRENT_PROJECT, projectId)
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().is5xxServerError())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(15)
|
||||
public void deleteCommentSuccess() throws Exception {
|
||||
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||
functionalCaseCommentExample.createCriteria().andCaseIdEqualTo("xiaomeinvGTest").andNotifierEqualTo("default-project-member-user-guo;default-project-member-user-guo-4;");
|
||||
|
@ -363,7 +392,7 @@ public class FunctionalCaseCommentControllerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Order(14)
|
||||
@Order(16)
|
||||
public void deleteNoCommentSuccess() throws Exception {
|
||||
delFunctionalCaseComment("no_comment");
|
||||
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||
|
@ -375,6 +404,19 @@ public class FunctionalCaseCommentControllerTests {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(17)
|
||||
public void deleteCommentFirstSuccess() throws Exception {
|
||||
delFunctionalCaseComment("xiaomeinvGTest");
|
||||
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||
functionalCaseCommentExample.createCriteria().andParentIdEqualTo("xiaomeinvGTest");
|
||||
List<FunctionalCaseComment> functionalCaseComments1 = functionalCaseCommentMapper.selectByExample(functionalCaseCommentExample);
|
||||
Assertions.assertTrue(functionalCaseComments1.isEmpty());
|
||||
FunctionalCaseComment functionalCaseComment = functionalCaseCommentMapper.selectByPrimaryKey("xiaomeinvGTest");
|
||||
Assertions.assertNull(functionalCaseComment);
|
||||
|
||||
}
|
||||
|
||||
private FunctionalCaseComment getFunctionalCaseComment(FunctionalCaseCommentRequest functionalCaseCommentRequest) throws Exception {
|
||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(SAVE_URL).header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||
|
|
|
@ -70,6 +70,7 @@ VALUES (UUID(), 'default-project-member-user-guo', 'project_admin', '10000110000
|
|||
INSERT INTO user_role_permission(id, role_id, permission_id)
|
||||
VALUES ('user_role_guo_permission1', 'project_admin', 'FUNCTIONAL_CASE_COMMENT:READ+ADD'),
|
||||
('user_role_guo_permission2', 'project_admin', 'FUNCTIONAL_CASE_COMMENT:READ+DELETE'),
|
||||
('user_role_guo_permission3', 'project_admin', 'FUNCTIONAL_CASE:READ+ADD');
|
||||
('user_role_guo_permission3', 'project_admin', 'FUNCTIONAL_CASE:READ+ADD'),
|
||||
('user_role_guo_permission4', 'project_admin', 'FUNCTIONAL_CASE_COMMENT:READ');
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue