feat(功能用例): 关注/取消关注用例
This commit is contained in:
parent
7eabb3fe89
commit
46abc85a9f
|
@ -141,4 +141,6 @@ case_comment.case_is_null=Function use case does not exist
|
|||
case_comment.parent_id_is_null=The comment id of the current reply is empty
|
||||
case_comment.parent_case_is_null=The comment currently being replied to does not exist
|
||||
case_comment.reply_user_is_null=The user who replied is empty
|
||||
case_comment.id_is_null=The current comment id is empty
|
||||
case_comment.id_is_null=The current comment id is empty
|
||||
un_follow_functional_case=unfollow functional case
|
||||
follow_functional_case=followed functional case
|
|
@ -141,4 +141,6 @@ case_comment.case_is_null=功能用例不存在
|
|||
case_comment.parent_id_is_null=当前回复的评论id为空
|
||||
case_comment.parent_case_is_null=当前回复的评论不存在
|
||||
case_comment.reply_user_is_null=回复的用户为空
|
||||
case_comment.id_is_null=当前评论id为空
|
||||
case_comment.id_is_null=当前评论id为空
|
||||
un_follow_functional_case=取消关注用例
|
||||
follow_functional_case=关注用例
|
|
@ -141,4 +141,6 @@ case_comment.case_is_null=功能用例不存在
|
|||
case_comment.parent_id_is_null=目前回覆的評論id為空
|
||||
case_comment.parent_case_is_null=目前回應的評論不存在
|
||||
case_comment.reply_user_is_null=回覆的用戶為空
|
||||
case_comment.id_is_null=目前評論id為空
|
||||
case_comment.id_is_null=目前評論id為空
|
||||
un_follow_functional_case=取消關注用例
|
||||
follow_functional_case=關注用例
|
|
@ -4,6 +4,8 @@ import io.metersphere.functional.domain.FunctionalCase;
|
|||
import io.metersphere.functional.dto.FunctionalCaseDetailDTO;
|
||||
import io.metersphere.functional.request.FunctionalCaseAddRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseEditRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseFollowerRequest;
|
||||
import io.metersphere.functional.service.FunctionalCaseLogService;
|
||||
import io.metersphere.functional.service.FunctionalCaseService;
|
||||
import io.metersphere.project.service.ProjectTemplateService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
|
@ -15,6 +17,7 @@ import io.metersphere.system.utils.SessionUtils;
|
|||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -50,7 +53,7 @@ public class FunctionalCaseController {
|
|||
@PostMapping("/add")
|
||||
@Operation(summary = "功能用例-新增用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_ADD)
|
||||
@Log(type = OperationLogType.ADD, expression = "#msClass.addFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseService.class)
|
||||
@Log(type = OperationLogType.ADD, expression = "#msClass.addFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseLogService.class)
|
||||
public FunctionalCase addFunctionalCase(@Validated @RequestPart("request") FunctionalCaseAddRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> files) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
return functionalCaseService.addFunctionalCase(request, files, userId);
|
||||
|
@ -68,9 +71,27 @@ public class FunctionalCaseController {
|
|||
@PostMapping("/update")
|
||||
@Operation(summary = "功能用例-更新用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
|
||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseService.class)
|
||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseLogService.class)
|
||||
public FunctionalCase updateFunctionalCase(@Validated @RequestPart("request") FunctionalCaseEditRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> files) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
return functionalCaseService.updateFunctionalCase(request, files, userId);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/edit/follower")
|
||||
@Operation(summary = "功能用例-关注/取消关注用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
|
||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.editFollower(#request)", msClass = FunctionalCaseLogService.class)
|
||||
public void editFollower(@Validated @RequestBody FunctionalCaseFollowerRequest request) {
|
||||
functionalCaseService.editFollower(request.getFunctionalCaseId(), request.getUserId());
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/follower/{functionalCaseId}")
|
||||
@Operation(summary = "功能用例-获取用例关注人")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
|
||||
public List<String> getFollower(@PathVariable @NotBlank(message = "{functional_case.id.not_blank}") String functionalCaseId) {
|
||||
return functionalCaseService.getFollower(functionalCaseId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package io.metersphere.functional.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author wx
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FunctionalCaseFollowerRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "用户id")
|
||||
@NotBlank(message = "{user_id.not_blank}")
|
||||
private String userId;
|
||||
|
||||
@Schema(description = "用例id")
|
||||
@NotBlank(message = "{functional_case.id.not_blank}")
|
||||
private String functionalCaseId;
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package io.metersphere.functional.service;
|
||||
|
||||
import io.metersphere.functional.domain.FunctionalCaseFollower;
|
||||
import io.metersphere.functional.domain.FunctionalCaseFollowerExample;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseFollowerMapper;
|
||||
import io.metersphere.functional.request.FunctionalCaseAddRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseEditRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseFollowerRequest;
|
||||
import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.log.constants.OperationLogModule;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.log.dto.LogDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wx
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class FunctionalCaseLogService {
|
||||
|
||||
@Resource
|
||||
private FunctionalCaseFollowerMapper functionalCaseFollowerMapper;
|
||||
|
||||
|
||||
//TODO 日志(需要修改)
|
||||
|
||||
/**
|
||||
* 新增用例 日志
|
||||
*
|
||||
* @param requests
|
||||
* @param files
|
||||
* @return
|
||||
*/
|
||||
public LogDTO addFunctionalCaseLog(FunctionalCaseAddRequest requests, List<MultipartFile> files) {
|
||||
LogDTO dto = new LogDTO(
|
||||
requests.getProjectId(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
OperationLogType.ADD.name(),
|
||||
OperationLogModule.FUNCTIONAL_CASE,
|
||||
requests.getName());
|
||||
|
||||
dto.setPath("/functional/case/add");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(requests));
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新用例 日志
|
||||
*
|
||||
* @param requests
|
||||
* @param files
|
||||
* @return
|
||||
*/
|
||||
public LogDTO updateFunctionalCaseLog(FunctionalCaseEditRequest requests, List<MultipartFile> files) {
|
||||
//TODO 获取原值
|
||||
LogDTO dto = new LogDTO(
|
||||
requests.getProjectId(),
|
||||
null,
|
||||
requests.getId(),
|
||||
null,
|
||||
OperationLogType.UPDATE.name(),
|
||||
OperationLogModule.FUNCTIONAL_CASE,
|
||||
requests.getName());
|
||||
|
||||
dto.setPath("/functional/case/update");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setModifiedValue(JSON.toJSONBytes(requests));
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 关注取消关注日志
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public LogDTO editFollower(FunctionalCaseFollowerRequest request) {
|
||||
FunctionalCaseFollowerExample example = new FunctionalCaseFollowerExample();
|
||||
example.createCriteria().andCaseIdEqualTo(request.getFunctionalCaseId()).andUserIdEqualTo(request.getUserId());
|
||||
List<FunctionalCaseFollower> caseFollowers = functionalCaseFollowerMapper.selectByExample(example);
|
||||
String content = "";
|
||||
if (CollectionUtils.isNotEmpty(caseFollowers)) {
|
||||
content = Translator.get("un_follow_functional_case");
|
||||
} else {
|
||||
content = Translator.get("follow_functional_case");
|
||||
}
|
||||
LogDTO dto = new LogDTO(
|
||||
null,
|
||||
null,
|
||||
request.getFunctionalCaseId(),
|
||||
request.getUserId(),
|
||||
OperationLogType.UPDATE.name(),
|
||||
OperationLogModule.FUNCTIONAL_CASE,
|
||||
content);
|
||||
dto.setPath("/functional/case/follower/" + request.getFunctionalCaseId());
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
return dto;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
package io.metersphere.functional.service;
|
||||
|
||||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.functional.domain.FunctionalCaseAttachment;
|
||||
import io.metersphere.functional.domain.FunctionalCaseBlob;
|
||||
import io.metersphere.functional.domain.FunctionalCaseCustomField;
|
||||
import io.metersphere.functional.domain.*;
|
||||
import io.metersphere.functional.dto.CaseCustomsFieldDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseDetailDTO;
|
||||
import io.metersphere.functional.mapper.ExtFunctionalCaseMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseBlobMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseFollowerMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||
import io.metersphere.functional.request.FunctionalCaseAddRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseEditRequest;
|
||||
|
@ -16,16 +14,13 @@ import io.metersphere.project.service.ProjectTemplateService;
|
|||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.MsFileUtils;
|
||||
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
|
||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||
import io.metersphere.system.file.FileRequest;
|
||||
import io.metersphere.system.file.MinioRepository;
|
||||
import io.metersphere.system.log.constants.OperationLogModule;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.log.dto.LogDTO;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.uid.NumGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -33,8 +28,11 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author wx
|
||||
|
@ -66,6 +64,8 @@ public class FunctionalCaseService {
|
|||
@Resource
|
||||
private ProjectTemplateService projectTemplateService;
|
||||
|
||||
@Resource
|
||||
private FunctionalCaseFollowerMapper functionalCaseFollowerMapper;
|
||||
|
||||
public FunctionalCase addFunctionalCase(FunctionalCaseAddRequest request, List<MultipartFile> files, String userId) {
|
||||
String caseId = IDGenerator.nextStr();
|
||||
|
@ -119,13 +119,9 @@ public class FunctionalCaseService {
|
|||
}
|
||||
|
||||
public int getNextNum(String projectId) {
|
||||
//TODO 获取下一个num方法(暂时直接查询数据库)
|
||||
FunctionalCase testCase = extFunctionalCaseMapper.getMaxNumByProjectId(projectId);
|
||||
if (testCase == null || testCase.getNum() == null) {
|
||||
return 100001;
|
||||
} else {
|
||||
return Optional.ofNullable(testCase.getNum() + 1).orElse(100001);
|
||||
}
|
||||
long nextNum = NumGenerator.nextNum(projectId, ApplicationNumScope.CASE_MANAGEMENT);
|
||||
BigDecimal bigDecimal = new BigDecimal(nextNum);
|
||||
return bigDecimal.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,53 +263,42 @@ public class FunctionalCaseService {
|
|||
}
|
||||
|
||||
|
||||
|
||||
//TODO 日志
|
||||
/**
|
||||
* 新增用例 日志
|
||||
* 关注/取消关注用例
|
||||
*
|
||||
* @param requests
|
||||
* @param files
|
||||
* @return
|
||||
* @param functionalCaseId
|
||||
* @param userId
|
||||
*/
|
||||
public LogDTO addFunctionalCaseLog(FunctionalCaseAddRequest requests, List<MultipartFile> files) {
|
||||
LogDTO dto = new LogDTO(
|
||||
requests.getProjectId(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
OperationLogType.ADD.name(),
|
||||
OperationLogModule.FUNCTIONAL_CASE,
|
||||
requests.getName());
|
||||
|
||||
dto.setPath("/functional/case/add");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(requests));
|
||||
return dto;
|
||||
public void editFollower(String functionalCaseId, String userId) {
|
||||
FunctionalCaseFollowerExample example = new FunctionalCaseFollowerExample();
|
||||
example.createCriteria().andCaseIdEqualTo(functionalCaseId).andUserIdEqualTo(userId);
|
||||
if (functionalCaseFollowerMapper.countByExample(example) > 0) {
|
||||
functionalCaseFollowerMapper.deleteByPrimaryKey(functionalCaseId, userId);
|
||||
} else {
|
||||
FunctionalCaseFollower functionalCaseFollower = new FunctionalCaseFollower();
|
||||
functionalCaseFollower.setCaseId(functionalCaseId);
|
||||
functionalCaseFollower.setUserId(userId);
|
||||
functionalCaseFollowerMapper.insert(functionalCaseFollower);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新用例 日志
|
||||
* 获取用例关注人
|
||||
*
|
||||
* @param requests
|
||||
* @param files
|
||||
* @param functionalCaseId
|
||||
* @return
|
||||
*/
|
||||
public LogDTO updateFunctionalCaseLog(FunctionalCaseAddRequest requests, List<MultipartFile> files) {
|
||||
//TODO 获取原值
|
||||
LogDTO dto = new LogDTO(
|
||||
requests.getProjectId(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
OperationLogType.UPDATE.name(),
|
||||
OperationLogModule.FUNCTIONAL_CASE,
|
||||
requests.getName());
|
||||
|
||||
dto.setPath("/functional/case/update");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setModifiedValue(JSON.toJSONBytes(requests));
|
||||
return dto;
|
||||
public List<String> getFollower(String functionalCaseId) {
|
||||
FunctionalCaseFollowerExample example = new FunctionalCaseFollowerExample();
|
||||
example.createCriteria().andCaseIdEqualTo(functionalCaseId);
|
||||
List<FunctionalCaseFollower> caseFollowers = functionalCaseFollowerMapper.selectByExample(example);
|
||||
List<String> followers = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(caseFollowers)) {
|
||||
followers = caseFollowers.stream().map(FunctionalCaseFollower::getUserId).distinct().collect(Collectors.toList());
|
||||
}
|
||||
return followers;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.functional.controller;
|
|||
import io.metersphere.functional.dto.CaseCustomsFieldDTO;
|
||||
import io.metersphere.functional.request.FunctionalCaseAddRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseEditRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseFollowerRequest;
|
||||
import io.metersphere.functional.result.FunctionalCaseResultCode;
|
||||
import io.metersphere.functional.utils.FileBaseUtils;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
|
@ -33,6 +34,8 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
public static final String DEFAULT_TEMPLATE_FIELD_URL = "/functional/case/default/template/field/";
|
||||
public static final String FUNCTIONAL_CASE_DETAIL_URL = "/functional/case/detail/";
|
||||
public static final String FUNCTIONAL_CASE_UPDATE_URL = "/functional/case/update";
|
||||
public static final String FUNCTIONAL_CASE_EDIT_FOLLOWER_URL = "/functional/case/edit/follower";
|
||||
public static final String FUNCTIONAL_CASE_FOLLOWER_URL = "/functional/case/follower/";
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
|
@ -167,4 +170,34 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
editRequest.setSteps("");
|
||||
return editRequest;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
public void testEditFollower() throws Exception {
|
||||
FunctionalCaseFollowerRequest functionalCaseFollowerRequest = new FunctionalCaseFollowerRequest();
|
||||
functionalCaseFollowerRequest.setFunctionalCaseId("TEST_FUNCTIONAL_CASE_ID");
|
||||
functionalCaseFollowerRequest.setUserId("admin");
|
||||
//关注
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_EDIT_FOLLOWER_URL, functionalCaseFollowerRequest);
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
//获取关注人
|
||||
MvcResult followerMvcResult = this.requestGetWithOkAndReturn(FUNCTIONAL_CASE_FOLLOWER_URL + "TEST_FUNCTIONAL_CASE_ID");
|
||||
String followerReturnData = followerMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder followerResultHolder = JSON.parseObject(followerReturnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(followerResultHolder);
|
||||
|
||||
//取消关注
|
||||
MvcResult editMvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_EDIT_FOLLOWER_URL, functionalCaseFollowerRequest);
|
||||
String editReturnData = editMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder editResultHolder = JSON.parseObject(editReturnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(editResultHolder);
|
||||
//获取关注人
|
||||
MvcResult editFollowerMvcResult = this.requestGetWithOkAndReturn(FUNCTIONAL_CASE_FOLLOWER_URL + "TEST_FUNCTIONAL_CASE_ID");
|
||||
String editFollowerReturnData = editFollowerMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder editFollowerResultHolder = JSON.parseObject(editFollowerReturnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(editFollowerResultHolder);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue