feat(测试跟踪): 用例评审CURD
This commit is contained in:
parent
77ebb23127
commit
92f91fcb48
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
|
import io.metersphere.track.dto.TestCaseReviewDTO;
|
||||||
|
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ExtTestCaseReviewMapper {
|
||||||
|
|
||||||
|
List<TestCaseReviewDTO> list(@Param("request") QueryCaseReviewRequest params);
|
||||||
|
|
||||||
|
List<TestCaseReviewDTO> listByWorkspaceId(@Param("workspaceId") String workspaceId);
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?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.ExtTestCaseReviewMapper">
|
||||||
|
|
||||||
|
<select id="list" resultType="io.metersphere.track.dto.TestCaseReviewDTO" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
||||||
|
select test_case_review.* from test_case_review
|
||||||
|
<where>
|
||||||
|
<if test="request.name != null">
|
||||||
|
and test_case_review.name like CONCAT('%', #{request.name},'%')
|
||||||
|
</if>
|
||||||
|
<if test="request.id != null">
|
||||||
|
AND test_case_review.id = #{request.id}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
<if test="request.orders != null and request.orders.size() > 0">
|
||||||
|
order by
|
||||||
|
<foreach collection="request.orders" separator="," item="order">
|
||||||
|
test_case_review.${order.name} ${order.type}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="listByWorkspaceId" resultType="io.metersphere.track.dto.TestCaseReviewDTO" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
||||||
|
select distinct test_case_review.*
|
||||||
|
from test_case_review, project, test_case_review_project
|
||||||
|
where test_case_review.id = test_case_review_project.review_id
|
||||||
|
and test_case_review_project.project_id = project.id
|
||||||
|
and project.workspace_id = #{workspaceId}
|
||||||
|
</select>
|
||||||
|
</mapper>
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
|
public enum TestCaseReviewStatus {
|
||||||
|
Prepare, Underway, Completed
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
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.TestCaseReview;
|
||||||
|
import io.metersphere.base.domain.User;
|
||||||
|
import io.metersphere.commons.constants.RoleConstants;
|
||||||
|
import io.metersphere.commons.utils.PageUtils;
|
||||||
|
import io.metersphere.commons.utils.Pager;
|
||||||
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
|
import io.metersphere.track.dto.TestCaseReviewDTO;
|
||||||
|
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||||
|
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
||||||
|
import io.metersphere.track.service.TestCaseReviewService;
|
||||||
|
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/case/review")
|
||||||
|
@RestController
|
||||||
|
public class TestCaseReviewController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
TestCaseReviewService testCaseReviewService;
|
||||||
|
|
||||||
|
@PostMapping("/list/{goPage}/{pageSize}")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public Pager<List<TestCaseReviewDTO>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryCaseReviewRequest request) {
|
||||||
|
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||||
|
return PageUtils.setPageInfo(page, testCaseReviewService.listCaseReview(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/save")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public void saveCaseReview(@RequestBody SaveTestCaseReviewRequest reviewRequest) {
|
||||||
|
testCaseReviewService.saveTestCaseReview(reviewRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/project")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public List<Project> getProjectByReviewId(@RequestBody TestCaseReview request) {
|
||||||
|
return testCaseReviewService.getProjectByReviewId(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/reviewer")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public List<User> getUserByReviewId(@RequestBody TestCaseReview request) {
|
||||||
|
return testCaseReviewService.getUserByReviewId(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/recent/{count}")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public List<TestCaseReviewDTO> recentTestPlans(@PathVariable int count) {
|
||||||
|
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
|
||||||
|
PageHelper.startPage(1, count, true);
|
||||||
|
return testCaseReviewService.recent(currentWorkspaceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/edit")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public void editCaseReview(@RequestBody TestCaseReview testCaseReview) {
|
||||||
|
testCaseReviewService.editCaseReview(testCaseReview);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/delete/{reviewId}")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public void deleteCaseReview(@PathVariable String reviewId) {
|
||||||
|
testCaseReviewService.deleteCaseReview(reviewId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.metersphere.track.dto;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.TestCaseReview;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TestCaseReviewDTO extends TestCaseReview {
|
||||||
|
|
||||||
|
private String projectName;
|
||||||
|
private String reviewerName;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.track.request.testreview;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.TestCaseReview;
|
||||||
|
import io.metersphere.controller.request.OrderRequest;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class QueryCaseReviewRequest extends TestCaseReview {
|
||||||
|
private List<OrderRequest> orders;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.track.request.testreview;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.TestCaseReview;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class SaveTestCaseReviewRequest extends TestCaseReview {
|
||||||
|
private List<String> projectIds;
|
||||||
|
private List<String> userIds;
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.*;
|
||||||
|
import io.metersphere.base.mapper.*;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtTestCaseReviewMapper;
|
||||||
|
import io.metersphere.commons.constants.TestCaseReviewStatus;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.commons.utils.ServiceUtils;
|
||||||
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
|
import io.metersphere.track.dto.TestCaseReviewDTO;
|
||||||
|
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||||
|
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
||||||
|
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.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class TestCaseReviewService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TestCaseReviewProjectMapper testCaseReviewProjectMapper;
|
||||||
|
@Resource
|
||||||
|
private TestCaseReviewUsersMapper testCaseReviewUsersMapper;
|
||||||
|
@Resource
|
||||||
|
private TestCaseReviewMapper testCaseReviewMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtTestCaseReviewMapper extTestCaseReviewMapper;
|
||||||
|
@Resource
|
||||||
|
private ProjectMapper projectMapper;
|
||||||
|
@Resource
|
||||||
|
private UserMapper userMapper;
|
||||||
|
|
||||||
|
public void saveTestCaseReview(SaveTestCaseReviewRequest reviewRequest) {
|
||||||
|
checkCaseReviewExist(reviewRequest);
|
||||||
|
|
||||||
|
String reviewId = UUID.randomUUID().toString();
|
||||||
|
List<String> projectIds = reviewRequest.getProjectIds();
|
||||||
|
List<String> userIds = reviewRequest.getUserIds();
|
||||||
|
|
||||||
|
projectIds.forEach(projectId -> {
|
||||||
|
TestCaseReviewProject testCaseReviewProject = new TestCaseReviewProject();
|
||||||
|
testCaseReviewProject.setProjectId(projectId);
|
||||||
|
testCaseReviewProject.setReviewId(reviewId);
|
||||||
|
testCaseReviewProjectMapper.insertSelective(testCaseReviewProject);
|
||||||
|
});
|
||||||
|
|
||||||
|
userIds.forEach(userId -> {
|
||||||
|
TestCaseReviewUsers testCaseReviewUsers = new TestCaseReviewUsers();
|
||||||
|
testCaseReviewUsers.setReviewId(reviewId);
|
||||||
|
testCaseReviewUsers.setUserId(userId);
|
||||||
|
testCaseReviewUsersMapper.insert(testCaseReviewUsers);
|
||||||
|
});
|
||||||
|
|
||||||
|
reviewRequest.setId(reviewId);
|
||||||
|
reviewRequest.setCreateTime(System.currentTimeMillis());
|
||||||
|
reviewRequest.setUpdateTime(System.currentTimeMillis());
|
||||||
|
reviewRequest.setCreator(SessionUtils.getUser().getId());
|
||||||
|
reviewRequest.setStatus(TestCaseReviewStatus.Prepare.name());
|
||||||
|
testCaseReviewMapper.insert(reviewRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TestCaseReviewDTO> listCaseReview(QueryCaseReviewRequest request) {
|
||||||
|
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
|
||||||
|
return extTestCaseReviewMapper.list(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Project> getProjectByReviewId(TestCaseReview request) {
|
||||||
|
String reviewId = request.getId();
|
||||||
|
|
||||||
|
TestCaseReviewProjectExample testCaseReviewProjectExample = new TestCaseReviewProjectExample();
|
||||||
|
testCaseReviewProjectExample.createCriteria().andReviewIdEqualTo(reviewId);
|
||||||
|
List<TestCaseReviewProject> testCaseReviewProject = testCaseReviewProjectMapper.selectByExample(testCaseReviewProjectExample);
|
||||||
|
|
||||||
|
List<String> projectIds = testCaseReviewProject
|
||||||
|
.stream()
|
||||||
|
.map(TestCaseReviewProject::getProjectId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
ProjectExample projectExample = new ProjectExample();
|
||||||
|
projectExample.createCriteria().andIdIn(projectIds);
|
||||||
|
return projectMapper.selectByExample(projectExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<User> getUserByReviewId(TestCaseReview request) {
|
||||||
|
String reviewId = request.getId();
|
||||||
|
|
||||||
|
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
|
||||||
|
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
|
||||||
|
List<TestCaseReviewUsers> testCaseReviewUsers = testCaseReviewUsersMapper.selectByExample(testCaseReviewUsersExample);
|
||||||
|
|
||||||
|
List<String> userIds = testCaseReviewUsers
|
||||||
|
.stream()
|
||||||
|
.map(TestCaseReviewUsers::getUserId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
UserExample userExample = new UserExample();
|
||||||
|
userExample.createCriteria().andIdIn(userIds);
|
||||||
|
return userMapper.selectByExample(userExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TestCaseReviewDTO> recent(String currentWorkspaceId) {
|
||||||
|
return extTestCaseReviewMapper.listByWorkspaceId(currentWorkspaceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editCaseReview(TestCaseReview testCaseReview) {
|
||||||
|
testCaseReview.setUpdateTime(System.currentTimeMillis());
|
||||||
|
checkCaseReviewExist(testCaseReview);
|
||||||
|
testCaseReviewMapper.updateByPrimaryKeySelective(testCaseReview);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCaseReviewExist(TestCaseReview testCaseReview) {
|
||||||
|
if (testCaseReview.getName() != null) {
|
||||||
|
TestCaseReviewExample example = new TestCaseReviewExample();
|
||||||
|
TestCaseReviewExample.Criteria criteria = example
|
||||||
|
.createCriteria()
|
||||||
|
.andNameEqualTo(testCaseReview.getName());
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(testCaseReview.getId())) {
|
||||||
|
criteria.andIdNotEqualTo(testCaseReview.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (testCaseReviewMapper.selectByExample(example).size() > 0) {
|
||||||
|
MSException.throwException("评审名称已存在");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteCaseReview(String reviewId) {
|
||||||
|
deleteCaseReviewProject(reviewId);
|
||||||
|
deleteCaseReviewUsers(reviewId);
|
||||||
|
testCaseReviewMapper.deleteByPrimaryKey(reviewId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteCaseReviewProject(String reviewId) {
|
||||||
|
TestCaseReviewProjectExample testCaseReviewProjectExample = new TestCaseReviewProjectExample();
|
||||||
|
testCaseReviewProjectExample.createCriteria().andReviewIdEqualTo(reviewId);
|
||||||
|
testCaseReviewProjectMapper.deleteByExample(testCaseReviewProjectExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteCaseReviewUsers(String reviewId) {
|
||||||
|
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
|
||||||
|
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
|
||||||
|
testCaseReviewUsersMapper.deleteByExample(testCaseReviewUsersExample);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
<el-tooltip :content="tip"
|
<el-tooltip :content="tip"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
|
:enterable="false"
|
||||||
:effect="effect">
|
:effect="effect">
|
||||||
<el-button @click="exec()"
|
<el-button @click="exec()"
|
||||||
@click.stop="clickStop"
|
@click.stop="clickStop"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<div id="menu-bar" v-if="isRouterAlive">
|
<div id="menu-bar" v-if="isRouterAlive">
|
||||||
<el-row type="flex">
|
<el-row type="flex">
|
||||||
<el-col :span="8">
|
<el-col :span="12">
|
||||||
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router
|
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router
|
||||||
:default-active='$route.path'>
|
:default-active='$route.path'>
|
||||||
<el-menu-item :index="'/track/home'">
|
<el-menu-item :index="'/track/home'">
|
||||||
|
@ -30,6 +30,16 @@
|
||||||
:title="$t('test_track.case.create_case')"/>
|
:title="$t('test_track.case.create_case')"/>
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
|
|
||||||
|
<el-submenu v-permission="['test_manager','test_user','test_viewer']"
|
||||||
|
index="8" popper-class="submenu">
|
||||||
|
<template v-slot:title>用例评审</template>
|
||||||
|
<ms-recent-list ref="reviewRecent" :options="reviewRecent"/>
|
||||||
|
<el-divider/>
|
||||||
|
<ms-show-all :index="'/track/review/all'"/>
|
||||||
|
<el-menu-item :index="testCaseReviewEditPath" class="blank_item"/>
|
||||||
|
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/review/create'" title="创建用例评审"/>
|
||||||
|
</el-submenu>
|
||||||
|
|
||||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']" index="7" popper-class="submenu">
|
<el-submenu v-permission="['test_manager','test_user','test_viewer']" index="7" popper-class="submenu">
|
||||||
<template v-slot:title>{{ $t('test_track.plan.test_plan') }}</template>
|
<template v-slot:title>{{ $t('test_track.plan.test_plan') }}</template>
|
||||||
<ms-recent-list ref="planRecent" :options="planRecent"/>
|
<ms-recent-list ref="planRecent" :options="planRecent"/>
|
||||||
|
@ -41,7 +51,7 @@
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="16"/>
|
<el-col :span="12"/>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -61,6 +71,7 @@ export default {
|
||||||
testPlanViewPath: '',
|
testPlanViewPath: '',
|
||||||
isRouterAlive: true,
|
isRouterAlive: true,
|
||||||
testCaseEditPath: '',
|
testCaseEditPath: '',
|
||||||
|
testCaseReviewEditPath: '',
|
||||||
testCaseProjectPath: '',
|
testCaseProjectPath: '',
|
||||||
isProjectActivation: true,
|
isProjectActivation: true,
|
||||||
projectRecent: {
|
projectRecent: {
|
||||||
|
@ -82,6 +93,15 @@ export default {
|
||||||
router: function (item) {
|
router: function (item) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
reviewRecent: {
|
||||||
|
title: "最近的评审",
|
||||||
|
url: "/test/case/review/recent/5",
|
||||||
|
index: function (item) {
|
||||||
|
return '/test/case/review/' + item.id;
|
||||||
|
},
|
||||||
|
router: function (item) {
|
||||||
|
}
|
||||||
|
},
|
||||||
planRecent: {
|
planRecent: {
|
||||||
title: this.$t('test_track.recent_plan'),
|
title: this.$t('test_track.recent_plan'),
|
||||||
url: "/test/plan/recent/5",
|
url: "/test/plan/recent/5",
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
<template>
|
||||||
|
<ms-container>
|
||||||
|
|
||||||
|
<ms-main-container>
|
||||||
|
<test-case-review-list
|
||||||
|
@openCaseReviewEditDialog="openCaseReviewEditDialog"
|
||||||
|
@caseReviewEdit="openCaseReviewEditDialog"
|
||||||
|
ref="caseReviewList"/>
|
||||||
|
</ms-main-container>
|
||||||
|
|
||||||
|
<test-case-review-edit ref="caseReviewEditDialog" @refresh="refreshCaseReviewList"/>
|
||||||
|
|
||||||
|
</ms-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TestCaseReviewList from "./components/TestCaseReviewList";
|
||||||
|
import TestCaseReviewEdit from "./components/TestCaseReviewEdit";
|
||||||
|
import MsMainContainer from "../../common/components/MsMainContainer";
|
||||||
|
import MsContainer from "../../common/components/MsContainer";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestCaseReview",
|
||||||
|
components: {
|
||||||
|
MsMainContainer,
|
||||||
|
MsContainer,
|
||||||
|
TestCaseReviewList,
|
||||||
|
TestCaseReviewEdit
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.$route.path.indexOf("/track/review/create") >= 0){
|
||||||
|
this.openCaseReviewEditDialog();
|
||||||
|
this.$router.push('/track/review/all');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$route'(to) {
|
||||||
|
if (to.path.indexOf("/track/review/create") >= 0){
|
||||||
|
this.openCaseReviewEditDialog();
|
||||||
|
this.$router.push('/track/review/all');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openCaseReviewEditDialog(data) {
|
||||||
|
this.$refs.caseReviewEditDialog.openCaseReviewEditDialog(data);
|
||||||
|
},
|
||||||
|
refreshCaseReviewList() {
|
||||||
|
this.$refs.caseReviewList.condition = {};
|
||||||
|
this.$refs.caseReviewList.initTableData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,245 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<el-dialog :close-on-click-modal="false"
|
||||||
|
:title="operationType === 'edit' ? '编辑用例评审' : '创建用例评审'"
|
||||||
|
:visible.sync="dialogFormVisible"
|
||||||
|
@close="close"
|
||||||
|
width="65%">
|
||||||
|
|
||||||
|
<el-form :model="form" :rules="rules" ref="reviewForm">
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8" :offset="1">
|
||||||
|
<el-form-item
|
||||||
|
placeholder="请输入评审标题"
|
||||||
|
label="评审标题"
|
||||||
|
:label-width="formLabelWidth"
|
||||||
|
prop="name">
|
||||||
|
<el-input v-model="form.name"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="11" :offset="2">
|
||||||
|
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectIds">
|
||||||
|
<el-select
|
||||||
|
:disabled="(form.status == null) ? false : true"
|
||||||
|
v-model="form.projectIds"
|
||||||
|
:placeholder="$t('test_track.plan.input_plan_project')"
|
||||||
|
multiple
|
||||||
|
style="width: 100%"
|
||||||
|
collapse-tags
|
||||||
|
filterable>
|
||||||
|
<el-option
|
||||||
|
v-for="item in projects"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="10" :offset="1">
|
||||||
|
<el-form-item label="评审人" :label-width="formLabelWidth" prop="principal">
|
||||||
|
<el-select
|
||||||
|
v-model="form.userIds"
|
||||||
|
placeholder="请选择评审人"
|
||||||
|
filterable multiple
|
||||||
|
collapse-tags
|
||||||
|
:disabled="(form.status == null) ? false : true"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in reviewerOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item label="截止时间" :label-width="formLabelWidth" prop="endTime">
|
||||||
|
<el-date-picker @change="endTimeChange" type="datetime" :placeholder="$t('commons.select_date')"
|
||||||
|
v-model="form.endTime"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
|
||||||
|
<el-row type="flex" justify="left" style="margin-top: 10px;">
|
||||||
|
<el-col :span="23" :offset="1">
|
||||||
|
<el-form-item :label="$t('commons.description')" :label-width="formLabelWidth" prop="description">
|
||||||
|
<el-input v-model="form.description"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 4}"
|
||||||
|
:rows="2"
|
||||||
|
:placeholder="$t('commons.input_content')"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row v-if="operationType == 'edit'" type="flex" justify="left" style="margin-top: 10px;">
|
||||||
|
<el-col :span="19" :offset="1">
|
||||||
|
<el-form-item label="当前状态" :label-width="formLabelWidth" prop="status">
|
||||||
|
<test-plan-status-button :status="form.status" @statusChange="statusChange"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template v-slot:footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="dialogFormVisible = false">
|
||||||
|
{{ $t('test_track.cancel') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" @click="saveReview">
|
||||||
|
{{ $t('test_track.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import TestPlanStatusButton from "../../plan/common/TestPlanStatusButton";
|
||||||
|
import {WORKSPACE_ID} from "../../../../../common/js/constants";
|
||||||
|
import {listenGoBack, removeGoBackListener} from "../../../../../common/js/utils";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestCaseReviewEdit",
|
||||||
|
components: {TestPlanStatusButton},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogFormVisible: false,
|
||||||
|
form: {
|
||||||
|
name: '',
|
||||||
|
projectIds: [],
|
||||||
|
userIds: [],
|
||||||
|
stage: '',
|
||||||
|
description: '',
|
||||||
|
endTime: ''
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
name: [
|
||||||
|
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
|
||||||
|
{max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur'}
|
||||||
|
],
|
||||||
|
projectIds: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
|
||||||
|
userIds: [{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}],
|
||||||
|
stage: [{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}],
|
||||||
|
description: [{max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}],
|
||||||
|
endTime: [{required: true, message: '请选择截止时间', trigger: 'blur'}]
|
||||||
|
},
|
||||||
|
formLabelWidth: "120px",
|
||||||
|
operationType: '',
|
||||||
|
projects: [],
|
||||||
|
reviewerOptions: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openCaseReviewEditDialog(caseReview) {
|
||||||
|
this.resetForm();
|
||||||
|
this.getProjects();
|
||||||
|
this.setReviewerOptions();
|
||||||
|
this.operationType = 'save';
|
||||||
|
if (caseReview) {
|
||||||
|
//修改
|
||||||
|
this.operationType = 'edit';
|
||||||
|
let tmp = {};
|
||||||
|
Object.assign(tmp, caseReview);
|
||||||
|
Object.assign(this.form, tmp);
|
||||||
|
}
|
||||||
|
listenGoBack(this.close);
|
||||||
|
this.dialogFormVisible = true;
|
||||||
|
},
|
||||||
|
saveReview() {
|
||||||
|
this.$refs['reviewForm'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
let param = {};
|
||||||
|
Object.assign(param, this.form);
|
||||||
|
param.name = param.name.trim();
|
||||||
|
if (param.name == '') {
|
||||||
|
this.$warning(this.$t('test_track.plan.input_plan_name'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.operationType === 'save') {
|
||||||
|
this.compareTime(new Date().getTime(), this.form.endTime);
|
||||||
|
}
|
||||||
|
this.$post('/test/case/review/' + this.operationType, param, () => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.dialogFormVisible = false;
|
||||||
|
this.$emit("refresh");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getProjects() {
|
||||||
|
this.$get("/project/listAll", (response) => {
|
||||||
|
if (response.success) {
|
||||||
|
this.projects = response.data;
|
||||||
|
} else {
|
||||||
|
this.$warning()(response.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setReviewerOptions() {
|
||||||
|
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||||
|
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||||
|
this.reviewerOptions = response.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
statusChange(status) {
|
||||||
|
this.form.status = status;
|
||||||
|
this.$forceUpdate();
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
removeGoBackListener(this.close);
|
||||||
|
this.dialogFormVisible = false;
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
//防止点击修改后,点击新建触发校验
|
||||||
|
if (this.$refs['reviewForm']) {
|
||||||
|
this.$refs['reviewForm'].validate((valid) => {
|
||||||
|
this.$refs['reviewForm'].resetFields();
|
||||||
|
this.form.name = '';
|
||||||
|
this.form.stage = '';
|
||||||
|
this.form.endTime = '';
|
||||||
|
this.form.description = '';
|
||||||
|
this.form.status = null;
|
||||||
|
this.form.projectIds = [];
|
||||||
|
this.form.userIds = [];
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
endTimeChange(value) {
|
||||||
|
this.form.endTime = this.form.endTime.getTime();
|
||||||
|
this.compareTime(new Date().getTime(), value.getTime());
|
||||||
|
},
|
||||||
|
compareTime(ts1, ts2) {
|
||||||
|
if (ts1 > ts2) {
|
||||||
|
this.form.endTime = '';
|
||||||
|
this.$warning("截止时间不能早于当前时间!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
|
@ -0,0 +1,227 @@
|
||||||
|
<template>
|
||||||
|
<el-card class="table-card" v-loading="result.loading">
|
||||||
|
<template v-slot:header>
|
||||||
|
<ms-table-header :is-tester-permission="true" :condition.sync="condition"
|
||||||
|
@search="initTableData" @create="testCaseReviewCreate"
|
||||||
|
create-tip="创建用例评审"
|
||||||
|
title="用例评审"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
border
|
||||||
|
class="adjust-table"
|
||||||
|
:data="tableData"
|
||||||
|
@filter-change="filter"
|
||||||
|
@sort-change="sort"
|
||||||
|
@row-click="intoReview">
|
||||||
|
<el-table-column
|
||||||
|
prop="name"
|
||||||
|
label="评审名称"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="reviewer"
|
||||||
|
label="评审人"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="projectName"
|
||||||
|
label="所属项目"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="creator"
|
||||||
|
label="发起人"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
column-key="status"
|
||||||
|
:filters="statusFilters"
|
||||||
|
:label="$t('test_track.plan.plan_status')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span @click.stop="clickt = 'stop'">
|
||||||
|
<el-dropdown class="test-case-status" @command="statusChange">
|
||||||
|
<span class="el-dropdown-link">
|
||||||
|
<plan-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: 'Prepare'}">
|
||||||
|
{{ $t('test_track.plan.plan_status_prepare') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
|
||||||
|
:command="{id: scope.row.id, status: 'Underway'}">
|
||||||
|
{{ $t('test_track.plan.plan_status_running') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
|
||||||
|
:command="{id: scope.row.id, status: 'Completed'}">
|
||||||
|
{{ $t('test_track.plan.plan_status_completed') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="reviewerSize"
|
||||||
|
label="已评"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="resultMap"
|
||||||
|
label="结果分布"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="createTime"
|
||||||
|
:label="$t('commons.create_time')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="endTime"
|
||||||
|
label="截止时间"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.endTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('commons.operating')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<ms-table-operator :is-tester-permission="true" @editClick="handleEdit(scope.row)"
|
||||||
|
@deleteClick="handleDelete(scope.row)">
|
||||||
|
<template v-slot:middle>
|
||||||
|
<ms-table-operator-button :isTesterPermission="true" type="success" tip="重新发起" icon="el-icon-document"
|
||||||
|
@exec="reCreate(scope.row)"/>
|
||||||
|
</template>
|
||||||
|
</ms-table-operator>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||||
|
:total="total"/>
|
||||||
|
<ms-delete-confirm title="删除用例评审" @delete="_handleDelete" ref="deleteConfirm"/>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsDeleteConfirm from "../../../common/components/MsDeleteConfirm";
|
||||||
|
import MsTableOperator from "../../../common/components/MsTableOperator";
|
||||||
|
import MsTableOperatorButton from "../../../common/components/MsTableOperatorButton";
|
||||||
|
import MsDialogFooter from "../../../common/components/MsDialogFooter";
|
||||||
|
import MsTableHeader from "../../../common/components/MsTableHeader";
|
||||||
|
import MsCreateBox from "../../../settings/CreateBox";
|
||||||
|
import MsTablePagination from "../../../common/pagination/TablePagination";
|
||||||
|
import {_filter, _sort, checkoutTestManagerOrTestUser} from "../../../../../common/js/utils";
|
||||||
|
import PlanStatusTableItem from "../../common/tableItems/plan/PlanStatusTableItem";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestCaseReviewList",
|
||||||
|
components: {
|
||||||
|
MsDeleteConfirm,
|
||||||
|
MsTableOperator,
|
||||||
|
MsTableOperatorButton,
|
||||||
|
MsDialogFooter,
|
||||||
|
MsTableHeader,
|
||||||
|
MsCreateBox,
|
||||||
|
MsTablePagination,
|
||||||
|
PlanStatusTableItem
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
result: {},
|
||||||
|
condition: {},
|
||||||
|
tableData: [],
|
||||||
|
isTestManagerOrTestUser: false,
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
statusFilters: [
|
||||||
|
{text: this.$t('test_track.plan.plan_status_prepare'), value: 'Prepare'},
|
||||||
|
{text: this.$t('test_track.plan.plan_status_running'), value: 'Underway'},
|
||||||
|
{text: this.$t('test_track.plan.plan_status_completed'), value: 'Completed'}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$route'(to) {
|
||||||
|
if (to.path.indexOf("/track/review/all") >= 0) {
|
||||||
|
this.initTableData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
|
||||||
|
this.initTableData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initTableData() {
|
||||||
|
this.result = this.$post("/test/case/review/list/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
||||||
|
let data = response.data;
|
||||||
|
this.total = data.itemCount;
|
||||||
|
this.tableData = data.listObject;
|
||||||
|
for (let i = 0; i < this.tableData.length; i++) {
|
||||||
|
let path = "/test/case/review/project";
|
||||||
|
this.$post(path, {id: this.tableData[i].id}, res => {
|
||||||
|
let arr = res.data;
|
||||||
|
let projectName = arr.map(data => data.name).join("、");
|
||||||
|
let projectIds = arr.map(data => data.id);
|
||||||
|
this.$set(this.tableData[i], "projectName", projectName);
|
||||||
|
this.$set(this.tableData[i], "projectIds", projectIds);
|
||||||
|
});
|
||||||
|
this.$post('/test/case/review/reviewer', {id: this.tableData[i].id}, res => {
|
||||||
|
let arr = res.data;
|
||||||
|
let reviewer = arr.map(data => data.name).join("、");
|
||||||
|
let userIds = arr.map(data => data.id);
|
||||||
|
this.$set(this.tableData[i], "reviewer", reviewer);
|
||||||
|
this.$set(this.tableData[i], "userIds", userIds);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
intoReview() {
|
||||||
|
|
||||||
|
},
|
||||||
|
testCaseReviewCreate() {
|
||||||
|
this.$emit('openCaseReviewEditDialog');
|
||||||
|
},
|
||||||
|
handleEdit(caseReview) {
|
||||||
|
this.$emit('caseReviewEdit', caseReview);
|
||||||
|
},
|
||||||
|
statusChange() {
|
||||||
|
|
||||||
|
},
|
||||||
|
handleDelete(caseReview) {
|
||||||
|
this.$refs.deleteConfirm.open(caseReview);
|
||||||
|
},
|
||||||
|
_handleDelete(caseReview) {
|
||||||
|
let reviewId = caseReview.id;
|
||||||
|
this.$get('/test/case/review/delete/' + reviewId, () => {
|
||||||
|
this.initTableData();
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
filter(filters) {
|
||||||
|
_filter(filters, this.condition);
|
||||||
|
this.initTableData();
|
||||||
|
},
|
||||||
|
sort(column) {
|
||||||
|
_sort(column, this.condition);
|
||||||
|
this.initTableData();
|
||||||
|
},
|
||||||
|
reCreate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -4,6 +4,7 @@ const TestTrack = () => import(/* webpackChunkName: "track" */ '@/business/compo
|
||||||
const TrackHome = () => import(/* webpackChunkName: "track" */ '@/business/components/track/home/TrackHome')
|
const TrackHome = () => import(/* webpackChunkName: "track" */ '@/business/components/track/home/TrackHome')
|
||||||
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 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 {
|
||||||
|
@ -53,6 +54,11 @@ export default {
|
||||||
path: "project/:type",
|
path: "project/:type",
|
||||||
name: "trackProject",
|
name: "trackProject",
|
||||||
component: MsProject
|
component: MsProject
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
path: "review/:type",
|
||||||
|
name: "testCaseReview",
|
||||||
|
component: TestCaseReview
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue