feat(测试跟踪): 测试计划和评审评论改造

--story=1008184 --user=陈建星 测试计划优化 https://www.tapd.cn/55049933/s/1198664
This commit is contained in:
chenjianxing 2022-07-13 19:04:37 +08:00 committed by jianxing
parent ab79efcdf2
commit db13582205
24 changed files with 676 additions and 411 deletions

View File

@ -17,6 +17,8 @@ public class TestCaseComment implements Serializable {
private String status;
private String type;
private String description;
private static final long serialVersionUID = 1L;

View File

@ -503,6 +503,76 @@ public class TestCaseCommentExample {
addCriterion("`status` not between", value1, value2, "status");
return (Criteria) this;
}
public Criteria andTypeIsNull() {
addCriterion("`type` is null");
return (Criteria) this;
}
public Criteria andTypeIsNotNull() {
addCriterion("`type` is not null");
return (Criteria) this;
}
public Criteria andTypeEqualTo(String value) {
addCriterion("`type` =", value, "type");
return (Criteria) this;
}
public Criteria andTypeNotEqualTo(String value) {
addCriterion("`type` <>", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThan(String value) {
addCriterion("`type` >", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThanOrEqualTo(String value) {
addCriterion("`type` >=", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThan(String value) {
addCriterion("`type` <", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThanOrEqualTo(String value) {
addCriterion("`type` <=", value, "type");
return (Criteria) this;
}
public Criteria andTypeLike(String value) {
addCriterion("`type` like", value, "type");
return (Criteria) this;
}
public Criteria andTypeNotLike(String value) {
addCriterion("`type` not like", value, "type");
return (Criteria) this;
}
public Criteria andTypeIn(List<String> values) {
addCriterion("`type` in", values, "type");
return (Criteria) this;
}
public Criteria andTypeNotIn(List<String> values) {
addCriterion("`type` not in", values, "type");
return (Criteria) this;
}
public Criteria andTypeBetween(String value1, String value2) {
addCriterion("`type` between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andTypeNotBetween(String value1, String value2) {
addCriterion("`type` not between", value1, value2, "type");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -7,7 +7,8 @@
<result column="author" jdbcType="VARCHAR" property="author" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<result column="status" jdbcType="VARCHAR" property="status"/>
<result column="status" jdbcType="VARCHAR" property="status" />
<result column="type" jdbcType="VARCHAR" property="type" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.TestCaseComment">
<result column="description" jdbcType="LONGVARCHAR" property="description" />
@ -71,7 +72,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, case_id, author, create_time, update_time, `status`
id, case_id, author, create_time, update_time, `status`, `type`
</sql>
<sql id="Blob_Column_List">
description
@ -125,12 +126,12 @@
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.TestCaseComment">
insert into test_case_comment (id, case_id, author,
create_time, update_time, `status`,
description)
values (#{id,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR}, #{author,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{status,jdbcType=VARCHAR},
#{description,jdbcType=LONGVARCHAR})
insert into test_case_comment (id, case_id, author,
create_time, update_time, `status`,
`type`, description)
values (#{id,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR}, #{author,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{status,jdbcType=VARCHAR},
#{type,jdbcType=VARCHAR}, #{description,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseComment">
insert into test_case_comment
@ -153,6 +154,9 @@
<if test="status != null">
`status`,
</if>
<if test="type != null">
`type`,
</if>
<if test="description != null">
description,
</if>
@ -176,6 +180,9 @@
<if test="status != null">
#{status,jdbcType=VARCHAR},
</if>
<if test="type != null">
#{type,jdbcType=VARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=LONGVARCHAR},
</if>
@ -208,6 +215,9 @@
<if test="record.status != null">
`status` = #{record.status,jdbcType=VARCHAR},
</if>
<if test="record.type != null">
`type` = #{record.type,jdbcType=VARCHAR},
</if>
<if test="record.description != null">
description = #{record.description,jdbcType=LONGVARCHAR},
</if>
@ -219,12 +229,13 @@
<update id="updateByExampleWithBLOBs" parameterType="map">
update test_case_comment
set id = #{record.id,jdbcType=VARCHAR},
case_id = #{record.caseId,jdbcType=VARCHAR},
author = #{record.author,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
`status` = #{record.status,jdbcType=VARCHAR},
description = #{record.description,jdbcType=LONGVARCHAR}
case_id = #{record.caseId,jdbcType=VARCHAR},
author = #{record.author,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
`status` = #{record.status,jdbcType=VARCHAR},
`type` = #{record.type,jdbcType=VARCHAR},
description = #{record.description,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -232,11 +243,12 @@
<update id="updateByExample" parameterType="map">
update test_case_comment
set id = #{record.id,jdbcType=VARCHAR},
case_id = #{record.caseId,jdbcType=VARCHAR},
author = #{record.author,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
`status` = #{record.status,jdbcType=VARCHAR}
case_id = #{record.caseId,jdbcType=VARCHAR},
author = #{record.author,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
`status` = #{record.status,jdbcType=VARCHAR},
`type` = #{record.type,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -259,6 +271,9 @@
<if test="status != null">
`status` = #{status,jdbcType=VARCHAR},
</if>
<if test="type != null">
`type` = #{type,jdbcType=VARCHAR},
</if>
<if test="description != null">
description = #{description,jdbcType=LONGVARCHAR},
</if>
@ -267,21 +282,23 @@
</update>
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.TestCaseComment">
update test_case_comment
set case_id = #{caseId,jdbcType=VARCHAR},
author = #{author,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
`status` = #{status,jdbcType=VARCHAR},
description = #{description,jdbcType=LONGVARCHAR}
set case_id = #{caseId,jdbcType=VARCHAR},
author = #{author,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
`status` = #{status,jdbcType=VARCHAR},
`type` = #{type,jdbcType=VARCHAR},
description = #{description,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.TestCaseComment">
update test_case_comment
set case_id = #{caseId,jdbcType=VARCHAR},
author = #{author,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
`status` = #{status,jdbcType=VARCHAR}
set case_id = #{caseId,jdbcType=VARCHAR},
author = #{author,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
`status` = #{status,jdbcType=VARCHAR},
`type` = #{type,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -12,6 +12,6 @@ public interface ExtTestCaseCommentMapper {
* @param caseId
* @return
*/
List<TestCaseCommentDTO> getCaseComments(@Param("caseId") String caseId);
List<TestCaseCommentDTO> getCaseComments(@Param("caseId") String caseId, @Param("type") String type);
}

View File

@ -6,9 +6,10 @@
parameterType="java.lang.String">
select *, user.name as authorName from test_case_comment, user
where test_case_comment.author = user.id and case_id = #{caseId}
<if test="type != null and type != ''">
and test_case_comment.type = #{type}
</if>
order by test_case_comment.update_time desc
</select>
</mapper>
</mapper>

View File

@ -0,0 +1,7 @@
package io.metersphere.commons.constants;
public enum TestCaseCommentType {
CASE,
REVIEW,
PLAN
}

View File

@ -16,7 +16,6 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
@RequestMapping("/test/case/comment")
@RestController
@ -31,13 +30,17 @@ public class TestCaseCommentController {
@SendNotice(taskType = NoticeConstants.TaskType.TRACK_TEST_CASE_TASK, target = "#targetClass.getTestCase(#request.caseId)", targetClass = TestCaseService.class,
event = NoticeConstants.Event.COMMENT, subject = "测试用例通知")
public TestCaseComment saveComment(@RequestBody SaveCommentRequest request) {
request.setId(UUID.randomUUID().toString());
return testCaseCommentService.saveComment(request);
}
@GetMapping("/list/{caseId}/{type}")
public List<TestCaseCommentDTO> getCaseComments(@PathVariable String caseId, @PathVariable String type) {
return testCaseCommentService.getCaseComments(caseId, type);
}
@GetMapping("/list/{caseId}")
public List<TestCaseCommentDTO> getCaseComments(@PathVariable String caseId) {
return testCaseCommentService.getCaseComments(caseId);
return testCaseCommentService.getCaseComments(caseId, null);
}
@GetMapping("/delete/{commentId}")

View File

@ -3,7 +3,6 @@ package io.metersphere.track.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.base.domain.Project;
import io.metersphere.base.domain.TestCaseComment;
import io.metersphere.base.domain.TestCaseReview;
import io.metersphere.base.domain.User;
import io.metersphere.commons.constants.NoticeConstants;
@ -152,15 +151,4 @@ public class TestCaseReviewController {
public void editTestFollows(@RequestBody SaveTestCaseReviewRequest testCaseReview) {
testCaseReviewService.editCaseRevieweFollow(testCaseReview);
}
@PostMapping("/comment/save")
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_REVIEW_READ_COMMENT)
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE_REVIEW, type = OperLogConstants.CREATE, content = "#msClass.getLogDetails(#request.id)", msClass = TestCaseCommentService.class)
@SendNotice(taskType = NoticeConstants.TaskType.REVIEW_TASK, target = "#targetClass.getTestReview(#request.reviewId)", targetClass = TestCaseReviewService.class,
event = NoticeConstants.Event.COMMENT, subject = "测试评审通知")
public TestCaseComment saveComment(@RequestBody SaveCommentRequest request) {
request.setId(UUID.randomUUID().toString());
return testCaseCommentService.saveComment(request);
}
}

View File

@ -13,6 +13,7 @@ import io.metersphere.track.dto.TestPlanCaseDTO;
import io.metersphere.track.request.testcase.TestPlanCaseBatchRequest;
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
import io.metersphere.track.request.testplancase.TestPlanFuncCaseBatchRequest;
import io.metersphere.track.request.testplancase.TestPlanFuncCaseEditRequest;
import io.metersphere.track.service.TestPlanTestCaseService;
import org.springframework.web.bind.annotation.*;
@ -106,7 +107,7 @@ public class TestPlanTestCaseController {
@PostMapping("/edit")
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE_REVIEW, type = OperLogConstants.UPDATE, content = "#msClass.getLogDetails(#testPlanTestCase.id)", msClass = TestPlanTestCaseService.class)
public void editTestCase(@RequestBody TestPlanTestCaseWithBLOBs testPlanTestCase) {
public void editTestCase(@RequestBody TestPlanFuncCaseEditRequest testPlanTestCase) {
testPlanTestCaseService.editTestCase(testPlanTestCase);
}

View File

@ -13,6 +13,7 @@ import io.metersphere.track.dto.TestReviewCaseDTO;
import io.metersphere.track.request.testplancase.TestReviewCaseBatchRequest;
import io.metersphere.track.request.testreview.DeleteRelevanceRequest;
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
import io.metersphere.track.request.testreview.TestCaseReviewTestCaseEditRequest;
import io.metersphere.track.service.TestReviewTestCaseService;
import org.springframework.web.bind.annotation.*;
@ -69,7 +70,7 @@ public class TestReviewTestCaseController {
@PostMapping("/edit")
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE_REVIEW, type = OperLogConstants.REVIEW, content = "#msClass.getLogDetails(#testCaseReviewTestCase)", msClass = TestReviewTestCaseService.class)
public void editTestCase(@RequestBody TestCaseReviewTestCase testCaseReviewTestCase) {
public void editTestCase(@RequestBody TestCaseReviewTestCaseEditRequest testCaseReviewTestCase) {
testReviewTestCaseService.editTestCase(testCaseReviewTestCase);
}

View File

@ -0,0 +1,11 @@
package io.metersphere.track.request.testplancase;
import io.metersphere.base.domain.TestPlanTestCaseWithBLOBs;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class TestPlanFuncCaseEditRequest extends TestPlanTestCaseWithBLOBs {
private String comment;
}

View File

@ -0,0 +1,11 @@
package io.metersphere.track.request.testreview;
import io.metersphere.base.domain.TestCaseReviewTestCase;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class TestCaseReviewTestCaseEditRequest extends TestCaseReviewTestCase {
private String comment;
}

View File

@ -6,16 +6,21 @@ import io.metersphere.base.mapper.TestCaseCommentMapper;
import io.metersphere.base.mapper.TestCaseMapper;
import io.metersphere.base.mapper.UserMapper;
import io.metersphere.base.mapper.ext.ExtTestCaseCommentMapper;
import io.metersphere.commons.constants.*;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.i18n.Translator;
import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.log.utils.ReflexObjectUtil;
import io.metersphere.log.vo.DetailColumn;
import io.metersphere.log.vo.OperatingLogDetails;
import io.metersphere.log.vo.track.TestCaseReviewReference;
import io.metersphere.notice.annotation.SendNotice;
import io.metersphere.track.dto.TestCaseCommentDTO;
import io.metersphere.track.request.testreview.SaveCommentRequest;
import io.metersphere.track.request.testreview.TestCaseReviewTestCaseEditRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -23,6 +28,7 @@ import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Service
@Transactional(rollbackFor = Exception.class)
@ -37,20 +43,41 @@ public class TestCaseCommentService {
private UserMapper userMapper;
public TestCaseComment saveComment(SaveCommentRequest request) {
TestCaseComment testCaseComment = new TestCaseComment();
testCaseComment.setId(request.getId());
testCaseComment.setAuthor(SessionUtils.getUser().getId());
testCaseComment.setCaseId(request.getCaseId());
testCaseComment.setCreateTime(System.currentTimeMillis());
testCaseComment.setUpdateTime(System.currentTimeMillis());
testCaseComment.setDescription(request.getDescription());
testCaseComment.setStatus(request.getStatus());
testCaseCommentMapper.insert(testCaseComment);
return testCaseComment;
request.setId(UUID.randomUUID().toString());
request.setAuthor(SessionUtils.getUser().getId());
request.setCreateTime(System.currentTimeMillis());
request.setUpdateTime(System.currentTimeMillis());
if (StringUtils.isBlank(request.getType())) {
request.setType(TestCaseCommentType.CASE.name());
}
testCaseCommentMapper.insert(request);
return request;
}
/**
* TestReviewTestCaseService 通知等会失效
* 需要走 Spring 的代理对象
* @param request
*/
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_REVIEW_READ_COMMENT)
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE_REVIEW, type = OperLogConstants.CREATE, content = "#msClass.getLogDetails(#request.id)", msClass = TestCaseCommentService.class)
@SendNotice(taskType = NoticeConstants.TaskType.REVIEW_TASK, target = "#targetClass.getTestReview(#request.reviewId)", targetClass = TestCaseReviewService.class,
event = NoticeConstants.Event.COMMENT, subject = "测试评审通知")
public void saveComment(TestCaseReviewTestCaseEditRequest request) {
SaveCommentRequest saveCommentRequest = new SaveCommentRequest();
saveCommentRequest.setCaseId(request.getCaseId());
saveCommentRequest.setDescription(request.getComment());
saveCommentRequest.setStatus(request.getStatus());
saveCommentRequest.setType(TestCaseCommentType.REVIEW.name());
saveComment(saveCommentRequest);
}
public List<TestCaseCommentDTO> getCaseComments(String caseId, String type) {
return extTestCaseCommentMapper.getCaseComments(caseId, type);
}
public List<TestCaseCommentDTO> getCaseComments(String caseId) {
return extTestCaseCommentMapper.getCaseComments(caseId);
return this.getCaseComments(caseId, null);
}
public void deleteCaseComment(String caseId) {

View File

@ -7,6 +7,7 @@ import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
import io.metersphere.commons.constants.IssueRefType;
import io.metersphere.commons.constants.ProjectApplicationType;
import io.metersphere.commons.constants.TestCaseCommentType;
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.commons.user.SessionUser;
import io.metersphere.commons.utils.*;
@ -26,6 +27,7 @@ import io.metersphere.track.request.testcase.TrackCount;
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
import io.metersphere.track.request.testplancase.TestPlanFuncCaseBatchRequest;
import io.metersphere.track.request.testplancase.TestPlanFuncCaseConditions;
import io.metersphere.track.request.testplancase.TestPlanFuncCaseEditRequest;
import io.metersphere.track.request.testreview.SaveCommentRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
@ -144,10 +146,8 @@ public class TestPlanTestCaseService {
return list;
}
public void editTestCase(TestPlanTestCaseWithBLOBs testPlanTestCase) {
if (StringUtils.equals(TestPlanTestCaseStatus.Prepare.name(), testPlanTestCase.getStatus())) {
testPlanTestCase.setStatus(TestPlanTestCaseStatus.Underway.name());
} else {
public void editTestCase(TestPlanFuncCaseEditRequest testPlanTestCase) {
if (!StringUtils.equals(TestPlanTestCaseStatus.Prepare.name(), testPlanTestCase.getStatus())) {
//记录功能用例执行信息
functionCaseExecutionInfoService.insertExecutionInfo(testPlanTestCase.getId(), testPlanTestCase.getStatus());
}
@ -156,6 +156,19 @@ public class TestPlanTestCaseService {
testPlanTestCase.setRemark(null);
testPlanTestCaseMapper.updateByPrimaryKeySelective(testPlanTestCase);
testCaseService.updateLastExecuteStatus(testPlanTestCase.getCaseId(), testPlanTestCase.getStatus());
saveComment(testPlanTestCase);
}
private void saveComment(TestPlanFuncCaseEditRequest testPlanTestCase) {
if (StringUtils.isNotEmpty(testPlanTestCase.getComment())) {
SaveCommentRequest saveCommentRequest = new SaveCommentRequest();
saveCommentRequest.setCaseId(testPlanTestCase.getCaseId());
saveCommentRequest.setDescription(testPlanTestCase.getComment());
saveCommentRequest.setStatus(testPlanTestCase.getStatus());
saveCommentRequest.setType(TestCaseCommentType.PLAN.name());
testCaseCommentService.saveComment(saveCommentRequest);
}
}
public int deleteTestCase(String id) {
@ -351,7 +364,7 @@ public class TestPlanTestCaseService {
SaveCommentRequest saveCommentRequest = new SaveCommentRequest();
saveCommentRequest.setCaseId(testPlanTestCase.getCaseId());
saveCommentRequest.setId(UUID.randomUUID().toString());
saveCommentRequest.setType(TestCaseCommentType.PLAN.name());
saveCommentRequest.setDescription("关联的测试:[" + testName + "]" + tip);
testCaseCommentService.saveComment(saveCommentRequest);
});
@ -458,7 +471,6 @@ public class TestPlanTestCaseService {
TestPlanUtils.addToReportStatusResultList(statusResultMap, statusResult, TestPlanTestCaseStatus.Blocking.name());
TestPlanUtils.addToReportStatusResultList(statusResultMap, statusResult, TestPlanTestCaseStatus.Skip.name());
TestPlanUtils.addToReportStatusResultList(statusResultMap, statusResult, TestPlanTestCaseStatus.Underway.name());
functionResult.setCaseData(statusResult);
}

View File

@ -20,6 +20,7 @@ import io.metersphere.track.dto.TestReviewCaseDTO;
import io.metersphere.track.request.testplancase.TestReviewCaseBatchRequest;
import io.metersphere.track.request.testreview.DeleteRelevanceRequest;
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
import io.metersphere.track.request.testreview.TestCaseReviewTestCaseEditRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@ -59,6 +60,8 @@ public class TestReviewTestCaseService {
TestCaseService testCaseService;
@Resource
ExtTestPlanTestCaseMapper extTestPlanTestCaseMapper;
@Resource
TestCaseCommentService testCaseCommentService;
public List<TestReviewCaseDTO> list(QueryCaseReviewRequest request) {
request.setOrders(ServiceUtils.getDefaultSortOrder(request.getOrders()));
@ -149,7 +152,7 @@ public class TestReviewTestCaseService {
testCaseReviewTestCaseMapper.deleteByExample(example);
}
public void editTestCase(TestCaseReviewTestCase testCaseReviewTestCase) {
public void editTestCase(TestCaseReviewTestCaseEditRequest testCaseReviewTestCase) {
checkReviewCase(testCaseReviewTestCase.getReviewId());
// 记录测试用例评审状态变更
@ -160,6 +163,11 @@ public class TestReviewTestCaseService {
// 修改用例评审状态
testCaseService.updateReviewStatus(testCaseReviewTestCase.getCaseId(), testCaseReviewTestCase.getStatus());
if (StringUtils.isNotEmpty(testCaseReviewTestCase.getComment())) {
// 走Spring的代理对象防止发送通知操作记录等操作失效
testCaseCommentService.saveComment(testCaseReviewTestCase);
}
}
public TestReviewCaseDTO get(String reviewId) {

View File

@ -1,6 +1,6 @@
<template>
<span>
<ms-tag v-if="value == 'Prepare'" type="info" :content="$t('test_track.plan.plan_status_prepare')"/>
<ms-tag v-if="value == 'Prepare'" type="info" :content="$t('test_track.plan.plan_status_prepare')" style="background-color: #D7D7D7; border-color: #D7D7D7"/>
<ms-tag v-else-if="value == 'Underway'" type="primary" :content="$t('test_track.plan.plan_status_running')"/>
<ms-tag v-else-if="value == 'Pass'" type="success" :content="$t('test_track.plan_view.pass')"/>
<ms-tag v-else-if="value == 'UnPass'" type="danger" :content="$t('test_track.plan_view.not_pass')"/>

View File

@ -1,27 +1,15 @@
<template>
<el-row type="flex" justify="start" :gutter="20" class="status-button">
<el-col>
<el-button :disabled="isReadOnly" type="success" round size="mini"
:icon="status == 'Pass' ? 'el-icon-check' : ''"
@click="setStatus('Pass')"> {{$t('test_track.plan_view.pass')}}
</el-button>
</el-col>
<el-col>
<el-button :disabled="isReadOnly" type="danger" round size="mini"
:icon="status == 'Failure' ? 'el-icon-check' : ''"
@click="setStatus('Failure')"> {{$t('test_track.plan_view.failure')}}
</el-button>
</el-col>
<el-col>
<el-button :disabled="isReadOnly" type="warning" round size="mini"
:icon="status == 'Blocking' ? 'el-icon-check' : ''"
@click="setStatus('Blocking')"> {{$t('test_track.plan_view.blocking')}}
</el-button>
</el-col>
<el-col>
<el-button :disabled="isReadOnly" type="info" round size="mini"
:icon="status == 'Skip' ? 'el-icon-check' : ''"
@click="setStatus('Skip')"> {{$t('test_track.plan_view.skip')}}
<el-col v-for="item in statusButtons"
:key="item.value">
<el-button
size="mini"
:disabled="isReadOnly"
:type="item.type"
:icon="status == item.value ? 'el-icon-check' : ''"
:style="item.style"
@click="setStatus(item.value)">
{{item.label}}
</el-button>
</el-col>
</el-row>
@ -39,6 +27,38 @@
default: false
}
},
data() {
return {
statusButtons: [
{
type: 'success',
value: 'Pass',
label: this.$t('test_track.plan_view.pass')
},
{
type: 'danger',
value: 'Failure',
label: this.$t('test_track.plan_view.failure')
},
{
type: 'warning',
value: 'Blocking',
label: this.$t('test_track.plan_view.blocking')
},
{
type: 'info',
value: 'Skip',
label: this.$t('test_track.plan_view.skip')
},
{
type: 'info',
value: 'Prepare',
label: this.$t('test_track.plan.plan_status_prepare'),
style: "background-color: #D7D7D7; border-color: #D7D7D7"
},
]
}
},
methods: {
setStatus(status) {
if (this.isReadOnly) {

View File

@ -34,11 +34,8 @@
:next-page-data="nextPageData"
:pre-page-data="prePageData"
@pre="handlePre"
@next="saveCase(true, true)"
@next="handleNext"
:list="testCases"/>
<el-button class="save-btn" type="primary" size="mini" :disabled="isReadOnly" @click="saveCase(true)">
{{$t('test_track.save')}} & {{$t('test_track.next')}}
</el-button>
</el-col>
</el-row>
@ -71,10 +68,9 @@
</el-form-item >
</el-col>
<el-col :span="10">
<test-plan-test-case-status-button class="status-button"
@statusChange="statusChange"
:is-read-only="statusReadOnly"
:status="testCase.status"/>
<el-form-item :label="$t('test_track.plan.load_case.execution_status')" :label-width="formLabelWidth">
<status-table-item :value="originalStatus"/>
</el-form-item >
</el-col>
</el-row>
@ -124,15 +120,15 @@
</el-col>
<el-col :span="7">
<div class="comment-card">
<el-card>
<template slot="header">
<span style="font-size: 15px; color: #1E90FF">{{ $t('test_track.review.comment') }}</span>
<i class="el-icon-refresh" @click="getComments(testCase)"
style="margin-left:10px;font-size: 14px; cursor: pointer"/>
</template>
<review-comment :comments="comments" :case-id="testCase.caseId" :review-id="testCase.reviewId"
@getComments="getComments"/>
</el-card>
<test-plan-functional-execute
:test-case="testCase"
:is-read-only="isReadOnly"
:origin-status="originalStatus"
@saveCase="saveCase()"/>
<review-comment
default-type="PLAN"
:case-id="testCase.caseId"
ref="comment"/>
</div>
</el-col>
</el-row>
@ -163,10 +159,15 @@ import StepChangeItem from "@/business/components/track/case/components/StepChan
import TestCaseStepItem from "@/business/components/track/case/components/TestCaseStepItem";
import TestPlanCaseStepResultsItem
from "@/business/components/track/plan/view/comonents/functional/TestPlanCaseStepResultsItem";
import TestPlanFunctionalExecute
from "@/business/components/track/plan/view/comonents/functional/TestPlanFunctionalExecute";
import StatusTableItem from "@/business/components/track/common/tableItems/planview/StatusTableItem";
export default {
name: "FunctionalTestCaseEdit",
components: {
StatusTableItem,
TestPlanFunctionalExecute,
TestPlanCaseStepResultsItem,
TestCaseStepItem,
StepChangeItem,
@ -192,10 +193,6 @@ export default {
testCase: {},
index: 0,
editor: ClassicEditor,
editorConfig: {
toolbar: ['heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'insertTable', '|', 'undo', 'redo'],
},
readConfig: {toolbar: []},
test: {},
activeTab: 'detail',
users: [],
@ -208,12 +205,12 @@ export default {
tableData: [],
comments: [],
testCaseTemplate: {},
formLabelWidth: "100px",
formLabelWidth: '100px',
isCustomFiledActive: false,
otherInfoActive: true,
isReadOnly: false,
testCases: [],
originalStatus: ""
originalStatus: ''
};
},
props: {
@ -238,25 +235,11 @@ export default {
systemNameMap() {
return SYSTEM_FIELD_NAME_MAP;
},
statusReadOnly() {
return !hasPermission('PROJECT_TRACK_PLAN:READ+RUN');
},
pageTotal() {
return Math.ceil(this.total / this.pageSize);
}
},
methods: {
getComments(testCase) {
let id = '';
if (testCase) {
id = testCase.caseId;
} else {
id = this.testCase.caseId;
}
this.result = this.$get('/test/case/comment/list/' + id, res => {
this.comments = res.data;
})
},
handleClose() {
removeGoBackListener(this.handleClose);
this.showDialog = false;
@ -267,11 +250,6 @@ export default {
this.handleClose();
this.$emit('refreshTable');
},
statusChange(status) {
this.originalStatus = this.testCase.status;
this.testCase.status = status;
this.saveCase(true);
},
getOption(param) {
let formData = new FormData();
let url = '/test/case/edit/testPlan';
@ -307,7 +285,7 @@ export default {
}
};
},
saveCase(next, noTip) {
saveCase() {
let param = {};
param.id = this.testCase.id;
param.caseId = this.testCase.caseId;
@ -318,6 +296,7 @@ export default {
param.nodeId = this.testCase.nodeId;
param.demandId = this.testCase.demandId;
param.name = this.testCase.name;
param.comment = this.testCase.comment;
let option = this.getOption(param);
for (let i = 0; i < this.testCase.steptResults.length; i++) {
let result = {};
@ -341,18 +320,17 @@ export default {
this.$request(option, (response) => {
});
if (!noTip) {
if (!this.isLastData()) {
this.$success(this.$t('commons.save_success') + ' -> ' + this.$t('test_track.plan_view.next_case'));
} else {
this.$success(this.$t('commons.save_success'));
}
}
this.$success(this.$t('commons.save_success'));
this.updateTestCases(param);
this.setPlanStatus(this.testCase.planId);
if (next) {
this.handleNext();
if (this.testCase.comment) {
this.$refs.comment.getComments();
this.testCase.comment = '';
}
this.originalStatus = this.testCase.status;
});
},
updateTestCases(param) {
@ -437,13 +415,13 @@ export default {
}
}
this.testCase = item;
this.originalStatus = this.testCase.status;
parseCustomField(this.testCase, this.testCaseTemplate, null, buildTestCaseOldFields(this.testCase));
this.isCustomFiledActive = true;
if (!this.testCase.actualResult) {
// ,使
this.testCase.actualResult = this.testCaseTemplate.actualResult;
}
this.getComments(item);
});
},
openTestCaseEdit(testCase, tableData) {
@ -452,6 +430,7 @@ export default {
this.hasTapdId = false;
this.hasZentaoId = false;
this.isReadOnly = !hasPermission('PROJECT_TRACK_PLAN:READ+RELEVANCE_OR_CANCEL');
this.originalStatus = testCase.status;
if (tableData) {
this.testCases = tableData;
@ -537,11 +516,6 @@ export default {
color: dimgray;
}
.status-button {
padding-left: 4%;
padding-right: 4%;
}
.head-right {
text-align: right;
}
@ -554,10 +528,6 @@ export default {
line-height: 16px;
}
.status-button {
float: right;
}
.el-scrollbar {
height: 100%;
}
@ -607,11 +577,6 @@ p {
overflow: auto;
}
.save-btn {
margin-left: 10px;
}
.el-divider__text {
line-height: normal;
}

View File

@ -0,0 +1,105 @@
<template>
<el-form class="comment-form clearfix">
<el-form-item
:label="'评论'">
<ms-mark-down-text
default-open="edit"
prop="comment"
custom-min-height="100"
:class="{inputWarning: inputWarning}"
:data="data"
:toolbars="toolbars"
ref="md"/>
</el-form-item>
</el-form>
</template>
<script>
import MsMarkDownText from "@/business/components/track/case/components/MsMarkDownText";
export default {
name: "TestPlanCommentInput",
components: {MsMarkDownText},
props: {
data: {
type: Object,
default() {
return {
comment: ''
}
}
}
},
watch: {
'data.comment'() {
if (this.data && this.data.comment && this.data.comment.length > 0) {
this.inputWarning = false;
}
},
'data.status'() {
if (this.data.status !== 'Failure' && this.inputWarning) {
this.inputWarning = false;
}
}
},
data() {
return {
toolbars: {
bold: false, //
italic: false, //
header: false, //
underline: false, // 线
strikethrough: false, // 线
mark: false, //
superscript: false, //
subscript: false, //
quote: false, //
ol: false, //
ul: false, //
link: false, //
imagelink: true, //
code: false, // code
table: false, //
fullscreen: false, //
readmodel: false, //
htmlcode: false, // html
help: false, //
/* 1.3.5 */
undo: false, //
redo: false, //
trash: false, //
save: false, // eventssave
/* 1.4.2 */
navigation: false, //
/* 2.1.8 */
alignleft: false, //
aligncenter: false, //
alignright: false, //
/* 2.2.1 */
subfield: false, //
preview: false, //
},
inputWarning: false
};
},
methods: {
inputLight() {
this.inputWarning = true;
this.$refs.md.getTextareaDom().focus();
},
}
}
</script>
<style scoped>
.comment-form {
padding-right: 20px;
padding-left: 30px;
margin-top: 100px;
}
.inputWarning {
-webkit-box-shadow: 0 0 8px rgb(205,51,43) !important;
}
</style>

View File

@ -0,0 +1,70 @@
<template>
<el-card>
<test-plan-test-case-status-button class="status-button"
@statusChange="statusChange"
:is-read-only="statusReadOnly"
:status="testCase.status"/>
<el-button class="save-btn" type="primary" size="mini" :disabled="isReadOnly" @click="saveCase()">
{{$t('test_track.save')}}
</el-button>
<test-plan-comment-input
:data="testCase"
ref="comment"/>
</el-card>
</template>
<script>
import TestPlanTestCaseStatusButton from "@/business/components/track/plan/common/TestPlanTestCaseStatusButton";
import {hasPermission} from "@/common/js/utils";
import TestPlanCommentInput from "@/business/components/track/plan/view/comonents/functional/TestPlanCommentInput";
export default {
name: "TestPlanFunctionalExecute",
components: {TestPlanCommentInput, TestPlanTestCaseStatusButton},
props: {
isReadOnly: Boolean,
originStatus: String,
testCase: {
type: Object,
default() {
return {}
}
}
},
computed: {
statusReadOnly() {
return !hasPermission('PROJECT_TRACK_PLAN:READ+RUN');
},
},
methods: {
statusChange(status) {
this.testCase.status = status;
},
saveCase() {
//
if (this.testCase.status === 'Failure' && this.originStatus !== 'Failure' && !this.testCase.comment) {
this.$refs.comment.inputLight();
} else {
this.$emit('saveCase');
}
}
}
}
</script>
<style scoped>
.status-button {
padding-left: 4%;
padding-right: 4%;
}
.status-button {
float: left;
}
.save-btn {
float: right;
margin-top: 10px;
}
</style>

View File

@ -1,39 +1,38 @@
<template>
<div v-loading="result.loading">
<div class="comment-list">
<review-comment-item v-for="(comment) in comments" v-bind:key="comment.id"
ref="reviewComments"
:comment="comment"
@refresh="refresh"
:review-status="reviewStatus" api-url="/test/case"/>
<div v-if="comments.length === 0" style="text-align: center">
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
<el-card>
<template slot="header">
<span style="font-size: 15px; color: #1E90FF">{{ $t('test_track.review.comment') }}</span>
<i class="el-icon-refresh" @click="getComments()"/>
<el-select
class="type-select"
v-model="type"
size="small">
<el-option
v-for="item in commentTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</template>
<div v-loading="result.loading">
<div class="comment-list">
<review-comment-item v-for="(comment) in comments"
api-url="/test/case"
:key="comment.id"
:comment="comment"
@refresh="refresh"
ref="reviewComments"/>
<div v-if="comments.length === 0" style="text-align: center">
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
<span style="font-size: 15px; color: #8a8b8d;">
{{ $t('test_track.comment.no_comment') }}
</span>
</i>
</div>
</div>
<div>
<div class="editors_div_style">
<div id="editorsDiv">
<ms-mark-down-text
default-open="edit"
prop="description"
custom-min-height="220"
:data="form"
:toolbars="toolbars"
ref="md"/>
</i>
</div>
</div>
<el-button type="primary" size="mini" class="send-btn"
v-permission="['PROJECT_TRACK_REVIEW:READ+COMMENT']"
@click="sendComment" :disabled="isReadOnly">
{{ $t('test_track.comment.send') }}
</el-button>
</div>
</div>
</el-card>
</template>
<script>
@ -46,141 +45,85 @@ export default {
components: {MsMarkDownText, ReviewCommentItem, FormRichTextItem},
props: {
caseId: String,
comments: Array,
reviewId: String,
reviewStatus: String,
oldReviewStatus: String,
defaultType: String
},
data() {
return {
result: {},
form: {
description: ''
},
loadCommenItem: true,
labelWidth: '120px',
showEditor: true,
isReadOnly: false,
toolbars: {
bold: false, //
italic: false, //
header: false, //
underline: false, // 线
strikethrough: false, // 线
mark: false, //
superscript: false, //
subscript: false, //
quote: false, //
ol: false, //
ul: false, //
link: false, //
imagelink: true, //
code: false, // code
table: false, //
fullscreen: false, //
readmodel: false, //
htmlcode: false, // html
help: false, //
/* 1.3.5 */
undo: false, //
redo: false, //
trash: false, //
save: false, // eventssave
/* 1.4.2 */
navigation: false, //
/* 2.1.8 */
alignleft: false, //
aligncenter: false, //
alignright: false, //
/* 2.2.1 */
subfield: false, //
preview: false, //
}
comments: [],
type: '',
commentTypeOptions: [
{
value: 'CASE',
label: '用例评论'
},
{
value: 'PLAN',
label: '执行评论'
},
{
value: 'REVIEW',
label: '评审评论'
},
{
value: null,
label: '全部评论'
}
],
};
},
created() {
this.isReadOnly = false;
this.type = this.defaultType;
},
watch: {
comments() {
caseId() {
this.type = this.defaultType;
this.getComments();
},
type() {
this.getComments();
}
},
methods: {
sendComment() {
let comment = {};
comment.caseId = this.caseId;
comment.description = this.form.description;
comment.reviewId = this.reviewId;
comment.status = this.reviewStatus;
if (!comment.description) {
this.$warning(this.$t('test_track.comment.description_is_null'));
return;
}
this.result = this.$post('/test/case/review/comment/save', comment, () => {
this.$success(this.$t('test_track.comment.send_success'));
this.form.description = "";
this.refresh();
if (this.$refs.md) {
this.$refs.md.toolbar_left_click('trash');
}
if ((this.oldReviewStatus === 'Prepare' || this.oldReviewStatus === 'Pass') && this.reviewStatus === 'UnPass') {
this.$emit('saveCaseReview');
}
});
},
inputLight() {
let textAreaDom = this.$refs.md.getTextareaDom();
let editorDivDom = document.getElementById("editorsDiv");
if (editorDivDom) {
editorDivDom.setAttribute("style", "-webkit-box-shadow: 0 0 8px rgb(205,51,43);");
}
textAreaDom.focus();
},
resetInputLight() {
let editorDivDom = document.getElementById("editorsDiv");
if (editorDivDom) {
editorDivDom.setAttribute("style", "-webkit-box-shadow: 0 0 0px rgb(-1,0,0);");
getComments() {
if (this.caseId) {
let type = this.type ? this.type : '';
this.result = this.$get('/test/case/comment/list/' + this.caseId + '/' + type , res => {
this.comments = res.data;
});
}
},
refresh() {
this.resetInputLight();
this.$emit('getComments');
this.getComments();
}
}
};
</script>
<style scoped>
.send-btn {
margin-top: 5px;
width: 100%;
}
.comment-list {
overflow-y: scroll;
height: calc(100vh - 450px);
}
.editors-div {
-webkit-box-shadow: 0 0 8px rgb(-1, 0, 0);
}
.editors_div_style {
height: 300px;
overflow: auto
}
.review-mavon-editor {
min-height: 20px;
height: 300px;
overflow: auto
}
.review-mavon-editor {
position: initial;
height: calc(100vh - 340px);
}
/deep/ .v-note-wrapper {
position: initial;
}
.el-icon-refresh {
margin-left: 10px;
font-size: 14px;
cursor: pointer
}
.type-select {
float: right;
width: 120px;
}
</style>

View File

@ -11,12 +11,7 @@
{{ comment.createTime | timestampFormatDate }}
</span>
<span>
<el-button v-if="comment.status === 'UnPass'" type="danger" size="mini" round>
{{ $t('test_track.review.un_pass') }}
</el-button>
<el-button v-if="comment.status === 'Pass'" type="success" size="mini">
{{ $t('test_track.review.pass') }}
</el-button>
<status-table-item v-if="comment.status" :value="comment.status"/>
</span>
<span class="comment-delete">
<el-link icon="el-icon-edit" style="font-size: 9px;margin-right: 6px;" @click="openEdit" :disabled="readOnly"/>
@ -66,17 +61,17 @@
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
import {getCurrentUser} from "@/common/js/utils";
import MsMarkDownText from "@/business/components/track/case/components/MsMarkDownText";
import StatusTableItem from "@/business/components/track/common/tableItems/planview/StatusTableItem";
export default {
name: "ReviewCommentItem",
components: {MsDialogFooter, MsMarkDownText},
components: {StatusTableItem, MsDialogFooter, MsMarkDownText},
props: {
comment: Object,
readOnly: {
type: Boolean,
default: false
},
reviewStatus: String,
apiUrl: String
},
data() {

View File

@ -0,0 +1,71 @@
<template>
<el-card>
<div class="status-bnt">
<el-button type="success" size="mini"
:disabled="isReadOnly" :icon="testCase.reviewStatus === 'Pass' ? 'el-icon-check' : ''"
@click="changeStatus('Pass')">
{{ $t('test_track.review.pass') }}
</el-button>
<el-button type="danger" size="mini"
:disabled="isReadOnly"
:icon="testCase.reviewStatus === 'UnPass' ? 'el-icon-check' : ''"
@click="changeStatus('UnPass')">
{{ $t('test_track.review.un_pass') }}
</el-button>
</div>
<el-button class="save-btn" type="primary" size="mini" :disabled="isReadOnly" @click="saveCase()">
{{$t('test_track.save')}}
</el-button>
<test-plan-comment-input
:data="testCase"
ref="comment"/>
</el-card>
</template>
<script>
import TestPlanTestCaseStatusButton from "@/business/components/track/plan/common/TestPlanTestCaseStatusButton";
import TestPlanCommentInput from "@/business/components/track/plan/view/comonents/functional/TestPlanCommentInput";
export default {
name: "TestReviewTestCaseExecute",
components: {TestPlanCommentInput, TestPlanTestCaseStatusButton},
props: {
isReadOnly: Boolean,
originStatus: String,
testCase: {
type: Object,
default() {
return {}
}
}
},
methods: {
saveCase() {
//
if (this.testCase.reviewStatus === 'UnPass' && this.originStatus !== 'UnPass' && !this.testCase.comment) {
this.$refs.comment.inputLight();
} else {
this.$emit('saveCase');
}
},
changeStatus(status) {
this.testCase.reviewStatus = status;
}
}
}
</script>
<style scoped>
.status-bnt {
float: left;
}
.save-btn {
float: right;
margin-top: 10px;
}
</style>

View File

@ -11,8 +11,8 @@
<template v-slot:default="scope">
<el-row :gutter="10">
<div class="container">
<el-col :span="17">
<el-col :span="17">
<div class="container">
<el-card>
<el-scrollbar>
@ -40,20 +40,6 @@
:list="testCases"
@pre="handlePre"
@next="handleNext"/>
<el-divider direction="vertical"></el-divider>
<el-button type="success" size="mini"
:disabled="isReadOnly" :icon="testCase.reviewStatus === 'Pass' ? 'el-icon-check' : ''"
@click="saveCase('Pass')">
{{ $t('test_track.review.pass') }}
</el-button>
<el-button type="danger" size="mini"
:disabled="isReadOnly"
:icon="testCase.reviewStatus === 'UnPass' ? 'el-icon-check' : ''"
@click="saveCase('UnPass')">
{{ $t('test_track.review.un_pass') }}
</el-button>
</el-col>
</el-row>
@ -62,9 +48,9 @@
<el-col>
<el-divider content-position="left">
<el-button class="test-case-name" type="text" @click="openTestTestCase(testCase)">
<span class="title-link" :title="testCase.name">
{{ testCase.num }}-{{ testCase.name }}
</span>
<span class="title-link" :title="testCase.name">
{{ testCase.num }}-{{ testCase.name }}
</span>
</el-button>
</el-divider>
</el-col>
@ -88,6 +74,11 @@
{{ testCase.projectName }}
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="$t('评审状态')" :label-width="formLabelWidth">
<status-table-item :value="oldReviewStatus"/>
</el-form-item >
</el-col>
</el-row>
<el-form ref="customFieldForm"
@ -130,21 +121,23 @@
</el-scrollbar>
</el-card>
</div>
</el-col>
<el-col :span="7">
<div class="comment-card">
<test-review-test-case-execute
:test-case="testCase"
:is-read-only="isReadOnly"
:origin-status="oldReviewStatus"
@saveCase="saveCase()"/>
<review-comment
default-type="REVIEW"
:case-id="testCase.caseId"
@saveCaseReview="saveCaseReview"
ref="comment"/>
</div>
</el-col>
<el-col :span="7">
<el-card class="comment-card">
<template slot="header">
<span style="font-size: 15px; color: #1E90FF">{{ $t('test_track.review.comment') }}</span>
<i class="el-icon-refresh" @click="getComments(testCase)"
style="margin-left:10px;font-size: 14px; cursor: pointer"/>
</template>
<review-comment :comments="comments" :case-id="testCase.caseId" :review-id="testCase.reviewId"
:oldReviewStatus="oldReviewStatus"
@getComments="getComments" :review-status="testCase.reviewStatus" ref="reviewComment"
@saveCaseReview="saveCaseReview"/>
</el-card>
</el-col>
</div>
</el-row>
</template>
@ -173,10 +166,14 @@ import CustomFiledComponent from "@/business/components/project/template/CustomF
import StepChangeItem from "@/business/components/track/case/components/StepChangeItem";
import TestCaseStepItem from "@/business/components/track/case/components/TestCaseStepItem";
import MsPreviousNextButton from "@/business/components/common/components/MsPreviousNextButton";
import TestReviewTestCaseExecute from "@/business/components/track/review/components/TestReviewTestCaseExecute";
import StatusTableItem from "@/business/components/track/common/tableItems/planview/StatusTableItem";
export default {
name: "TestReviewTestCaseEdit",
components: {
StatusTableItem,
TestReviewTestCaseExecute,
MsPreviousNextButton,
TestCaseStepItem,
StepChangeItem,
@ -218,7 +215,7 @@ export default {
hasZentaoId: false,
formLabelWidth: '100px',
isCustomFiledActive: false,
oldReviewStatus: 'Prepare'
oldReviewStatus: ''
};
},
props: {
@ -289,49 +286,27 @@ export default {
this.handleClose();
this.$emit('refreshTable');
},
saveCase(status) {
saveCase() {
let param = {};
param.id = this.testCase.id;
param.caseId = this.testCase.caseId;
param.reviewId = this.testCase.reviewId;
param.status = status;
if (status === 'UnPass') {
this.testCase.reviewStatus = 'UnPass';
//
if (this.oldReviewStatus === 'Prepare' && this.comments.length < 1) {
this.$refs.reviewComment.inputLight();
this.$warning(this.$t('test_track.comment.description_is_null'));
} else if (this.$refs.reviewComment.form.description.length > 0) {
//
this.$refs.reviewComment.inputLight();
this.$warning(this.$t('test_track.comment.submit_description'));
} else if (this.oldReviewStatus === 'Pass') {
//
this.$refs.reviewComment.inputLight();
this.$warning(this.$t('test_track.comment.description_is_null'));
} else {
//
this._saveCase(param, status);
}
} else {
this._saveCase(param, status);
}
},
_saveCase(param, status) {
param.comment = this.testCase.comment;
param.status = this.testCase.reviewStatus;
this.$post('/test/review/case/edit', param, () => {
if (!this.isLastData()) {
this.$success(this.$t('commons.save_success') + ' -> ' + this.$t('test_track.plan_view.next_case'));
} else {
this.$success(this.$t('commons.save_success'));
}
this.$success(this.$t('commons.save_success'));
this.updateTestCases(param);
this.setReviewStatus(this.testCase.reviewId);
this.testCase.reviewStatus = status;
//
this.testCases[this.index].reviewStatus = status;
this.handleNext();
this.testCases[this.index].reviewStatus = this.testCase.reviewStatus;
//
this.oldReviewStatus = status;
this.oldReviewStatus = this.testCase.reviewStatus;
if (this.testCase.comment) {
this.$refs.comment.getComments();
this.testCase.comment = '';
}
});
},
saveCaseReview() {
@ -411,8 +386,6 @@ export default {
// ,使
this.testCase.actualResult = this.testCaseTemplate.actualResult;
}
this.getComments(item);
this.$refs.reviewComment.resetInputLight();
})
},
@ -434,7 +407,6 @@ export default {
//
this.oldReviewStatus = testCase.reviewStatus;
this.activeTab = 'detail';
this.getComments(testCase);
this.hasTapdId = false;
this.hasZentaoId = false;
listenGoBack(this.handleClose);
@ -457,22 +429,6 @@ export default {
initFuc(testCase.id);
});
},
getComments(testCase) {
let id = '';
if (testCase) {
id = testCase.caseId;
} else {
id = this.testCase.caseId;
}
this.result = this.$get('/test/case/comment/list/' + id, res => {
if (res.data) {
this.comments = null;
this.comments = res.data;
}
})
},
openTestTestCase(item) {
let testCaseData = this.$router.resolve(
{path: '/track/case/all', query: {redirectID: getUUID(), dataType: "testCase", dataSelectRange: item.caseId}}
@ -520,10 +476,6 @@ export default {
color: dimgray;
}
.status-button {
padding-left: 4%;
}
.head-right {
text-align: right;
margin-top: 30px;
@ -537,14 +489,6 @@ export default {
line-height: 16px;
}
.status-button {
float: right;
}
.head-right-tip {
color: darkgrey;
}
.el-scrollbar {
height: 100%;
}
@ -569,12 +513,14 @@ export default {
height: calc(100vh - 50px);
}
.comment-card >>> .el-card__header {
padding: 0 20px;
.comment-card {
padding-left: 0;
padding-right: 15px;
padding-top: 15px;
}
.comment-card >>> .el-card__body {
height: calc(100vh - 100px);
.comment-card >>> .el-card__header {
padding: 0 20px;
}
.tb-edit >>> .el-textarea__inner {
@ -598,15 +544,6 @@ export default {
margin-right: 5px;
}
.step-info {
padding-left: 40px;
padding-right: 15px;
}
.el-divider__text {
line-height: normal;
}
/deep/ .el-drawer__body {
overflow: unset;
}