feat(测试跟踪): 用例评审关联测试用例
This commit is contained in:
parent
95b722e86c
commit
3135bf3406
|
@ -2,15 +2,16 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestCaseReviewMapper">
|
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestCaseReviewMapper">
|
||||||
|
|
||||||
<select id="list" resultType="io.metersphere.track.dto.TestCaseReviewDTO" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
<select id="list" resultType="io.metersphere.track.dto.TestCaseReviewDTO" parameterType="io.metersphere.track.request.testreview.QueryCaseReviewRequest">
|
||||||
select test_case_review.* from test_case_review
|
select distinct test_case_review.*
|
||||||
|
from test_case_review, project, test_case_review_project
|
||||||
<where>
|
<where>
|
||||||
|
test_case_review.id = test_case_review_project.review_id
|
||||||
|
and test_case_review_project.project_id = project.id
|
||||||
<if test="request.name != null">
|
<if test="request.name != null">
|
||||||
and test_case_review.name like CONCAT('%', #{request.name},'%')
|
and test_case_review.name like CONCAT('%', #{request.name},'%')
|
||||||
</if>
|
</if>
|
||||||
<if test="request.id != null">
|
and project.workspace_id = #{request.workspaceId}
|
||||||
AND test_case_review.id = #{request.id}
|
|
||||||
</if>
|
|
||||||
</where>
|
</where>
|
||||||
<if test="request.orders != null and request.orders.size() > 0">
|
<if test="request.orders != null and request.orders.size() > 0">
|
||||||
order by
|
order by
|
||||||
|
@ -20,7 +21,7 @@
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="listByWorkspaceId" resultType="io.metersphere.track.dto.TestCaseReviewDTO" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
<select id="listByWorkspaceId" resultType="io.metersphere.track.dto.TestCaseReviewDTO" parameterType="io.metersphere.track.request.testreview.QueryCaseReviewRequest">
|
||||||
select distinct test_case_review.*
|
select distinct test_case_review.*
|
||||||
from test_case_review, project, test_case_review_project
|
from test_case_review, project, test_case_review_project
|
||||||
where test_case_review.id = test_case_review_project.review_id
|
where test_case_review.id = test_case_review_project.review_id
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
|
import io.metersphere.track.dto.TestReviewCaseDTO;
|
||||||
|
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
public interface ExtTestReviewCaseMapper {
|
||||||
|
|
||||||
|
List<TestReviewCaseDTO> list(@Param("request") QueryCaseReviewRequest request);
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestReviewCaseMapper">
|
||||||
|
<sql id="condition">
|
||||||
|
<choose>
|
||||||
|
<when test='${object}.operator == "like"'>
|
||||||
|
like CONCAT('%', #{${object}.value},'%')
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "not like"'>
|
||||||
|
not like CONCAT('%', #{${object}.value},'%')
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "in"'>
|
||||||
|
in
|
||||||
|
<foreach collection="${object}.value" item="v" separator="," open="(" close=")">
|
||||||
|
#{v}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "not in"'>
|
||||||
|
not in
|
||||||
|
<foreach collection="${object}.value" item="v" separator="," open="(" close=")">
|
||||||
|
#{v}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "between"'>
|
||||||
|
between #{${object}.value[0]} and #{${object}.value[1]}
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "gt"'>
|
||||||
|
> #{${object}.value}
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "lt"'>
|
||||||
|
< #{${object}.value}
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "ge"'>
|
||||||
|
>= #{${object}.value}
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "le"'>
|
||||||
|
<= #{${object}.value}
|
||||||
|
</when>
|
||||||
|
<when test='${object}.operator == "current user"'>
|
||||||
|
= '${@io.metersphere.commons.utils.SessionUtils@getUserId()}'
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
= #{${object}.value}
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<sql id="combine">
|
||||||
|
<if test='${condition}.name != null and (${name} == null or ${name} == "")'>
|
||||||
|
and test_case.name
|
||||||
|
<include refid="condition">
|
||||||
|
<property name="object" value="${condition}.name"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
<if test="${condition}.module != null">
|
||||||
|
and test_case.node_path
|
||||||
|
<include refid="condition">
|
||||||
|
<property name="object" value="${condition}.module"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
<if test="${condition}.priority != null">
|
||||||
|
and test_case.priority
|
||||||
|
<include refid="condition">
|
||||||
|
<property name="object" value="${condition}.priority"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
<if test="${condition}.createTime != null">
|
||||||
|
and test_case.create_time
|
||||||
|
<include refid="condition">
|
||||||
|
<property name="object" value="${condition}.createTime"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
<if test="${condition}.type != null">
|
||||||
|
and test_case.type
|
||||||
|
<include refid="condition">
|
||||||
|
<property name="object" value="${condition}.type"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
<if test="${condition}.updateTime != null">
|
||||||
|
and test_case.update_time
|
||||||
|
<include refid="condition">
|
||||||
|
<property name="object" value="${condition}.updateTime"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
<if test="${condition}.method != null">
|
||||||
|
and test_case.method
|
||||||
|
<include refid="condition">
|
||||||
|
<property name="object" value="${condition}.method"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
<if test="${condition}.creator != null">
|
||||||
|
and test_case.maintainer
|
||||||
|
<include refid="condition">
|
||||||
|
<property name="object" value="${condition}.creator"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="list" resultType="io.metersphere.track.dto.TestReviewCaseDTO">
|
||||||
|
select test_case.remark, test_case_review_test_case.*, test_case.*, test_case_node.name as model, project.name as projectName
|
||||||
|
from test_case_review_test_case
|
||||||
|
inner join test_case on test_case_review_test_case.case_id = test_case.id
|
||||||
|
left join test_case_node on test_case_node.id=test_case.node_id
|
||||||
|
inner join project on project.id = test_case.project_id
|
||||||
|
<where>
|
||||||
|
<if test="request.combine != null">
|
||||||
|
<include refid="combine">
|
||||||
|
<property name="condition" value="request.combine"/>
|
||||||
|
<property name="name" value="request.name"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
|
<if test="request.name != null">
|
||||||
|
and (test_case.name like CONCAT('%', #{request.name},'%') or test_case.num like CONCAT('%', #{request.name},'%'))
|
||||||
|
</if>
|
||||||
|
<if test="request.id != null">
|
||||||
|
and test_case.id = #{request.id}
|
||||||
|
</if>
|
||||||
|
<if test="request.nodeIds != null and request.nodeIds.size() > 0">
|
||||||
|
and test_case.node_id in
|
||||||
|
<foreach collection="request.nodeIds" item="nodeId" separator="," open="(" close=")">
|
||||||
|
#{nodeId}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
<if test="request.status != null">
|
||||||
|
and test_case_review_test_case.status = #{request.status}
|
||||||
|
</if>
|
||||||
|
<if test="request.reviewer != null">
|
||||||
|
and test_case_review_test_case.reviewer = #{request.reviewer}
|
||||||
|
</if>
|
||||||
|
<if test="request.reviewId != null">
|
||||||
|
and test_case_review_test_case.review_id = #{request.reviewId}
|
||||||
|
</if>
|
||||||
|
<if test="request.method != null">
|
||||||
|
and test_case.method = #{request.method}
|
||||||
|
</if>
|
||||||
|
<if test="request.filters != null and request.filters.size() > 0">
|
||||||
|
<foreach collection="request.filters.entrySet()" index="key" item="values">
|
||||||
|
<if test="values != null and values.size() > 0">
|
||||||
|
<choose>
|
||||||
|
<when test="key=='priority'">
|
||||||
|
and test_case.priority in
|
||||||
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
|
#{value}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
<when test="key=='type'">
|
||||||
|
and test_case.type in
|
||||||
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
|
#{value}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
<when test="key=='method'">
|
||||||
|
and test_case.method in
|
||||||
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
|
#{value}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
and test_case_review_test_case.status in
|
||||||
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
|
#{value}
|
||||||
|
</foreach>
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</if>
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
<if test="request.orders != null and request.orders.size() > 0">
|
||||||
|
order by
|
||||||
|
<foreach collection="request.orders" separator="," item="order">
|
||||||
|
<choose>
|
||||||
|
<when test="order.name == 'num'">
|
||||||
|
test_case.num ${order.type}
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
test_case_review_test_case.${order.name} ${order.type}
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
</mapper>
|
|
@ -274,4 +274,10 @@ public class WorkspaceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Project> getProjects(String workspaceId) {
|
||||||
|
ProjectExample projectExample = new ProjectExample();
|
||||||
|
projectExample.createCriteria().andWorkspaceIdEqualTo(workspaceId);
|
||||||
|
return projectMapper.selectByExample(projectExample);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,11 @@ public class TestCaseController {
|
||||||
return testCaseService.getTestCaseNames(request);
|
return testCaseService.getTestCaseNames(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/reviews/case")
|
||||||
|
public List<TestCase> getReviewCase(@RequestBody QueryTestCaseRequest request) {
|
||||||
|
return testCaseService.getReviewCase(request);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/get/{testCaseId}")
|
@GetMapping("/get/{testCaseId}")
|
||||||
public TestCaseWithBLOBs getTestCase(@PathVariable String testCaseId) {
|
public TestCaseWithBLOBs getTestCase(@PathVariable String testCaseId) {
|
||||||
return testCaseService.getTestCase(testCaseId);
|
return testCaseService.getTestCase(testCaseId);
|
||||||
|
|
|
@ -32,11 +32,21 @@ public class TestCaseNodeController {
|
||||||
return testCaseNodeService.getAllNodeByPlanId(request);
|
return testCaseNodeService.getAllNodeByPlanId(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/list/all/review")
|
||||||
|
public List<TestCaseNodeDTO> getAllNodeByReviewId(@RequestBody QueryNodeRequest request) {
|
||||||
|
return testCaseNodeService.getAllNodeByReviewId(request);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/list/plan/{planId}")
|
@GetMapping("/list/plan/{planId}")
|
||||||
public List<TestCaseNodeDTO> getNodeByPlanId(@PathVariable String planId) {
|
public List<TestCaseNodeDTO> getNodeByPlanId(@PathVariable String planId) {
|
||||||
return testCaseNodeService.getNodeByPlanId(planId);
|
return testCaseNodeService.getNodeByPlanId(planId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/list/review/{reviewId}")
|
||||||
|
public List<TestCaseNodeDTO> getNodeByReviewId(@PathVariable String reviewId) {
|
||||||
|
return testCaseNodeService.getNodeByReviewId(reviewId);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
public String addNode(@RequestBody TestCaseNode node) {
|
public String addNode(@RequestBody TestCaseNode node) {
|
||||||
|
|
|
@ -4,15 +4,19 @@ import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.base.domain.Project;
|
import io.metersphere.base.domain.Project;
|
||||||
import io.metersphere.base.domain.TestCaseReview;
|
import io.metersphere.base.domain.TestCaseReview;
|
||||||
|
import io.metersphere.base.domain.TestPlan;
|
||||||
import io.metersphere.base.domain.User;
|
import io.metersphere.base.domain.User;
|
||||||
import io.metersphere.commons.constants.RoleConstants;
|
import io.metersphere.commons.constants.RoleConstants;
|
||||||
import io.metersphere.commons.utils.PageUtils;
|
import io.metersphere.commons.utils.PageUtils;
|
||||||
import io.metersphere.commons.utils.Pager;
|
import io.metersphere.commons.utils.Pager;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.track.dto.TestCaseReviewDTO;
|
import io.metersphere.track.dto.TestCaseReviewDTO;
|
||||||
|
import io.metersphere.track.request.testreview.ReviewRelevanceRequest;
|
||||||
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||||
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
||||||
|
import io.metersphere.track.request.testreview.TestReviewRelevanceRequest;
|
||||||
import io.metersphere.track.service.TestCaseReviewService;
|
import io.metersphere.track.service.TestCaseReviewService;
|
||||||
|
import io.metersphere.track.service.TestReviewProjectService;
|
||||||
import org.apache.shiro.authz.annotation.Logical;
|
import org.apache.shiro.authz.annotation.Logical;
|
||||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
@ -25,6 +29,8 @@ public class TestCaseReviewController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
TestCaseReviewService testCaseReviewService;
|
TestCaseReviewService testCaseReviewService;
|
||||||
|
@Resource
|
||||||
|
TestReviewProjectService testReviewProjectService;
|
||||||
|
|
||||||
@PostMapping("/list/{goPage}/{pageSize}")
|
@PostMapping("/list/{goPage}/{pageSize}")
|
||||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
@ -70,4 +76,36 @@ public class TestCaseReviewController {
|
||||||
public void deleteCaseReview(@PathVariable String reviewId) {
|
public void deleteCaseReview(@PathVariable String reviewId) {
|
||||||
testCaseReviewService.deleteCaseReview(reviewId);
|
testCaseReviewService.deleteCaseReview(reviewId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/list/all")
|
||||||
|
public List<TestCaseReview> listAll() {
|
||||||
|
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
|
||||||
|
return testCaseReviewService.listCaseReviewAll(currentWorkspaceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/relevance")
|
||||||
|
public void testReviewRelevance(@RequestBody ReviewRelevanceRequest request) {
|
||||||
|
testCaseReviewService.testReviewRelevance(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/projects")
|
||||||
|
public List<Project> getProjectByReviewId(@RequestBody TestReviewRelevanceRequest request) {
|
||||||
|
List<String> projectIds = testReviewProjectService.getProjectIdsByPlanId(request.getReviewId());
|
||||||
|
request.setProjectIds(projectIds);
|
||||||
|
return testReviewProjectService.getProject(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/project/{goPage}/{pageSize}")
|
||||||
|
public Pager<List<Project>> getProjectByReviewId(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody TestReviewRelevanceRequest request) {
|
||||||
|
List<String> projectIds = testReviewProjectService.getProjectIdsByPlanId(request.getReviewId());
|
||||||
|
request.setProjectIds(projectIds);
|
||||||
|
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||||
|
return PageUtils.setPageInfo(page, testReviewProjectService.getProject(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/get/{reviewId}")
|
||||||
|
public TestCaseReview getTestReview(@PathVariable String reviewId) {
|
||||||
|
return testCaseReviewService.getTestReview(reviewId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package io.metersphere.track.controller;
|
||||||
|
|
||||||
|
import com.github.pagehelper.Page;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import io.metersphere.commons.constants.RoleConstants;
|
||||||
|
import io.metersphere.commons.utils.PageUtils;
|
||||||
|
import io.metersphere.commons.utils.Pager;
|
||||||
|
import io.metersphere.track.dto.TestReviewCaseDTO;
|
||||||
|
import io.metersphere.track.request.testplancase.TestReviewCaseBatchRequest;
|
||||||
|
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||||
|
import io.metersphere.track.service.TestReviewTestCaseService;
|
||||||
|
import org.apache.shiro.authz.annotation.Logical;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RequestMapping("/test/review/case")
|
||||||
|
@RestController
|
||||||
|
public class TestReviewTestCaseController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
TestReviewTestCaseService testReviewTestCaseService;
|
||||||
|
|
||||||
|
@PostMapping("/list/{goPage}/{pageSize}")
|
||||||
|
public Pager<List<TestReviewCaseDTO>> getTestPlanCases(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryCaseReviewRequest request) {
|
||||||
|
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||||
|
return PageUtils.setPageInfo(page, testReviewTestCaseService.list(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public int deleteTestCase(@PathVariable String id) {
|
||||||
|
return testReviewTestCaseService.deleteTestCase(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batch/delete")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public void deleteTestCaseBath(@RequestBody TestReviewCaseBatchRequest request) {
|
||||||
|
testReviewTestCaseService.deleteTestCaseBath(request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package io.metersphere.track.dto;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TestReviewCaseDTO extends TestCaseWithBLOBs {
|
||||||
|
private String reviewer;
|
||||||
|
private String reviewerName;
|
||||||
|
private String status;
|
||||||
|
private String results;
|
||||||
|
private String reviewId;
|
||||||
|
private String caseId;
|
||||||
|
private String issues;
|
||||||
|
private String model;
|
||||||
|
private String projectName;
|
||||||
|
}
|
|
@ -9,5 +9,6 @@ public class QueryNodeRequest {
|
||||||
|
|
||||||
private String testPlanId;
|
private String testPlanId;
|
||||||
private String projectId;
|
private String projectId;
|
||||||
|
private String reviewId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,4 +27,6 @@ public class QueryTestCaseRequest extends TestCase {
|
||||||
private String workspaceId;
|
private String workspaceId;
|
||||||
|
|
||||||
private Map<String, Object> combine;
|
private Map<String, Object> combine;
|
||||||
|
|
||||||
|
private String reviewId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.metersphere.track.request.testplancase;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.TestCaseReviewTestCase;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TestReviewCaseBatchRequest extends TestCaseReviewTestCase {
|
||||||
|
private List<String> ids;
|
||||||
|
}
|
|
@ -1,14 +1,38 @@
|
||||||
package io.metersphere.track.request.testreview;
|
package io.metersphere.track.request.testreview;
|
||||||
|
|
||||||
import io.metersphere.base.domain.TestCaseReview;
|
import io.metersphere.base.domain.TestCaseReview;
|
||||||
|
import io.metersphere.base.domain.TestCaseReviewTestCase;
|
||||||
import io.metersphere.controller.request.OrderRequest;
|
import io.metersphere.controller.request.OrderRequest;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class QueryCaseReviewRequest extends TestCaseReview {
|
public class QueryCaseReviewRequest extends TestCaseReviewTestCase {
|
||||||
|
private List<String> nodeIds;
|
||||||
|
|
||||||
|
private List<String> nodePaths;
|
||||||
|
|
||||||
private List<OrderRequest> orders;
|
private List<OrderRequest> orders;
|
||||||
|
|
||||||
|
private Map<String, List<String>> filters;
|
||||||
|
|
||||||
|
private List<String> reviewIds;
|
||||||
|
|
||||||
|
private List<String> projectIds;
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
private String node;
|
||||||
|
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
private Map<String, Object> combine;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.track.request.testreview;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ReviewRelevanceRequest {
|
||||||
|
private String reviewId;
|
||||||
|
private List<String> testCaseIds = new ArrayList<>();
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.track.request.testreview;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TestReviewRelevanceRequest {
|
||||||
|
private String reviewId;
|
||||||
|
private String name;
|
||||||
|
private List<String> projectIds;
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ import org.apache.ibatis.session.SqlSession;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -45,6 +46,12 @@ public class TestCaseNodeService {
|
||||||
TestPlanProjectService testPlanProjectService;
|
TestPlanProjectService testPlanProjectService;
|
||||||
@Resource
|
@Resource
|
||||||
ProjectMapper projectMapper;
|
ProjectMapper projectMapper;
|
||||||
|
@Resource
|
||||||
|
TestCaseReviewService testCaseReviewService;
|
||||||
|
@Resource
|
||||||
|
TestCaseReviewTestCaseMapper testCaseReviewTestCaseMapper;
|
||||||
|
@Resource
|
||||||
|
TestCaseReviewMapper testCaseReviewMapper;
|
||||||
|
|
||||||
public String addNode(TestCaseNode node) {
|
public String addNode(TestCaseNode node) {
|
||||||
validateNode(node);
|
validateNode(node);
|
||||||
|
@ -199,6 +206,31 @@ public class TestCaseNodeService {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TestCaseNodeDTO> getNodeByReviewId(String reviewId) {
|
||||||
|
List<TestCaseNodeDTO> list = new ArrayList<>();
|
||||||
|
TestCaseReview testCaseReview = new TestCaseReview();
|
||||||
|
testCaseReview.setId(reviewId);
|
||||||
|
List<Project> project = testCaseReviewService.getProjectByReviewId(testCaseReview);
|
||||||
|
List<String> projectIds = project.stream().map(Project::getId).collect(Collectors.toList());
|
||||||
|
projectIds.forEach(id -> {
|
||||||
|
String name = projectMapper.selectByPrimaryKey(id).getName();
|
||||||
|
|
||||||
|
TestCaseReviewTestCaseExample testCaseReviewTestCaseExample = new TestCaseReviewTestCaseExample();
|
||||||
|
testCaseReviewTestCaseExample.createCriteria().andReviewIdEqualTo(reviewId);
|
||||||
|
List<TestCaseReviewTestCase> testCaseReviewTestCases = testCaseReviewTestCaseMapper.selectByExample(testCaseReviewTestCaseExample);
|
||||||
|
List<String> caseIds = testCaseReviewTestCases.stream().map(TestCaseReviewTestCase::getCaseId).collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<TestCaseNodeDTO> nodeList = getReviewNodeDTO(id, caseIds);
|
||||||
|
TestCaseNodeDTO testCaseNodeDTO = new TestCaseNodeDTO();
|
||||||
|
testCaseNodeDTO.setName(name);
|
||||||
|
testCaseNodeDTO.setLabel(name);
|
||||||
|
testCaseNodeDTO.setChildren(nodeList);
|
||||||
|
list.add(testCaseNodeDTO);
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private List<TestCaseNodeDTO> getNodeDTO(String projectId, String planId) {
|
private List<TestCaseNodeDTO> getNodeDTO(String projectId, String planId) {
|
||||||
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
|
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
|
||||||
testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(planId);
|
testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(planId);
|
||||||
|
@ -235,6 +267,36 @@ public class TestCaseNodeService {
|
||||||
return nodeTrees;
|
return nodeTrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<TestCaseNodeDTO> getReviewNodeDTO(String projectId, List<String> caseIds) {
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(caseIds)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestCaseNodeExample testCaseNodeExample = new TestCaseNodeExample();
|
||||||
|
testCaseNodeExample.createCriteria().andProjectIdEqualTo(projectId);
|
||||||
|
List<TestCaseNode> nodes = testCaseNodeMapper.selectByExample(testCaseNodeExample);
|
||||||
|
|
||||||
|
|
||||||
|
TestCaseExample testCaseExample = new TestCaseExample();
|
||||||
|
testCaseExample.createCriteria().andIdIn(caseIds);
|
||||||
|
List<String> dataNodeIds = testCaseMapper.selectByExample(testCaseExample).stream()
|
||||||
|
.map(TestCase::getNodeId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<TestCaseNodeDTO> nodeTrees = getNodeTrees(nodes);
|
||||||
|
|
||||||
|
Iterator<TestCaseNodeDTO> iterator = nodeTrees.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
TestCaseNodeDTO rootNode = iterator.next();
|
||||||
|
if (pruningTree(rootNode, dataNodeIds)) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeTrees;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 去除没有数据的节点
|
* 去除没有数据的节点
|
||||||
*
|
*
|
||||||
|
@ -281,6 +343,17 @@ public class TestCaseNodeService {
|
||||||
return getNodeTreeByProjectId(projectId);
|
return getNodeTreeByProjectId(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TestCaseNodeDTO> getAllNodeByReviewId(QueryNodeRequest request) {
|
||||||
|
String reviewId = request.getReviewId();
|
||||||
|
String projectId = request.getProjectId();
|
||||||
|
TestCaseReview testCaseReview = testCaseReviewMapper.selectByPrimaryKey(reviewId);
|
||||||
|
if (testCaseReview == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return getNodeTreeByProjectId(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, String> createNodeByTestCases(List<TestCaseWithBLOBs> testCases, String projectId) {
|
public Map<String, String> createNodeByTestCases(List<TestCaseWithBLOBs> testCases, String projectId) {
|
||||||
|
|
||||||
List<TestCaseNodeDTO> nodeTrees = getNodeTreeByProjectId(projectId);
|
List<TestCaseNodeDTO> nodeTrees = getNodeTreeByProjectId(projectId);
|
||||||
|
|
|
@ -8,13 +8,18 @@ import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.ServiceUtils;
|
import io.metersphere.commons.utils.ServiceUtils;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.track.dto.TestCaseReviewDTO;
|
import io.metersphere.track.dto.TestCaseReviewDTO;
|
||||||
|
import io.metersphere.track.request.testreview.ReviewRelevanceRequest;
|
||||||
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||||
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
|
import org.apache.ibatis.session.SqlSession;
|
||||||
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -34,6 +39,10 @@ public class TestCaseReviewService {
|
||||||
private ProjectMapper projectMapper;
|
private ProjectMapper projectMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private UserMapper userMapper;
|
private UserMapper userMapper;
|
||||||
|
@Resource
|
||||||
|
private TestCaseMapper testCaseMapper;
|
||||||
|
@Resource
|
||||||
|
SqlSessionFactory sqlSessionFactory;
|
||||||
|
|
||||||
public void saveTestCaseReview(SaveTestCaseReviewRequest reviewRequest) {
|
public void saveTestCaseReview(SaveTestCaseReviewRequest reviewRequest) {
|
||||||
checkCaseReviewExist(reviewRequest);
|
checkCaseReviewExist(reviewRequest);
|
||||||
|
@ -147,4 +156,58 @@ public class TestCaseReviewService {
|
||||||
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
|
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
|
||||||
testCaseReviewUsersMapper.deleteByExample(testCaseReviewUsersExample);
|
testCaseReviewUsersMapper.deleteByExample(testCaseReviewUsersExample);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TestCaseReview> listCaseReviewAll(String currentWorkspaceId) {
|
||||||
|
ProjectExample projectExample = new ProjectExample();
|
||||||
|
projectExample.createCriteria().andWorkspaceIdEqualTo(currentWorkspaceId);
|
||||||
|
List<Project> projects = projectMapper.selectByExample(projectExample);
|
||||||
|
List<String> projectIds = projects.stream().map(Project::getId).collect(Collectors.toList());
|
||||||
|
|
||||||
|
TestCaseReviewProjectExample testCaseReviewProjectExample = new TestCaseReviewProjectExample();
|
||||||
|
testCaseReviewProjectExample.createCriteria().andProjectIdIn(projectIds);
|
||||||
|
List<TestCaseReviewProject> testCaseReviewProjects = testCaseReviewProjectMapper.selectByExample(testCaseReviewProjectExample);
|
||||||
|
List<String> reviewIds = testCaseReviewProjects.stream().map(TestCaseReviewProject::getReviewId).collect(Collectors.toList());
|
||||||
|
|
||||||
|
TestCaseReviewExample testCaseReviewExample = new TestCaseReviewExample();
|
||||||
|
testCaseReviewExample.createCriteria().andIdIn(reviewIds);
|
||||||
|
return testCaseReviewMapper.selectByExample(testCaseReviewExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReviewRelevance(ReviewRelevanceRequest request) {
|
||||||
|
List<String> testCaseIds = request.getTestCaseIds();
|
||||||
|
|
||||||
|
if (testCaseIds.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
|
TestCaseReviewTestCaseMapper batchMapper = sqlSession.getMapper(TestCaseReviewTestCaseMapper.class);
|
||||||
|
|
||||||
|
if (!testCaseIds.isEmpty()) {
|
||||||
|
testCaseIds.forEach(caseId -> {
|
||||||
|
TestCaseReviewTestCase caseReview = new TestCaseReviewTestCase();
|
||||||
|
caseReview.setId(UUID.randomUUID().toString());
|
||||||
|
caseReview.setReviewer(SessionUtils.getUser().getId());
|
||||||
|
caseReview.setCaseId(caseId);
|
||||||
|
caseReview.setCreateTime(System.currentTimeMillis());
|
||||||
|
caseReview.setUpdateTime(System.currentTimeMillis());
|
||||||
|
caseReview.setReviewId(request.getReviewId());
|
||||||
|
caseReview.setStatus(TestCaseReviewStatus.Prepare.name());
|
||||||
|
batchMapper.insert(caseReview);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlSession.flushStatements();
|
||||||
|
|
||||||
|
TestCaseReview testCaseReview = testCaseReviewMapper.selectByPrimaryKey(request.getReviewId());
|
||||||
|
if (StringUtils.equals(testCaseReview.getStatus(), TestCaseReviewStatus.Prepare.name())
|
||||||
|
|| StringUtils.equals(testCaseReview.getStatus(), TestCaseReviewStatus.Completed.name())) {
|
||||||
|
testCaseReview.setStatus(TestCaseReviewStatus.Underway.name());
|
||||||
|
testCaseReviewMapper.updateByPrimaryKey(testCaseReview);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestCaseReview getTestReview(String reviewId) {
|
||||||
|
return Optional.ofNullable(testCaseReviewMapper.selectByPrimaryKey(reviewId)).orElse(new TestCaseReview());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,8 @@ public class TestCaseService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
TestCaseIssueService testCaseIssueService;
|
TestCaseIssueService testCaseIssueService;
|
||||||
|
@Resource
|
||||||
|
TestCaseReviewTestCaseMapper testCaseReviewTestCaseMapper;
|
||||||
|
|
||||||
public void addTestCase(TestCaseWithBLOBs testCase) {
|
public void addTestCase(TestCaseWithBLOBs testCase) {
|
||||||
testCase.setName(testCase.getName());
|
testCase.setName(testCase.getName());
|
||||||
|
@ -203,6 +205,25 @@ public class TestCaseService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TestCase> getReviewCase(QueryTestCaseRequest request) {
|
||||||
|
|
||||||
|
List<TestCase> testCases = extTestCaseMapper.getTestCaseNames(request);
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(request.getReviewId())) {
|
||||||
|
TestCaseReviewTestCaseExample testCaseReviewTestCaseExample = new TestCaseReviewTestCaseExample();
|
||||||
|
testCaseReviewTestCaseExample.createCriteria().andReviewIdEqualTo(request.getReviewId());
|
||||||
|
List<String> relevanceIds = testCaseReviewTestCaseMapper.selectByExample(testCaseReviewTestCaseExample).stream()
|
||||||
|
.map(TestCaseReviewTestCase::getCaseId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return testCases.stream()
|
||||||
|
.filter(testcase -> !relevanceIds.contains(testcase.getId()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return testCases;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<TestCase> recentTestPlans(QueryTestCaseRequest request, int count) {
|
public List<TestCase> recentTestPlans(QueryTestCaseRequest request, int count) {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.*;
|
||||||
|
import io.metersphere.base.mapper.ProjectMapper;
|
||||||
|
import io.metersphere.base.mapper.TestCaseReviewProjectMapper;
|
||||||
|
import io.metersphere.track.request.testreview.TestReviewRelevanceRequest;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class TestReviewProjectService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ProjectMapper projectMapper;
|
||||||
|
@Resource
|
||||||
|
TestCaseReviewProjectMapper testCaseReviewProjectMapper;
|
||||||
|
|
||||||
|
public List<String> getProjectIdsByPlanId(String reviewId) {
|
||||||
|
TestCaseReviewProjectExample example = new TestCaseReviewProjectExample();
|
||||||
|
example.createCriteria().andReviewIdEqualTo(reviewId);
|
||||||
|
List<String> projectIds = testCaseReviewProjectMapper.selectByExample(example)
|
||||||
|
.stream()
|
||||||
|
.map(TestCaseReviewProject::getProjectId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (projectIds.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return projectIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Project> getProject(TestReviewRelevanceRequest request) {
|
||||||
|
ProjectExample projectExample = new ProjectExample();
|
||||||
|
ProjectExample.Criteria criteria = projectExample.createCriteria();
|
||||||
|
criteria.andIdIn(request.getProjectIds());
|
||||||
|
if (StringUtils.isNotBlank(request.getName())) {
|
||||||
|
criteria.andNameLike(StringUtils.wrapIfMissing(request.getName(), "%"));
|
||||||
|
}
|
||||||
|
return projectMapper.selectByExample(projectExample);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.TestCaseReviewTestCaseExample;
|
||||||
|
import io.metersphere.base.domain.TestPlanTestCaseExample;
|
||||||
|
import io.metersphere.base.domain.User;
|
||||||
|
import io.metersphere.base.mapper.TestCaseReviewTestCaseMapper;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtTestReviewCaseMapper;
|
||||||
|
import io.metersphere.commons.utils.ServiceUtils;
|
||||||
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
|
import io.metersphere.controller.request.member.QueryMemberRequest;
|
||||||
|
import io.metersphere.service.UserService;
|
||||||
|
import io.metersphere.track.dto.TestReviewCaseDTO;
|
||||||
|
import io.metersphere.track.request.testplancase.TestReviewCaseBatchRequest;
|
||||||
|
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class TestReviewTestCaseService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ExtTestReviewCaseMapper extTestReviewCaseMapper;
|
||||||
|
@Resource
|
||||||
|
UserService userService;
|
||||||
|
@Resource
|
||||||
|
TestCaseReviewTestCaseMapper testCaseReviewTestCaseMapper;
|
||||||
|
|
||||||
|
public List<TestReviewCaseDTO> list(QueryCaseReviewRequest request) {
|
||||||
|
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
|
||||||
|
List<TestReviewCaseDTO> list = extTestReviewCaseMapper.list(request);
|
||||||
|
QueryMemberRequest queryMemberRequest = new QueryMemberRequest();
|
||||||
|
queryMemberRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||||
|
Map<String, String> userMap = userService.getMemberList(queryMemberRequest)
|
||||||
|
.stream().collect(Collectors.toMap(User::getId, User::getName));
|
||||||
|
list.forEach(item -> {
|
||||||
|
item.setReviewerName(userMap.get(item.getReviewer()));
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int deleteTestCase(String id) {
|
||||||
|
return testCaseReviewTestCaseMapper.deleteByPrimaryKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteTestCaseBath(TestReviewCaseBatchRequest request) {
|
||||||
|
TestCaseReviewTestCaseExample example = new TestCaseReviewTestCaseExample();
|
||||||
|
example.createCriteria().andIdIn(request.getIds());
|
||||||
|
testCaseReviewTestCaseMapper.deleteByExample(example);
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,22 +59,30 @@ export default {
|
||||||
result: {},
|
result: {},
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
projectId: '',
|
projectId: '',
|
||||||
planId: '',
|
id: '',
|
||||||
condition: {},
|
condition: {},
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 5,
|
pageSize: 5,
|
||||||
total: 0,
|
total: 0,
|
||||||
|
url: '',
|
||||||
|
type: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
open(planId) {
|
open(obj) {
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true;
|
||||||
this.planId = planId;
|
this.id = obj.id;
|
||||||
|
this.url = obj.url;
|
||||||
|
this.type = obj.type;
|
||||||
this.initData();
|
this.initData();
|
||||||
},
|
},
|
||||||
initData() {
|
initData() {
|
||||||
this.condition.planId = this.planId;
|
if (this.type === 'plan') {
|
||||||
this.result = this.$post("/test/plan/project/" + this.currentPage + "/" + this.pageSize, this.condition, res => {
|
this.condition.planId = this.id;
|
||||||
|
} else {
|
||||||
|
this.condition.reviewId = this.id;
|
||||||
|
}
|
||||||
|
this.result = this.$post(this.url + this.currentPage + "/" + this.pageSize, this.condition, res => {
|
||||||
const data = res.data;
|
const data = res.data;
|
||||||
this.total = data.itemCount;
|
this.total = data.itemCount;
|
||||||
this.tableData = data.listObject;
|
this.tableData = data.listObject;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<el-breadcrumb-item class="node-breadcrumb">
|
<el-breadcrumb-item class="node-breadcrumb">
|
||||||
<a @click="showAll" >
|
<a @click="showAll" >
|
||||||
<i class="el-icon-s-home"></i>
|
<i class="el-icon-s-home"></i>
|
||||||
{{$t('test_track.plan_view.all_case')}}
|
{{title}}
|
||||||
</a>
|
</a>
|
||||||
</el-breadcrumb-item>
|
</el-breadcrumb-item>
|
||||||
|
|
||||||
|
@ -22,6 +22,12 @@
|
||||||
props: {
|
props: {
|
||||||
nodes: {
|
nodes: {
|
||||||
type: Array
|
type: Array
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return this.$t('test_track.plan_view.all_case')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
@ -97,7 +97,7 @@ export default {
|
||||||
title: "最近的评审",
|
title: "最近的评审",
|
||||||
url: "/test/case/review/recent/5",
|
url: "/test/case/review/recent/5",
|
||||||
index: function (item) {
|
index: function (item) {
|
||||||
return '/test/case/review/' + item.id;
|
return '/track/review/view/' + item.id;
|
||||||
},
|
},
|
||||||
router: function (item) {
|
router: function (item) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,7 +267,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
switchProject() {
|
switchProject() {
|
||||||
this.$refs.switchProject.open(this.planId);
|
this.$refs.switchProject.open({id: this.planId, url: '/test/plan/project/',type: 'plan'});
|
||||||
},
|
},
|
||||||
getProjectNode(projectId) {
|
getProjectNode(projectId) {
|
||||||
const index = this.projects.findIndex(project => project.id === projectId);
|
const index = this.projects.findIndex(project => project.id === projectId);
|
||||||
|
|
|
@ -118,7 +118,7 @@ import MsDialogFooter from "../../../common/components/MsDialogFooter";
|
||||||
import MsTableHeader from "../../../common/components/MsTableHeader";
|
import MsTableHeader from "../../../common/components/MsTableHeader";
|
||||||
import MsCreateBox from "../../../settings/CreateBox";
|
import MsCreateBox from "../../../settings/CreateBox";
|
||||||
import MsTablePagination from "../../../common/pagination/TablePagination";
|
import MsTablePagination from "../../../common/pagination/TablePagination";
|
||||||
import {_filter, _sort, checkoutTestManagerOrTestUser} from "../../../../../common/js/utils";
|
import {_filter, _sort, checkoutTestManagerOrTestUser, getCurrentWorkspaceId} from "../../../../../common/js/utils";
|
||||||
import PlanStatusTableItem from "../../common/tableItems/plan/PlanStatusTableItem";
|
import PlanStatusTableItem from "../../common/tableItems/plan/PlanStatusTableItem";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -162,6 +162,8 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initTableData() {
|
initTableData() {
|
||||||
|
let lastWorkspaceId = getCurrentWorkspaceId();
|
||||||
|
this.condition.workspaceId = lastWorkspaceId;
|
||||||
this.result = this.$post("/test/case/review/list/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
this.result = this.$post("/test/case/review/list/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
this.total = data.itemCount;
|
this.total = data.itemCount;
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
<template>
|
||||||
|
<ms-container>
|
||||||
|
|
||||||
|
<ms-aside-container>
|
||||||
|
<select-menu
|
||||||
|
:data="testReviews"
|
||||||
|
:current-data="currentReview"
|
||||||
|
title="评审"
|
||||||
|
@dataChange="changeReview"/>
|
||||||
|
<node-tree class="node-tree"
|
||||||
|
v-loading="result.loading"
|
||||||
|
@nodeSelectEvent="nodeChange"
|
||||||
|
@refresh="refresh"
|
||||||
|
:tree-nodes="treeNodes"
|
||||||
|
:draggable="false"
|
||||||
|
ref="nodeTree"/>
|
||||||
|
</ms-aside-container>
|
||||||
|
|
||||||
|
<ms-main-container>
|
||||||
|
<test-review-test-case-list
|
||||||
|
class="table-list"
|
||||||
|
@openTestReviewRelevanceDialog="openTestReviewRelevanceDialog"
|
||||||
|
@refresh="refresh"
|
||||||
|
:review-id="reviewId"
|
||||||
|
:select-node-ids="selectNodeIds"
|
||||||
|
:select-parent-nodes="selectParentNodes"
|
||||||
|
ref="testPlanTestCaseList"/>
|
||||||
|
</ms-main-container>
|
||||||
|
|
||||||
|
<test-review-relevance
|
||||||
|
@refresh="refresh"
|
||||||
|
:review-id="reviewId"
|
||||||
|
ref="testReviewRelevance"/>
|
||||||
|
|
||||||
|
</ms-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
import MsMainContainer from "../../../common/components/MsMainContainer";
|
||||||
|
import MsAsideContainer from "../../../common/components/MsAsideContainer";
|
||||||
|
import MsContainer from "../../../common/components/MsContainer";
|
||||||
|
import NodeTree from "../../common/NodeTree";
|
||||||
|
import TestReviewTestCaseList from "./components/TestReviewTestCaseList";
|
||||||
|
import SelectMenu from "../../common/SelectMenu";
|
||||||
|
import TestReviewRelevance from "./components/TestReviewRelevance";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestCaseReviewView",
|
||||||
|
components: {
|
||||||
|
MsMainContainer,
|
||||||
|
MsAsideContainer,
|
||||||
|
MsContainer,
|
||||||
|
NodeTree,
|
||||||
|
TestReviewTestCaseList,
|
||||||
|
TestReviewRelevance,
|
||||||
|
SelectMenu
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
result: {},
|
||||||
|
testReviews: [],
|
||||||
|
currentReview: {},
|
||||||
|
selectNodeIds: [],
|
||||||
|
selectParentNodes: [],
|
||||||
|
treeNodes: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
reviewId: function () {
|
||||||
|
return this.$route.params.reviewId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initData();
|
||||||
|
this.openTestCaseEdit(this.$route.path);
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$route'(to, from) {
|
||||||
|
this.openTestCaseEdit(to.path);
|
||||||
|
},
|
||||||
|
reviewId() {
|
||||||
|
this.initData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
refresh() {
|
||||||
|
this.selectNodeIds = [];
|
||||||
|
this.selectParentNodes = [];
|
||||||
|
this.getNodeTreeByReviewId();
|
||||||
|
},
|
||||||
|
initData() {
|
||||||
|
this.getTestReviews();
|
||||||
|
this.getNodeTreeByReviewId();
|
||||||
|
},
|
||||||
|
openTestReviewRelevanceDialog() {
|
||||||
|
this.$refs.testReviewRelevance.openTestReviewRelevanceDialog();
|
||||||
|
},
|
||||||
|
getTestReviews() {
|
||||||
|
this.result = this.$post('/test/case/review/list/all', {}, response => {
|
||||||
|
this.testReviews = response.data;
|
||||||
|
this.testReviews.forEach(review => {
|
||||||
|
if (this.reviewId && review.id === this.reviewId) {
|
||||||
|
this.currentReview = review;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
nodeChange(nodeIds, pNodes) {
|
||||||
|
this.selectNodeIds = nodeIds;
|
||||||
|
this.selectParentNodes = pNodes;
|
||||||
|
},
|
||||||
|
changeReview(review) {
|
||||||
|
this.currentReview = review;
|
||||||
|
this.$router.push('/track/review/view/' + review.id);
|
||||||
|
},
|
||||||
|
getNodeTreeByReviewId() {
|
||||||
|
if (this.reviewId) {
|
||||||
|
this.result = this.$get("/case/node/list/review/" + this.reviewId, response => {
|
||||||
|
this.treeNodes = response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openTestCaseEdit(path) {
|
||||||
|
if (path.indexOf("/review/view/edit") >= 0) {
|
||||||
|
let caseId = this.$route.params.caseId;
|
||||||
|
this.$get('/test/review/case/get/' + caseId, response => {
|
||||||
|
let testCase = response.data;
|
||||||
|
if (testCase) {
|
||||||
|
this.$refs.testPlanTestCaseList.handleEdit(testCase);
|
||||||
|
this.$router.push('/track/review/view/' + testCase.reviewId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,339 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<el-dialog title="关联测试评审"
|
||||||
|
:visible.sync="dialogFormVisible"
|
||||||
|
@close="close"
|
||||||
|
width="60%" v-loading="result.loading"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
top="50px">
|
||||||
|
|
||||||
|
<el-container class="main-content">
|
||||||
|
<el-aside class="tree-aside" width="250px">
|
||||||
|
<el-link type="primary" class="project-link" @click="switchProject">{{projectName ? projectName : '切换项目' }}</el-link>
|
||||||
|
<node-tree class="node-tree"
|
||||||
|
@nodeSelectEvent="nodeChange"
|
||||||
|
@refresh="refresh"
|
||||||
|
:tree-nodes="treeNodes"
|
||||||
|
ref="nodeTree"/>
|
||||||
|
</el-aside>
|
||||||
|
|
||||||
|
<el-container>
|
||||||
|
<el-main class="case-content">
|
||||||
|
<ms-table-header :condition.sync="condition" @search="getReviews" title="" :show-create="false"/>
|
||||||
|
<el-table
|
||||||
|
:data="testReviews"
|
||||||
|
@filter-change="filter"
|
||||||
|
row-key="id"
|
||||||
|
@select-all="handleSelectAll"
|
||||||
|
@select="handleSelectionChange"
|
||||||
|
height="50vh"
|
||||||
|
ref="table">
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
type="selection"/>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="name"
|
||||||
|
:label="$t('test_track.case.name')"
|
||||||
|
style="width: 100%">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
{{scope.row.name}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="priority"
|
||||||
|
:filters="priorityFilters"
|
||||||
|
column-key="priority"
|
||||||
|
:label="$t('test_track.case.priority')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<priority-table-item :value="scope.row.priority"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="type"
|
||||||
|
:filters="typeFilters"
|
||||||
|
column-key="type"
|
||||||
|
:label="$t('test_track.case.type')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<type-table-item :value="scope.row.type"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div style="text-align: center">共 {{testReviews.length}} 条</div>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</el-container>
|
||||||
|
|
||||||
|
<template v-slot:footer>
|
||||||
|
<ms-dialog-footer @cancel="dialogFormVisible = false" @confirm="saveReviewRelevance"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<switch-project ref="switchProject" @getProjectNode="getProjectNode"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import NodeTree from "../../../common/NodeTree";
|
||||||
|
import MsDialogFooter from "../../../../common/components/MsDialogFooter";
|
||||||
|
import PriorityTableItem from "../../../common/tableItems/planview/PriorityTableItem";
|
||||||
|
import TypeTableItem from "../../../common/tableItems/planview/TypeTableItem";
|
||||||
|
import MsTableSearchBar from "../../../../common/components/MsTableSearchBar";
|
||||||
|
import MsTableAdvSearchBar from "../../../../common/components/search/MsTableAdvSearchBar";
|
||||||
|
import MsTableHeader from "../../../../common/components/MsTableHeader";
|
||||||
|
import SwitchProject from "../../../case/components/SwitchProject";
|
||||||
|
import {TEST_CASE_CONFIGS} from "../../../../common/components/search/search-components";
|
||||||
|
import {_filter} from "../../../../../../common/js/utils";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestReviewRelevance",
|
||||||
|
components: {
|
||||||
|
NodeTree,
|
||||||
|
MsDialogFooter,
|
||||||
|
PriorityTableItem,
|
||||||
|
TypeTableItem,
|
||||||
|
MsTableSearchBar,
|
||||||
|
MsTableAdvSearchBar,
|
||||||
|
MsTableHeader,
|
||||||
|
SwitchProject
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
result: {},
|
||||||
|
dialogFormVisible: false,
|
||||||
|
isCheckAll: false,
|
||||||
|
testReviews: [],
|
||||||
|
selectIds: new Set(),
|
||||||
|
treeNodes: [],
|
||||||
|
selectNodeIds: [],
|
||||||
|
selectNodeNames: [],
|
||||||
|
projectId: '',
|
||||||
|
projectName: '',
|
||||||
|
projects: [],
|
||||||
|
condition: {
|
||||||
|
components: TEST_CASE_CONFIGS
|
||||||
|
},
|
||||||
|
priorityFilters: [
|
||||||
|
{text: 'P0', value: 'P0'},
|
||||||
|
{text: 'P1', value: 'P1'},
|
||||||
|
{text: 'P2', value: 'P2'},
|
||||||
|
{text: 'P3', value: 'P3'}
|
||||||
|
],
|
||||||
|
typeFilters: [
|
||||||
|
{text: this.$t('commons.functional'), value: 'functional'},
|
||||||
|
{text: this.$t('commons.performance'), value: 'performance'},
|
||||||
|
{text: this.$t('commons.api'), value: 'api'}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
reviewId: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
reviewId() {
|
||||||
|
this.initData();
|
||||||
|
},
|
||||||
|
selectNodeIds() {
|
||||||
|
this.getReviews();
|
||||||
|
},
|
||||||
|
projectId() {
|
||||||
|
this.getProjectNode();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
this.toggleSelection(this.testReviews);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openTestReviewRelevanceDialog() {
|
||||||
|
this.initData();
|
||||||
|
this.dialogFormVisible = true;
|
||||||
|
},
|
||||||
|
saveReviewRelevance() {
|
||||||
|
let param = {};
|
||||||
|
param.reviewId = this.reviewId;
|
||||||
|
param.testCaseIds = [...this.selectIds];
|
||||||
|
this.result = this.$post('/test/case/review/relevance', param, () => {
|
||||||
|
this.selectIds.clear();
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.dialogFormVisible = false;
|
||||||
|
this.$emit('refresh');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getReviews() {
|
||||||
|
if (this.reviewId) {
|
||||||
|
this.condition.reviewId = this.reviewId;
|
||||||
|
}
|
||||||
|
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
|
||||||
|
this.condition.nodeIds = this.selectNodeIds;
|
||||||
|
} else {
|
||||||
|
this.condition.nodeIds = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.projectId) {
|
||||||
|
this.condition.projectId = this.projectId;
|
||||||
|
this.result = this.$post('/test/case/reviews/case', this.condition, response => {
|
||||||
|
this.testReviews = response.data;
|
||||||
|
this.testReviews.forEach(item => {
|
||||||
|
item.checked = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
handleSelectAll(selection) {
|
||||||
|
if (selection.length > 0) {
|
||||||
|
this.testReviews.forEach(item => {
|
||||||
|
this.selectIds.add(item.id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// this.selectIds.clear();
|
||||||
|
this.testReviews.forEach(item => {
|
||||||
|
if (this.selectIds.has(item.id)) {
|
||||||
|
this.selectIds.delete(item.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSelectionChange(selection, row) {
|
||||||
|
if (this.selectIds.has(row.id)) {
|
||||||
|
this.selectIds.delete(row.id);
|
||||||
|
} else {
|
||||||
|
this.selectIds.add(row.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nodeChange(nodeIds, nodeNames) {
|
||||||
|
this.selectNodeIds = nodeIds;
|
||||||
|
this.selectNodeNames = nodeNames;
|
||||||
|
},
|
||||||
|
initData() {
|
||||||
|
this.getReviews();
|
||||||
|
this.getAllNodeTreeByPlanId();
|
||||||
|
this.getProject();
|
||||||
|
},
|
||||||
|
refresh() {
|
||||||
|
this.close();
|
||||||
|
},
|
||||||
|
getAllNodeTreeByPlanId() {
|
||||||
|
if (this.reviewId) {
|
||||||
|
let param = {
|
||||||
|
testPlanId: this.reviewId,
|
||||||
|
projectId: this.projectId
|
||||||
|
};
|
||||||
|
this.result = this.$post("/case/node/list/all/review", param , response => {
|
||||||
|
this.treeNodes = response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.selectIds.clear();
|
||||||
|
this.selectNodeIds = [];
|
||||||
|
this.selectNodeNames = [];
|
||||||
|
},
|
||||||
|
filter(filters) {
|
||||||
|
_filter(filters, this.condition);
|
||||||
|
this.initData();
|
||||||
|
},
|
||||||
|
toggleSelection(rows) {
|
||||||
|
rows.forEach(row => {
|
||||||
|
this.selectIds.forEach(id => {
|
||||||
|
if (row.id === id) {
|
||||||
|
// true 是为选中
|
||||||
|
this.$refs.table.toggleRowSelection(row, true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getProject() {
|
||||||
|
if (this.reviewId) {
|
||||||
|
this.$post("/test/case/review/projects", {reviewId: this.reviewId},res => {
|
||||||
|
let data = res.data;
|
||||||
|
if (data) {
|
||||||
|
this.projects = data;
|
||||||
|
this.projectId = data[0].id;
|
||||||
|
this.projectName = data[0].name;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
switchProject() {
|
||||||
|
this.$refs.switchProject.open({id: this.reviewId, url : '/test/case/review/project/', type: 'review'});
|
||||||
|
},
|
||||||
|
getProjectNode(projectId) {
|
||||||
|
const index = this.projects.findIndex(project => project.id === projectId);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.projectName = this.projects[index].name;
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
this.projectId = projectId;
|
||||||
|
}
|
||||||
|
this.result = this.$post("/case/node/list/all/review",
|
||||||
|
{reviewId: this.reviewId, projectId: this.projectId} , response => {
|
||||||
|
this.treeNodes = response.data;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selectNodeIds = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.tb-edit .el-input {
|
||||||
|
display: none;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tb-edit .current-row .el-input {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.tb-edit .current-row .el-input + span {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-tree {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-header {
|
||||||
|
background-color: darkgrey;
|
||||||
|
color: #333;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.case-content {
|
||||||
|
padding: 0px 20px;
|
||||||
|
height: 100%;
|
||||||
|
/*border: 1px solid #EBEEF5;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-aside {
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
min-height: 300px;
|
||||||
|
height: 100%;
|
||||||
|
/*border: 1px solid #EBEEF5;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-link {
|
||||||
|
float: right;
|
||||||
|
margin-right: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TestReviewTestCaseEdit"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,540 @@
|
||||||
|
<template>
|
||||||
|
<div class="card-container">
|
||||||
|
<el-card class="card-content" v-loading="result.loading">
|
||||||
|
<template v-slot:header>
|
||||||
|
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="initTableData"
|
||||||
|
:show-create="false" :tip="$t('commons.search_by_name_or_id')">
|
||||||
|
<template v-slot:title>
|
||||||
|
<node-breadcrumb class="table-title" :nodes="selectParentNodes" @refresh="refresh" title="全部评审"/>
|
||||||
|
</template>
|
||||||
|
<template v-slot:button>
|
||||||
|
<ms-table-button :is-tester-permission="true" icon="el-icon-video-play"
|
||||||
|
content="开始用例评审" @click="startReview"/>
|
||||||
|
<ms-table-button :is-tester-permission="true" icon="el-icon-connection"
|
||||||
|
content="关联用例评审"
|
||||||
|
@click="$emit('openTestReviewRelevanceDialog')"/>
|
||||||
|
</template>
|
||||||
|
</ms-table-header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<executor-edit ref="executorEdit" :select-ids="new Set(Array.from(this.selectRows).map(row => row.id))"
|
||||||
|
@refresh="initTableData"/>
|
||||||
|
<status-edit ref="statusEdit" :plan-id="reviewId"
|
||||||
|
:select-ids="new Set(Array.from(this.selectRows).map(row => row.id))" @refresh="initTableData"/>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
class="adjust-table"
|
||||||
|
border
|
||||||
|
@select-all="handleSelectAll"
|
||||||
|
@filter-change="filter"
|
||||||
|
@sort-change="sort"
|
||||||
|
@select="handleSelectionChange"
|
||||||
|
row-key="id"
|
||||||
|
@row-click="showDetail"
|
||||||
|
:data="tableData">
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
type="selection"/>
|
||||||
|
<el-table-column width="40" :resizable="false" align="center">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectRows.size"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="num"
|
||||||
|
sortable="custom"
|
||||||
|
:label="$t('commons.id')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="name"
|
||||||
|
:label="$t('commons.name')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="priority"
|
||||||
|
:filters="priorityFilters"
|
||||||
|
column-key="priority"
|
||||||
|
:label="$t('test_track.case.priority')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<priority-table-item :value="scope.row.priority" ref="priority"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="type"
|
||||||
|
:filters="typeFilters"
|
||||||
|
column-key="type"
|
||||||
|
:label="$t('test_track.case.type')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<type-table-item :value="scope.row.type"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="method"
|
||||||
|
:filters="methodFilters"
|
||||||
|
column-key="method"
|
||||||
|
:label="$t('test_track.case.method')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<method-table-item :value="scope.row.method"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="nodePath"
|
||||||
|
:label="$t('test_track.case.module')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="projectName"
|
||||||
|
:label="$t('test_track.plan.plan_project')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('test_track.issue.issue')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<el-popover
|
||||||
|
placement="right"
|
||||||
|
width="400"
|
||||||
|
trigger="hover">
|
||||||
|
<el-table border class="adjust-table" :data="scope.row.issuesContent" style="width: 100%">
|
||||||
|
<el-table-column prop="title" :label="$t('test_track.issue.title')" show-overflow-tooltip/>
|
||||||
|
<el-table-column prop="description" :label="$t('test_track.issue.description')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<el-popover
|
||||||
|
placement="left"
|
||||||
|
width="400"
|
||||||
|
trigger="hover"
|
||||||
|
>
|
||||||
|
<ckeditor :editor="editor" disabled :config="editorConfig"
|
||||||
|
v-model="scope.row.description"/>
|
||||||
|
<el-button slot="reference" type="text">{{$t('test_track.issue.preview')}}</el-button>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="platform" :label="$t('test_track.issue.platform')"/>
|
||||||
|
</el-table>
|
||||||
|
<el-button slot="reference" type="text">{{scope.row.issuesSize}}</el-button>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="reviewerName"
|
||||||
|
:label="$t('test_track.plan_view.executor')">
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
:filters="statusFilters"
|
||||||
|
column-key="status"
|
||||||
|
:label="$t('test_track.plan_view.execute_result')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span @click.stop="clickt = 'stop'">
|
||||||
|
<el-dropdown class="test-case-status" @command="statusChange">
|
||||||
|
<span class="el-dropdown-link">
|
||||||
|
<status-table-item :value="scope.row.status"/>
|
||||||
|
</span>
|
||||||
|
<el-dropdown-menu slot="dropdown" chang>
|
||||||
|
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Pass'}">
|
||||||
|
{{$t('test_track.plan_view.pass')}}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
|
||||||
|
:command="{id: scope.row.id, status: 'Failure'}">
|
||||||
|
{{$t('test_track.plan_view.failure')}}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
|
||||||
|
:command="{id: scope.row.id, status: 'Blocking'}">
|
||||||
|
{{$t('test_track.plan_view.blocking')}}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Skip'}">
|
||||||
|
{{$t('test_track.plan_view.skip')}}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
sortable
|
||||||
|
prop="updateTime"
|
||||||
|
:label="$t('commons.update_time')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('commons.operating')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<ms-table-operator-button :is-tester-permission="true" :tip="$t('commons.edit')" icon="el-icon-edit"
|
||||||
|
@exec="handleEdit(scope.row)"/>
|
||||||
|
<ms-table-operator-button :is-tester-permission="true" :tip="$t('test_track.plan_view.cancel_relevance')"
|
||||||
|
icon="el-icon-unlock" type="danger" @exec="handleDelete(scope.row)"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||||
|
:total="total"/>
|
||||||
|
|
||||||
|
<test-review-test-case-edit
|
||||||
|
ref="testReviewTestCaseEdit"
|
||||||
|
:search-param="condition"
|
||||||
|
@refresh="initTableData"
|
||||||
|
:is-read-only="isReadOnly"
|
||||||
|
@refreshTable="search"/>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
<batch-edit ref="batchEdit" @batchEdit="batchEdit"
|
||||||
|
:type-arr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_case')"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
|
||||||
|
import MsTableOperatorButton from "../../../../common/components/MsTableOperatorButton";
|
||||||
|
import MsTableOperator from "../../../../common/components/MsTableOperator";
|
||||||
|
import MethodTableItem from "../../../common/tableItems/planview/MethodTableItem";
|
||||||
|
import TypeTableItem from "../../../common/tableItems/planview/TypeTableItem";
|
||||||
|
import StatusTableItem from "../../../common/tableItems/planview/StatusTableItem";
|
||||||
|
import PriorityTableItem from "../../../common/tableItems/planview/PriorityTableItem";
|
||||||
|
import StatusEdit from "../../../plan/view/comonents/StatusEdit";
|
||||||
|
import ExecutorEdit from "../../../plan/view/comonents/ExecutorEdit";
|
||||||
|
import MsTipButton from "../../../../common/components/MsTipButton";
|
||||||
|
import MsTableHeader from "../../../../common/components/MsTableHeader";
|
||||||
|
import NodeBreadcrumb from "../../../common/NodeBreadcrumb";
|
||||||
|
import MsTableButton from "../../../../common/components/MsTableButton";
|
||||||
|
import ShowMoreBtn from "../../../case/components/ShowMoreBtn";
|
||||||
|
import BatchEdit from "../../../case/components/BatchEdit";
|
||||||
|
import MsTablePagination from '../../../../common/pagination/TablePagination';
|
||||||
|
import {_filter, _sort, checkoutTestManagerOrTestUser, hasRoles} from "../../../../../../common/js/utils";
|
||||||
|
import {TEST_CASE_CONFIGS} from "../../../../common/components/search/search-components";
|
||||||
|
import {ROLE_TEST_MANAGER, ROLE_TEST_USER, TokenKey, WORKSPACE_ID} from "../../../../../../common/js/constants";
|
||||||
|
import TestReviewTestCaseEdit from "./TestReviewTestCaseEdit";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestReviewTestCaseList",
|
||||||
|
components: {
|
||||||
|
MsTableOperatorButton, MsTableOperator, MethodTableItem, TypeTableItem,
|
||||||
|
StatusTableItem, PriorityTableItem, StatusEdit,
|
||||||
|
ExecutorEdit, MsTipButton, TestReviewTestCaseEdit, MsTableHeader,
|
||||||
|
NodeBreadcrumb, MsTableButton, ShowMoreBtn, BatchEdit, MsTablePagination
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
result: {},
|
||||||
|
condition: {
|
||||||
|
components: TEST_CASE_CONFIGS
|
||||||
|
},
|
||||||
|
tableData: [],
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
selectRows: new Set(),
|
||||||
|
testPlan: {},
|
||||||
|
isReadOnly: false,
|
||||||
|
isTestManagerOrTestUser: false,
|
||||||
|
priorityFilters: [
|
||||||
|
{text: 'P0', value: 'P0'},
|
||||||
|
{text: 'P1', value: 'P1'},
|
||||||
|
{text: 'P2', value: 'P2'},
|
||||||
|
{text: 'P3', value: 'P3'}
|
||||||
|
],
|
||||||
|
methodFilters: [
|
||||||
|
{text: this.$t('test_track.case.manual'), value: 'manual'},
|
||||||
|
{text: this.$t('test_track.case.auto'), value: 'auto'}
|
||||||
|
],
|
||||||
|
typeFilters: [
|
||||||
|
{text: this.$t('commons.functional'), value: 'functional'},
|
||||||
|
{text: this.$t('commons.performance'), value: 'performance'},
|
||||||
|
{text: this.$t('commons.api'), value: 'api'}
|
||||||
|
],
|
||||||
|
statusFilters: [
|
||||||
|
{text: this.$t('test_track.plan.plan_status_prepare'), value: 'Prepare'},
|
||||||
|
{text: this.$t('test_track.plan_view.pass'), value: 'Pass'},
|
||||||
|
{text: this.$t('test_track.plan_view.failure'), value: 'Failure'},
|
||||||
|
{text: this.$t('test_track.plan_view.blocking'), value: 'Blocking'},
|
||||||
|
{text: this.$t('test_track.plan_view.skip'), value: 'Skip'},
|
||||||
|
{text: this.$t('test_track.plan.plan_status_running'), value: 'Underway'},
|
||||||
|
],
|
||||||
|
showMore: false,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
name: this.$t('test_track.case.batch_edit_case'), handleClick: this.handleBatchEdit
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: this.$t('test_track.case.batch_unlink'), handleClick: this.handleDeleteBatch
|
||||||
|
}
|
||||||
|
],
|
||||||
|
typeArr: [
|
||||||
|
{id: 'status', name: this.$t('test_track.plan_view.execute_result')},
|
||||||
|
{id: 'executor', name: this.$t('test_track.plan_view.executor')},
|
||||||
|
],
|
||||||
|
valueArr: {
|
||||||
|
executor: [],
|
||||||
|
status: [
|
||||||
|
{name: this.$t('test_track.plan_view.pass'), id: 'Pass'},
|
||||||
|
{name: this.$t('test_track.plan_view.failure'), id: 'Failure'},
|
||||||
|
{name: this.$t('test_track.plan_view.blocking'), id: 'Blocking'},
|
||||||
|
{name: this.$t('test_track.plan_view.skip'), id: 'Skip'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
editor: ClassicEditor,
|
||||||
|
editorConfig: {
|
||||||
|
toolbar: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
reviewId: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
selectNodeIds: {
|
||||||
|
type: Array
|
||||||
|
},
|
||||||
|
selectParentNodes: {
|
||||||
|
type: Array
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
reviewId() {
|
||||||
|
this.refreshTableAndReview();
|
||||||
|
},
|
||||||
|
selectNodeIds() {
|
||||||
|
this.search();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.refreshTableAndReview();
|
||||||
|
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initTableData() {
|
||||||
|
if (this.reviewId) {
|
||||||
|
this.condition.reviewId = this.reviewId;
|
||||||
|
}
|
||||||
|
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
|
||||||
|
this.condition.nodeIds = this.selectNodeIds;
|
||||||
|
}
|
||||||
|
if (this.reviewId) {
|
||||||
|
this.result = this.$post(this.buildPagePath('/test/review/case/list'), this.condition, response => {
|
||||||
|
let data = response.data;
|
||||||
|
this.total = data.itemCount;
|
||||||
|
this.tableData = data.listObject;
|
||||||
|
for (let i = 0; i < this.tableData.length; i++) {
|
||||||
|
if (this.tableData[i]) {
|
||||||
|
this.$set(this.tableData[i], "issuesSize", 0);
|
||||||
|
this.$get("/issues/get/" + this.tableData[i].caseId, response => {
|
||||||
|
let issues = response.data;
|
||||||
|
if (this.tableData[i]) {
|
||||||
|
this.$set(this.tableData[i], "issuesSize", issues.length);
|
||||||
|
this.$set(this.tableData[i], "issuesContent", issues);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.selectRows.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showDetail(row, event, column) {
|
||||||
|
this.isReadOnly = true;
|
||||||
|
this.$refs.testReviewTestCaseEdit.openTestCaseEdit(row);
|
||||||
|
},
|
||||||
|
refresh() {
|
||||||
|
this.condition = {components: TEST_CASE_CONFIGS};
|
||||||
|
this.selectRows.clear();
|
||||||
|
this.$emit('refresh');
|
||||||
|
},
|
||||||
|
refreshTableAndReview() {
|
||||||
|
this.getTestReviewById();
|
||||||
|
this.initTableData();
|
||||||
|
},
|
||||||
|
refreshTestReviewRecent() {
|
||||||
|
if (hasRoles(ROLE_TEST_USER, ROLE_TEST_MANAGER)) {
|
||||||
|
let param = {};
|
||||||
|
param.id = this.reviewId;
|
||||||
|
param.updateTime = Date.now();
|
||||||
|
this.$post('/test/plan/edit', param);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
this.initTableData();
|
||||||
|
},
|
||||||
|
buildPagePath(path) {
|
||||||
|
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||||
|
},
|
||||||
|
handleEdit(testCase, index) {
|
||||||
|
this.isReadOnly = false;
|
||||||
|
if (!checkoutTestManagerOrTestUser()) {
|
||||||
|
this.isReadOnly = true;
|
||||||
|
}
|
||||||
|
this.$refs.testReviewTestCaseEdit.openTestCaseEdit(testCase);
|
||||||
|
},
|
||||||
|
handleDelete(testCase) {
|
||||||
|
this.$alert(this.$t('test_track.plan_view.confirm_cancel_relevance') + ' ' + testCase.name + " ?", '', {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
this._handleDelete(testCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleDeleteBatch() {
|
||||||
|
this.$alert(this.$t('test_track.plan_view.confirm_cancel_relevance') + " ?", '', {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
let ids = Array.from(this.selectRows).map(row => row.id);
|
||||||
|
this.$post('/test/review/case/batch/delete', {ids: ids}, () => {
|
||||||
|
this.selectRows.clear();
|
||||||
|
this.$emit("refresh");
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_handleDelete(testCase) {
|
||||||
|
let testCaseId = testCase.id;
|
||||||
|
this.$post('/test/review/case/delete/' + testCaseId, {}, () => {
|
||||||
|
this.$emit("refresh");
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleSelectAll(selection) {
|
||||||
|
if (selection.length > 0) {
|
||||||
|
if (selection.length === 1) {
|
||||||
|
this.selectRows.add(selection[0]);
|
||||||
|
} else {
|
||||||
|
this.tableData.forEach(item => {
|
||||||
|
this.$set(item, "showMore", true);
|
||||||
|
this.selectRows.add(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.selectRows.clear();
|
||||||
|
this.tableData.forEach(row => {
|
||||||
|
this.$set(row, "showMore", false);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSelectionChange(selection, row) {
|
||||||
|
if (this.selectRows.has(row)) {
|
||||||
|
this.$set(row, "showMore", false);
|
||||||
|
this.selectRows.delete(row);
|
||||||
|
} else {
|
||||||
|
this.$set(row, "showMore", true);
|
||||||
|
this.selectRows.add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
let arr = Array.from(this.selectRows);
|
||||||
|
|
||||||
|
// 选中1个以上的用例时显示更多操作
|
||||||
|
if (this.selectRows.size === 1) {
|
||||||
|
this.$set(arr[0], "showMore", false);
|
||||||
|
} else if (this.selectRows.size === 2) {
|
||||||
|
arr.forEach(row => {
|
||||||
|
this.$set(row, "showMore", true);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleBatch(type) {
|
||||||
|
if (this.selectRows.size < 1) {
|
||||||
|
this.$warning(this.$t('test_track.plan_view.select_manipulate'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type === 'executor') {
|
||||||
|
this.$refs.executorEdit.openExecutorEdit();
|
||||||
|
} else if (type === 'status') {
|
||||||
|
this.$refs.statusEdit.openStatusEdit();
|
||||||
|
} else if (type === 'delete') {
|
||||||
|
this.handleDeleteBatch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openTestReport() {
|
||||||
|
this.$refs.testReportTemplateList.open(this.reviewId);
|
||||||
|
},
|
||||||
|
statusChange(param) {
|
||||||
|
this.$post('/test/plan/case/edit', param, () => {
|
||||||
|
for (let i = 0; i < this.tableData.length; i++) {
|
||||||
|
if (this.tableData[i].id == param.id) {
|
||||||
|
this.tableData[i].status = param.status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getTestReviewById() {
|
||||||
|
if (this.reviewId) {
|
||||||
|
this.$post('/test/case/review/get/' + this.reviewId, {}, response => {
|
||||||
|
this.testPlan = response.data;
|
||||||
|
this.refreshTestReviewRecent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filter(filters) {
|
||||||
|
_filter(filters, this.condition);
|
||||||
|
this.initTableData();
|
||||||
|
},
|
||||||
|
sort(column) {
|
||||||
|
// 每次只对一个字段排序
|
||||||
|
if (this.condition.orders) {
|
||||||
|
this.condition.orders = [];
|
||||||
|
}
|
||||||
|
_sort(column, this.condition);
|
||||||
|
this.initTableData();
|
||||||
|
},
|
||||||
|
batchEdit(form) {
|
||||||
|
let param = {};
|
||||||
|
param[form.type] = form.value;
|
||||||
|
param.ids = Array.from(this.selectRows).map(row => row.id);
|
||||||
|
this.$post('/test/plan/case/batch/edit', param, () => {
|
||||||
|
this.selectRows.clear();
|
||||||
|
this.status = '';
|
||||||
|
this.$post('/test/plan/edit/status/' + this.reviewId);
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.$emit('refresh');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleBatchEdit() {
|
||||||
|
this.getMaintainerOptions();
|
||||||
|
this.$refs.batchEdit.open();
|
||||||
|
},
|
||||||
|
getMaintainerOptions() {
|
||||||
|
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||||
|
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||||
|
this.valueArr.executor = response.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
startReview() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.search {
|
||||||
|
margin-left: 10px;
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-case-status, .el-table {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
|
@ -5,6 +5,7 @@ const TrackHome = () => import(/* webpackChunkName: "track" */ '@/business/compo
|
||||||
const TestCase = () => import(/* webpackChunkName: "track" */ '@/business/components/track/case/TestCase')
|
const TestCase = () => import(/* webpackChunkName: "track" */ '@/business/components/track/case/TestCase')
|
||||||
const TestPlan = () => import(/* webpackChunkName: "track" */ '@/business/components/track/plan/TestPlan')
|
const TestPlan = () => import(/* webpackChunkName: "track" */ '@/business/components/track/plan/TestPlan')
|
||||||
const TestCaseReview = () => import(/* webpackChunkName: "track" */ '@/business/components/track/review/TestCaseReview')
|
const TestCaseReview = () => import(/* webpackChunkName: "track" */ '@/business/components/track/review/TestCaseReview')
|
||||||
|
const TestCaseReviewView = () => import(/* webpackChunkName: "track" */ '@/business/components/track/review/view/TestCaseReviewView')
|
||||||
const TestPlanView = () => import(/* webpackChunkName: "track" */ '@/business/components/track/plan/view/TestPlanView')
|
const TestPlanView = () => import(/* webpackChunkName: "track" */ '@/business/components/track/plan/view/TestPlanView')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -60,5 +61,10 @@ export default {
|
||||||
name: "testCaseReview",
|
name: "testCaseReview",
|
||||||
component: TestCaseReview
|
component: TestCaseReview
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "review/view/:reviewId",
|
||||||
|
name: "testCaseReviewView",
|
||||||
|
component: TestCaseReviewView
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue