feat(测试跟踪): 功能用例公共用例库(X-Pack) 多版本支持
--story=1004645 --user=王孝刚 功能用例公共用例库(X-Pack) 多版本支持 https://www.tapd.cn/55049933/s/1091704
This commit is contained in:
parent
4cfe63bee8
commit
9b3df16605
|
@ -232,8 +232,40 @@
|
|||
</select>
|
||||
|
||||
<select id="publicList" resultType="io.metersphere.track.dto.TestCaseDTO">
|
||||
select
|
||||
deleteUser.name AS delete_user_id,test_case.delete_time,
|
||||
SELECT test_case.versionName,
|
||||
test_case.versionId,
|
||||
test_case.createName,
|
||||
test_case.projectName,
|
||||
test_case.id,
|
||||
test_case.node_id,
|
||||
test_case.node_path,
|
||||
test_case.project_id,
|
||||
test_case.`name`,
|
||||
test_case.`type`,
|
||||
test_case.maintainer,
|
||||
test_case.priority,
|
||||
test_case.`method`,
|
||||
test_case.create_time,
|
||||
test_case.update_time,
|
||||
test_case.test_id,
|
||||
test_case.sort,
|
||||
test_case.num,
|
||||
test_case.other_test_name,
|
||||
test_case.review_status,
|
||||
test_case.tags,
|
||||
test_case.demand_id,
|
||||
test_case.demand_name,
|
||||
test_case.`status`,
|
||||
test_case.custom_num,
|
||||
test_case.step_model,
|
||||
test_case.create_user,
|
||||
test_case.custom_fields,
|
||||
test_case.case_public ,
|
||||
test_case.ref_id
|
||||
from
|
||||
(select
|
||||
project_version.name as versionName,
|
||||
project_version.id as versionId,
|
||||
<if test="request.selectFields != null and request.selectFields.size() > 0">
|
||||
<foreach collection="request.selectFields" item="field" separator=",">
|
||||
${field}
|
||||
|
@ -246,11 +278,13 @@
|
|||
test_case.other_test_name, test_case.review_status, test_case.tags,
|
||||
test_case.demand_id, test_case.demand_name, test_case.`status`,
|
||||
test_case.custom_num, test_case.step_model, test_case.create_user,u.name as createName,
|
||||
test_case.custom_fields,test_case.case_public , project.name as projectName
|
||||
test_case.custom_fields,test_case.case_public , project.name as projectName ,test_case.ref_id
|
||||
</if>
|
||||
from test_case left join user u on test_case.create_user=u.id
|
||||
left join user deleteUser on test_case.delete_user_id=deleteUser.id
|
||||
left join project on test_case.project_id = project.id
|
||||
left join (select id,workspace_id,NAME from project where workspace_id =#{request.workspaceId})
|
||||
project on test_case.project_id = project.id
|
||||
left join project_version on project.id = project_version.project_id and project_version.id =
|
||||
test_case.version_id
|
||||
<where>
|
||||
<include refid="filters"/>
|
||||
<if test="request.combine != null">
|
||||
|
@ -306,7 +340,71 @@
|
|||
</if>
|
||||
</where>
|
||||
|
||||
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
|
||||
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>) test_case right join
|
||||
(select
|
||||
max(test_case.update_time) update_time
|
||||
from test_case left join user u on test_case.create_user=u.id
|
||||
left join (select id,workspace_id,NAME from project where workspace_id =#{request.workspaceId})
|
||||
project on test_case.project_id = project.id
|
||||
left join project_version on project.id = project_version.project_id and project_version.id =
|
||||
test_case.version_id
|
||||
<where>
|
||||
<include refid="filters"/>
|
||||
<if test="request.combine != null">
|
||||
<include refid="combine">
|
||||
<property name="condition" value="request.combine"/>
|
||||
<property name="name" value="request.name"/>
|
||||
<property name="objectKey" value="request.combine.tags"/>
|
||||
</include>
|
||||
</if>
|
||||
|
||||
<if test="request.statusIsNot != null">
|
||||
and (test_case.status is null or test_case.status != #{request.statusIsNot})
|
||||
</if>
|
||||
|
||||
<if test="request.notEqStatus != null">
|
||||
and (test_case.status is null or test_case.status != #{request.notEqStatus})
|
||||
</if>
|
||||
<if test="request.name != null">
|
||||
and (test_case.name like CONCAT('%', #{request.name},'%')
|
||||
or test_case.num like CONCAT('%', #{request.name},'%')
|
||||
or test_case.tags like CONCAT('%', #{request.name},'%')
|
||||
or test_case.custom_num like CONCAT('%', #{request.name},'%'))
|
||||
</if>
|
||||
<if test="request.ids != null">
|
||||
and test_case.id in
|
||||
<foreach collection="request.ids" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.relevanceCreateTime >0">
|
||||
and test_case.id in (select test_case_id from test_case_test where test_case_test.create_time >=
|
||||
#{request.createTime})
|
||||
</if>
|
||||
<if test="request.createTime >0">
|
||||
and test_case.create_time >= #{request.createTime}
|
||||
</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.workspaceId != null">
|
||||
AND test_case.project_id in (select id from project where workspace_id=#{request.workspaceId})
|
||||
</if>
|
||||
and test_case.case_public = TRUE
|
||||
<include refid="filters"/>
|
||||
<if test="request.caseCoverage == 'uncoverage' ">
|
||||
and test_case.id not in (select distinct test_case_test.test_case_id from test_case_test)
|
||||
</if>
|
||||
<if test="request.caseCoverage == 'coverage' ">
|
||||
and test_case.id in (select distinct test_case_test.test_case_id from test_case_test)
|
||||
</if>
|
||||
</where>
|
||||
group by test_case.ref_id
|
||||
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>) tmp on test_case.update_time = tmp.update_time
|
||||
|
||||
</select>
|
||||
|
||||
<select id="moduleCount" resultType="java.lang.Integer">
|
||||
|
@ -758,7 +856,7 @@
|
|||
<update id="deletePublic">
|
||||
update test_case
|
||||
set case_public = false
|
||||
where id = #{request.id}
|
||||
where ref_id = #{request.refId}
|
||||
</update>
|
||||
|
||||
<update id="reduction">
|
||||
|
@ -790,7 +888,7 @@
|
|||
</select>
|
||||
|
||||
<select id="countByWorkSpaceId" resultType="java.lang.Integer">
|
||||
select count(id)
|
||||
select count(distinct ref_id)
|
||||
from test_case
|
||||
where project_id in (
|
||||
select id
|
||||
|
|
|
@ -250,13 +250,12 @@ public class TestCaseController {
|
|||
return testCaseService.deleteTestCaseToGc(testCaseId);
|
||||
}
|
||||
|
||||
@PostMapping("/deletePublic/{testCaseId}")
|
||||
@PostMapping("/deletePublic/{refId}")
|
||||
@MsAuditLog(module = "track_test_case", type = OperLogConstants.GC, beforeEvent = "#msClass.getLogDetails(#testCaseId)", msClass = TestCaseService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.TRACK_TEST_CASE_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getTestCase(#testCaseId)", targetClass = TestCaseService.class,
|
||||
mailTemplate = "track/TestCaseDelete", subject = "测试用例通知")
|
||||
public int deletePublic(@PathVariable String testCaseId) {
|
||||
checkPermissionService.checkTestCaseOwner(testCaseId);
|
||||
return testCaseService.deleteTestCasePublic(testCaseId);
|
||||
public int deletePublic(@PathVariable String refId) {
|
||||
return testCaseService.deleteTestCasePublic(refId);
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,6 +345,15 @@ public class TestCaseController {
|
|||
testCaseService.deleteToGcBatch(request.getIds());
|
||||
}
|
||||
|
||||
@PostMapping("/batch/movePublic/deleteToGc")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_CASE_READ_DELETE)
|
||||
@MsAuditLog(module = "track_test_case", type = OperLogConstants.BATCH_DEL, beforeEvent = "#msClass.getLogDetails(#request.ids)", msClass = TestCaseService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.TRACK_TEST_CASE_TASK, target = "#targetClass.findByBatchRequest(#request)", targetClass = TestCaseService.class,
|
||||
event = NoticeConstants.Event.DELETE, mailTemplate = "track/TestCaseDelete", subject = "测试用例通知")
|
||||
public void deleteToGcBatchPublic(@RequestBody TestCaseBatchRequest request) {
|
||||
testCaseService.deleteToGcBatchPublic(request.getIds());
|
||||
}
|
||||
|
||||
@PostMapping("/reduction")
|
||||
@MsAuditLog(module = "track_test_case", type = OperLogConstants.GC, beforeEvent = "#msClass.getLogDetails(#testCaseId)", msClass = TestCaseService.class)
|
||||
public void reduction(@RequestBody TestCaseBatchRequest request) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import io.metersphere.api.service.ApiTestCaseService;
|
|||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtIssuesMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtProjectVersionMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
|
||||
import io.metersphere.commons.constants.TestCaseConstants;
|
||||
import io.metersphere.commons.constants.TestCaseReviewStatus;
|
||||
|
@ -155,6 +156,8 @@ public class TestCaseService {
|
|||
private MinderExtraNodeService minderExtraNodeService;
|
||||
@Resource
|
||||
private ProjectVersionService projectVersionService;
|
||||
@Resource
|
||||
private ExtProjectVersionMapper extProjectVersionMapper;
|
||||
|
||||
private void setNode(TestCaseWithBLOBs testCase) {
|
||||
if (StringUtils.isEmpty(testCase.getNodeId()) || "default-module".equals(testCase.getNodeId())) {
|
||||
|
@ -1371,28 +1374,47 @@ public class TestCaseService {
|
|||
TestCaseExample exampleList = new TestCaseExample();
|
||||
exampleList.createCriteria().andIdIn(request.getIds());
|
||||
List<TestCaseWithBLOBs> list = testCaseMapper.selectByExampleWithBLOBs(exampleList);
|
||||
for (TestCaseWithBLOBs item : list) {
|
||||
TestCaseWithBLOBs batchCopy = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(batchCopy, item);
|
||||
checkTestCaseExist(batchCopy);
|
||||
batchCopy.setId(UUID.randomUUID().toString());
|
||||
batchCopy.setName("copy_" + item.getName());
|
||||
batchCopy.setCreateTime(System.currentTimeMillis());
|
||||
batchCopy.setUpdateTime(System.currentTimeMillis());
|
||||
batchCopy.setNum(getNextNum(SessionUtils.getCurrentProjectId()));
|
||||
batchCopy.setCustomNum(batchCopy.getNum().toString());
|
||||
batchCopy.setCreateUser(SessionUtils.getUserId());
|
||||
batchCopy.setMaintainer(SessionUtils.getUserId());
|
||||
batchCopy.setReviewStatus(TestCaseReviewStatus.Prepare.name());
|
||||
batchCopy.setStatus(TestCaseReviewStatus.Prepare.name());
|
||||
batchCopy.setNodePath(request.getNodePath());
|
||||
batchCopy.setNodeId(request.getNodeId());
|
||||
batchCopy.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
batchCopy.setCasePublic(false);
|
||||
testCaseMapper.insert(batchCopy);
|
||||
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class);
|
||||
Long nextOrder = ServiceUtils.getNextOrder(request.getProjectId(), extTestCaseMapper::getLastOrder);
|
||||
int nextNum = getNextNum(request.getProjectId());
|
||||
|
||||
try {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
TestCaseWithBLOBs batchCopy = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(batchCopy, list.get(i));
|
||||
checkTestCaseExist(batchCopy);
|
||||
String id = UUID.randomUUID().toString();
|
||||
batchCopy.setId(id);
|
||||
batchCopy.setName(ServiceUtils.getCopyName(batchCopy.getName()));
|
||||
batchCopy.setCreateTime(System.currentTimeMillis());
|
||||
batchCopy.setUpdateTime(System.currentTimeMillis());
|
||||
batchCopy.setCreateUser(SessionUtils.getUserId());
|
||||
batchCopy.setMaintainer(SessionUtils.getUserId());
|
||||
batchCopy.setReviewStatus(TestCaseReviewStatus.Prepare.name());
|
||||
batchCopy.setStatus(TestCaseReviewStatus.Prepare.name());
|
||||
batchCopy.setNodePath(request.getNodePath());
|
||||
batchCopy.setNodeId(request.getNodeId());
|
||||
batchCopy.setCasePublic(false);
|
||||
batchCopy.setRefId(id);
|
||||
if (!(batchCopy.getProjectId()).equals(SessionUtils.getCurrentProjectId())) {
|
||||
String versionId = extProjectVersionMapper.getDefaultVersion(SessionUtils.getCurrentProjectId());
|
||||
batchCopy.setVersionId(versionId);
|
||||
}
|
||||
batchCopy.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
batchCopy.setOrder(nextOrder += ServiceUtils.ORDER_STEP);
|
||||
batchCopy.setCustomNum(String.valueOf(nextNum));
|
||||
batchCopy.setNum(nextNum++);
|
||||
mapper.insert(batchCopy);
|
||||
if (i % 50 == 0)
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
} finally {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteTestCaseBath(TestCaseBatchRequest request) {
|
||||
TestCaseExample example = this.getBatchExample(request);
|
||||
deleteTestPlanTestCaseBath(request.getIds());
|
||||
|
@ -2013,6 +2035,21 @@ public class TestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
public void deleteToGcBatchPublic(List<String> ids) {
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
for (String id : ids) {
|
||||
TestCase testCase = testCaseMapper.selectByPrimaryKey(id);
|
||||
if ((StringUtils.isNotEmpty(testCase.getMaintainer()) && testCase.getMaintainer() == SessionUtils.getUserId()) ||
|
||||
(StringUtils.isNotEmpty(testCase.getCreateUser()) && testCase.getCreateUser() == SessionUtils.getUserId())) {
|
||||
this.deleteTestCasePublic(testCase.getRefId());
|
||||
}
|
||||
else {
|
||||
MSException.throwException(Translator.get("check_owner_case"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getCaseLogDetails(TestCaseMinderEditRequest request) {
|
||||
if (CollectionUtils.isNotEmpty(request.getData())) {
|
||||
List<String> ids = request.getData().stream().map(TestCase::getId).collect(Collectors.toList());
|
||||
|
@ -2237,13 +2274,16 @@ public class TestCaseService {
|
|||
try {
|
||||
for (int i = 0; i < testCases.size(); i++) {
|
||||
TestCaseWithBLOBs testCase = testCases.get(i);
|
||||
testCase.setId(UUID.randomUUID().toString());
|
||||
String id = UUID.randomUUID().toString();
|
||||
testCase.setId(id);
|
||||
testCase.setName(ServiceUtils.getCopyName(testCase.getName()));
|
||||
testCase.setNodeId(request.getNodeId());
|
||||
testCase.setNodePath(request.getNodePath());
|
||||
testCase.setOrder(nextOrder += ServiceUtils.ORDER_STEP);
|
||||
testCase.setCustomNum(String.valueOf(nextNum));
|
||||
testCase.setNum(nextNum++);
|
||||
testCase.setCasePublic(false);
|
||||
testCase.setRefId(id);
|
||||
mapper.insert(testCase);
|
||||
if (i % 50 == 0)
|
||||
sqlSession.flushStatements();
|
||||
|
@ -2284,9 +2324,9 @@ public class TestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
public int deleteTestCasePublic(String testCaseId) {
|
||||
public int deleteTestCasePublic(String refId) {
|
||||
TestCase testCase = new TestCase();
|
||||
testCase.setId(testCaseId);
|
||||
testCase.setRefId(refId);
|
||||
return extTestCaseMapper.deletePublic(testCase);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@
|
|||
@caseEdit="handleCaseCreateOrEdit($event,'edit')"
|
||||
@caseCreate="handleCaseCreateOrEdit($event,'add')"
|
||||
:read-only="testCaseReadOnly"
|
||||
@checkout="checkoutPublic($event, item)"
|
||||
:tree-nodes="treeNodes"
|
||||
:select-node="selectNode"
|
||||
:select-condition="condition"
|
||||
|
@ -646,6 +647,19 @@ export default {
|
|||
vh.loading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
checkoutPublic(testCase, item) {
|
||||
Object.assign(item.testCaseInfo, testCase)
|
||||
//子组件先变更 copy 状态,再执行初始化操作
|
||||
this.$refs.testCaseEditShow[0].changeType("copy");
|
||||
this.$refs.testCaseEditShow[0].initEdit(item.testCaseInfo, () => {
|
||||
this.$nextTick(() => {
|
||||
let vh = this.$refs.testCaseEditShow[0].$refs.versionHistory;
|
||||
vh.getVersionOptionList(vh.handleVersionOptions);
|
||||
vh.show = false;
|
||||
vh.loading = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
ref="versionHistory"
|
||||
:version-data="versionData"
|
||||
:current-id="currentTestCaseInfo.id"
|
||||
:current-project-id="currentProjectId"
|
||||
@compare="compare" @checkout="checkout" @create="create" @del="del"/>
|
||||
<el-dropdown split-button type="primary" class="ms-api-buttion" @click="handleCommand"
|
||||
@command="handleCommand" size="small" style="float: right;margin-right: 20px">
|
||||
|
@ -150,8 +151,8 @@
|
|||
:tree-nodes="treeNodes"></test-case-version-diff>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible=false">取 消</el-button>
|
||||
<el-button type="primary">确 定</el-button>
|
||||
<el-button @click="dialogVisible=false">{{this.$t('commons.cancel')}}</el-button>
|
||||
<el-button type="primary">{{this.$t('commons.confirm')}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
@ -309,7 +310,8 @@ export default {
|
|||
versionData: [],
|
||||
dialogVisible: false,
|
||||
oldData: null,
|
||||
newData: null
|
||||
newData: null ,
|
||||
currentProjectId: "" ,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -944,6 +946,9 @@ export default {
|
|||
},
|
||||
getVersionHistory() {
|
||||
this.$get('/test/case/versions/' + this.currentTestCaseInfo.id, response => {
|
||||
for (let i = 0; i < response.data.length; i++) {
|
||||
this.currentProjectId = response.data[i].projectId;
|
||||
}
|
||||
this.versionData = response.data;
|
||||
this.$refs.versionHistory.loading = false;
|
||||
});
|
||||
|
|
|
@ -18,13 +18,20 @@
|
|||
<el-link type="primary" style="margin-right: 20px" @click="openHis" v-if="form.id">
|
||||
{{ $t('operating_log.change_history') }}
|
||||
</el-link>
|
||||
<!-- 版本历史 -->
|
||||
<ms-version-history v-xpack
|
||||
ref="versionHistory"
|
||||
:version-data="versionData"
|
||||
:current-id="currentTestCaseInfo.id"
|
||||
:current-project-id="currentProjectId"
|
||||
@compare="compare" @checkout="checkout" @create="create" @del="del"/>
|
||||
<ms-table-button v-if="this.path!=='/test/case/add'"
|
||||
id="inputDelay"
|
||||
type="primary"
|
||||
:content="$t('commons.copy')"
|
||||
size="small" @click="handleCopyPublic"
|
||||
icon=""
|
||||
:disabled="readOnly"/>
|
||||
/>
|
||||
</div>
|
||||
<el-form :model="form" :rules="rules" ref="caseFrom" v-loading="result.loading" class="case-form">
|
||||
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
||||
|
@ -35,13 +42,13 @@
|
|||
:label="$t('test_track.case.name')"
|
||||
:label-width="formLabelWidth"
|
||||
prop="name">
|
||||
<el-input :disabled="true" v-model="form.name" size="small" class="ms-case-input"></el-input>
|
||||
<el-input :disabled="readOnly" v-model="form.name" size="small" class="ms-case-input"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('test_track.case.project')" :label-width="formLabelWidth" prop="projectId">
|
||||
<el-select v-model="form.projectId" filterable clearable :disabled="true">
|
||||
<el-select v-model="form.projectId" filterable clearable :disabled="readOnly">
|
||||
<el-option v-for="item in projectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -49,7 +56,7 @@
|
|||
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.tag')" :label-width="formLabelWidth" prop="tag">
|
||||
<ms-input-tag :read-only="true" :currentScenario="form" v-if="showInputTag" ref="tag" :disabled="true"
|
||||
<ms-input-tag :read-only="readOnly" :currentScenario="form" v-if="showInputTag" ref="tag" :disabled="true"
|
||||
class="ms-case-input"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -65,7 +72,7 @@
|
|||
<el-row v-if="isCustomNum">
|
||||
<el-col :span="7">
|
||||
<el-form-item label="ID" :label-width="formLabelWidth" prop="customNum">
|
||||
<el-input :disabled="true" v-model.trim="form.customNum" size="small"
|
||||
<el-input :disabled="readOnly" v-model.trim="form.customNum" size="small"
|
||||
class="ms-case-input"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -74,26 +81,26 @@
|
|||
|
||||
<ms-form-divider :title="$t('test_track.case.step_info')"/>
|
||||
|
||||
<form-rich-text-item :disabled="true" :label-width="formLabelWidth"
|
||||
<form-rich-text-item :disabled="readOnly" :label-width="formLabelWidth"
|
||||
:title="$t('test_track.case.prerequisite')" :data="form" prop="prerequisite"/>
|
||||
|
||||
<step-change-item :label-width="formLabelWidth" :form="form"/>
|
||||
<form-rich-text-item :disabled="true" :label-width="formLabelWidth" v-if="form.stepModel === 'TEXT'"
|
||||
<form-rich-text-item :disabled="readOnly" :label-width="formLabelWidth" v-if="form.stepModel === 'TEXT'"
|
||||
:title="$t('test_track.case.step_desc')" :data="form" prop="stepDescription"/>
|
||||
<form-rich-text-item :disabled="true" :label-width="formLabelWidth" v-if="form.stepModel === 'TEXT'"
|
||||
<form-rich-text-item :disabled="readOnly" :label-width="formLabelWidth" v-if="form.stepModel === 'TEXT'"
|
||||
:title="$t('test_track.case.expected_results')" :data="form" prop="expectedResult"/>
|
||||
|
||||
<test-case-step-item :label-width="formLabelWidth" v-if="form.stepModel === 'STEP' || !form.stepModel"
|
||||
:form="form" :read-only="true"/>
|
||||
:form="form" :read-only="readOnly"/>
|
||||
|
||||
<ms-form-divider :title="$t('test_track.case.other_info')"/>
|
||||
|
||||
<test-case-edit-other-info :read-only="true" :project-id="projectIds" :form="form"
|
||||
<test-case-edit-other-info :read-only="readOnly" :project-id="projectIds" :form="form"
|
||||
:label-width="formLabelWidth" :case-id="form.id" ref="otherInfo"/>
|
||||
|
||||
<el-row style="margin-top: 10px" v-if="type!=='add'">
|
||||
<el-col :span="20" :offset="1">{{ $t('test_track.review.comment') }}:
|
||||
<el-button icon="el-icon-plus" type="mini" @click="openComment" :disabled="true"></el-button>
|
||||
<el-button icon="el-icon-plus" type="mini" @click="openComment" :disabled="readOnly"></el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="type!=='add'">
|
||||
|
@ -102,7 +109,7 @@
|
|||
<review-comment-item v-for="(comment,index) in comments"
|
||||
:key="index"
|
||||
:comment="comment"
|
||||
@refresh="getComments" :disabled="true" api-url="/test/case"/>
|
||||
@refresh="getComments" :disabled="readOnly" api-url="/test/case"/>
|
||||
<div v-if="comments.length === 0" style="text-align: center">
|
||||
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
|
||||
<span style="font-size: 15px; color: #8a8b8d;">
|
||||
|
@ -120,6 +127,20 @@
|
|||
</div>
|
||||
<ms-change-history ref="changeHistory"/>
|
||||
|
||||
<el-dialog
|
||||
:fullscreen="true"
|
||||
:visible.sync="dialogVisible"
|
||||
width="100%"
|
||||
>
|
||||
<test-case-version-diff :old-data="oldData" :new-data="newData"
|
||||
:tree-nodes="treeNodes" :is-public="publicEnable"></test-case-version-diff>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible=false">{{this.$t('commons.cancel')}}</el-button>
|
||||
<el-button type="primary">{{this.$t('commons.confirm')}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
<batch-move ref="testBatchMove" :public-enable="publicEnable"
|
||||
@copyPublic="copyPublic"/>
|
||||
|
@ -166,6 +187,11 @@ import MsChangeHistory from "../../../history/ChangeHistory";
|
|||
import {getTestTemplate} from "@/network/custom-field-template";
|
||||
import CustomFiledFormItem from "@/business/components/common/components/form/CustomFiledFormItem";
|
||||
import BatchMove from "@/business/components/track/case/components/BatchMove";
|
||||
import TestCaseVersionDiff from "@/business/components/track/case/version/TestCaseVersionDiff";
|
||||
|
||||
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const versionHistory = requireComponent.keys().length > 0 ? requireComponent("./version/VersionHistory.vue") : {};
|
||||
|
||||
export default {
|
||||
name: "TestCaseEditShow",
|
||||
|
@ -183,7 +209,9 @@ export default {
|
|||
TestCaseComment, MsPreviousNextButton, MsInputTag, CaseComment, MsDialogFooter, TestCaseAttachment,
|
||||
MsTestCaseStepRichText,
|
||||
MsChangeHistory,
|
||||
BatchMove
|
||||
BatchMove,
|
||||
'MsVersionHistory': versionHistory.default,
|
||||
TestCaseVersionDiff
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -272,7 +300,13 @@ export default {
|
|||
id: 'id',
|
||||
label: 'name',
|
||||
},
|
||||
tabId: getUUID()
|
||||
tabId: getUUID(),
|
||||
versionData: [],
|
||||
currentProjectId: "" ,
|
||||
dialogVisible: false,
|
||||
oldData: null,
|
||||
newData: null,
|
||||
readOnly: true
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -302,14 +336,6 @@ export default {
|
|||
isCustomNum() {
|
||||
return this.$store.state.currentProjectIsCustomNum;
|
||||
},
|
||||
readOnly() {
|
||||
const {rowClickHasPermission} = this.currentTestCaseInfo;
|
||||
if (rowClickHasPermission !== undefined) {
|
||||
return !rowClickHasPermission;
|
||||
}
|
||||
return !hasPermission('PROJECT_TRACK_CASE:READ+CREATE') &&
|
||||
!hasPermission('PROJECT_TRACK_CASE:READ+EDIT');
|
||||
}
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
|
@ -390,6 +416,9 @@ export default {
|
|||
} else {
|
||||
this.isXpack = false;
|
||||
}
|
||||
if (hasLicense()) {
|
||||
this.getVersionHistory();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
currentUser: () => {
|
||||
|
@ -512,7 +541,7 @@ export default {
|
|||
initFuc(testCase);
|
||||
});
|
||||
},
|
||||
initEdit(testCase) {
|
||||
initEdit(testCase , callback) {
|
||||
if (window.history && window.history.pushState) {
|
||||
history.pushState(null, null, document.URL);
|
||||
window.addEventListener('popstate', this.close);
|
||||
|
@ -553,6 +582,9 @@ export default {
|
|||
this.customFieldForm = parseCustomField(this.form, this.testCaseTemplate, this.customFieldRules);
|
||||
this.reload();
|
||||
}
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
handlePre() {
|
||||
this.index--;
|
||||
|
@ -706,10 +738,13 @@ export default {
|
|||
this.close();
|
||||
}
|
||||
this.form.id = response.data.id;
|
||||
|
||||
this.currentTestCaseInfo.id = response.data.id;
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
if (hasLicense()) {
|
||||
this.getVersionHistory();
|
||||
}
|
||||
// 保存用例后刷新附件
|
||||
});
|
||||
}
|
||||
|
@ -886,6 +921,73 @@ export default {
|
|||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
getVersionHistory() {
|
||||
this.$get('/test/case/versions/' + this.currentTestCaseInfo.id, response => {
|
||||
for (let i = 0; i < response.data.length ; i++) {
|
||||
this.currentProjectId = response.data[i].projectId
|
||||
}
|
||||
this.versionData = response.data;
|
||||
this.$refs.versionHistory.loading = false;
|
||||
});
|
||||
},
|
||||
setSpecialPropForCompare: function (that) {
|
||||
that.newData.tags = JSON.parse(that.newData.tags || "");
|
||||
that.newData.steps = JSON.parse(that.newData.steps || "");
|
||||
that.oldData.tags = JSON.parse(that.oldData.tags || "");
|
||||
that.oldData.steps = JSON.parse(that.oldData.steps || "");
|
||||
that.newData.readOnly = true;
|
||||
that.oldData.readOnly = true;
|
||||
},
|
||||
compare(row) {
|
||||
this.$get('/test/case/get/' + row.id + "/" + this.currentTestCaseInfo.refId, response => {
|
||||
let p1 = this.$get('/test/case/get/' + response.data.id);
|
||||
let p2 = this.$get('/test/case/get/' + this.currentTestCaseInfo.id);
|
||||
let that = this;
|
||||
Promise.all([p1, p2]).then(data => {
|
||||
if (data[0] && data[1]) {
|
||||
that.newData = data[0].data.data;
|
||||
that.oldData = data[1].data.data;
|
||||
this.setSpecialPropForCompare(that);
|
||||
that.dialogVisible = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
checkout(row) {
|
||||
this.$refs.versionHistory.loading = true;
|
||||
let testCase = this.versionData.filter(v => v.versionId === row.id)[0];
|
||||
if (testCase) {
|
||||
this.$get('test/case/get/' + testCase.id, response => {
|
||||
let testCase = response.data;
|
||||
this.$emit("checkout", testCase);
|
||||
this.$refs.versionHistory.loading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
create(row) {
|
||||
// 创建新版本
|
||||
this.form.versionId = row.id;
|
||||
this.saveCase();
|
||||
},
|
||||
del(row) {
|
||||
let that = this;
|
||||
this.$alert(this.$t('api_test.definition.request.delete_confirm') + ' ' + row.name + " ?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.$get('/test/case/delete/' + row.id + '/' + this.form.refId, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.getVersionHistory();
|
||||
});
|
||||
} else {
|
||||
that.$refs.versionHistory.loading = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
changeType(type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -954,8 +954,8 @@ export default {
|
|||
});
|
||||
},
|
||||
_handleDeletePublic(testCase) {
|
||||
let testCaseId = testCase.id;
|
||||
this.$post('/test/case/deletePublic/' + testCaseId, {}, () => {
|
||||
let refId = testCase.refId;
|
||||
this.$post('/test/case/deletePublic/' + refId, {}, () => {
|
||||
this.$emit('refreshTable');
|
||||
this.initTableData();
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
|
@ -1082,13 +1082,18 @@ export default {
|
|||
|
||||
},
|
||||
handleDeleteBatchToPublic() {
|
||||
let param = {};
|
||||
param.ids = this.$refs.table.selectIds;
|
||||
param.casePublic = false;
|
||||
param.condition = this.condition;
|
||||
this.page.result = this.$post('/test/case/batch/edit', param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.refresh();
|
||||
this.$alert(this.$t('test_track.case.delete_confirm') + "?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
let param = buildBatchParam(this, this.$refs.table.selectIds);
|
||||
this.$post('/test/case/batch/movePublic/deleteToGc', param, () => {
|
||||
this.$refs.table.clear();
|
||||
this.$emit("refresh");
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleBatchMove() {
|
||||
|
@ -1118,6 +1123,7 @@ export default {
|
|||
},
|
||||
copyPublic(param) {
|
||||
param.condition = this.condition;
|
||||
param.projectId = this.projectId;
|
||||
this.page.result = this.$post('/test/case/batch/copy/public', param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$refs.testBatchMove.close();
|
||||
|
|
|
@ -16,17 +16,18 @@
|
|||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('test_track.case.module')" :label-width="oldData.formLabelWidth" prop="module">
|
||||
<el-form-item :label="$t('test_track.case.module')" :label-width="oldData.formLabelWidth" prop="module" v-if="!isPublic">
|
||||
<ms-select-tree :disabled="oldData.readOnly" :data="treeNodes" :defaultKey="oldData.module"
|
||||
:obj="moduleObj"
|
||||
@getValue="setModule" clearable checkStrictly size="small"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('test_track.case.project')" :label-width="oldData.formLabelWidth" prop="projectId"
|
||||
v-if="publicEnable">
|
||||
<el-select v-model="oldData.projectId" filterable clearable>
|
||||
v-if="isPublic" >
|
||||
<el-select v-model="oldData.projectId" filterable clearable :disabled="oldData.readOnly">
|
||||
<el-option v-for="item in projectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -45,7 +46,7 @@
|
|||
ref="oldCustomFieldForm"
|
||||
class="case-form">
|
||||
<custom-filed-form-item :form="oldData.customFieldForm" :form-label-width="oldData.formLabelWidth"
|
||||
:issue-template="oldData.testCaseTemplate"/>
|
||||
:issue-template="oldData.testCaseTemplate" :is-public="isPublic"/>
|
||||
</el-form>
|
||||
|
||||
<el-row v-if="oldData.isCustomNum">
|
||||
|
@ -91,7 +92,7 @@
|
|||
:key="index"
|
||||
:comment="comment"
|
||||
@refresh="getComments" api-url="/test/case"/>
|
||||
<div v-if="oldData.comments.length === 0" style="text-align: center">
|
||||
<div v-if="oldData.comments && oldData.comments.length === 0" style="text-align: center">
|
||||
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
|
||||
<span style="font-size: 15px; color: #8a8b8d;">
|
||||
{{ $t('test_track.comment.no_comment') }}
|
||||
|
@ -121,7 +122,7 @@
|
|||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('test_track.case.module')" :label-width="newData.formLabelWidth" prop="module">
|
||||
<el-form-item :label="$t('test_track.case.module')" :label-width="newData.formLabelWidth" prop="module" v-if="!isPublic">
|
||||
<ms-select-tree :disabled="newData.readOnly" :data="treeNodes" :defaultKey="newData.module"
|
||||
:obj="moduleObj"
|
||||
@getValue="setModule" clearable checkStrictly size="small"/>
|
||||
|
@ -130,8 +131,8 @@
|
|||
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('test_track.case.project')" :label-width="newData.formLabelWidth" prop="projectId"
|
||||
v-if="publicEnable">
|
||||
<el-select v-model="newData.projectId" filterable clearable>
|
||||
v-if="isPublic" >
|
||||
<el-select v-model="newData.projectId" filterable clearable :disabled="newData.readOnly">
|
||||
<el-option v-for="item in projectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -150,7 +151,7 @@
|
|||
ref="newCustomFieldForm"
|
||||
class="case-form">
|
||||
<custom-filed-form-item :form="newData.customFieldForm" :form-label-width="newData.formLabelWidth"
|
||||
:issue-template="newData.testCaseTemplate"/>
|
||||
:issue-template="newData.testCaseTemplate" :is-public="isPublic"/>
|
||||
</el-form>
|
||||
|
||||
<el-row v-if="newData.isCustomNum">
|
||||
|
@ -196,7 +197,7 @@
|
|||
:key="index"
|
||||
:comment="comment"
|
||||
@refresh="getComments" api-url="/test/case"/>
|
||||
<div v-if="newData.comments.length === 0" style="text-align: center">
|
||||
<div v-if="newData.comments && newData.comments.length === 0" style="text-align: center">
|
||||
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
|
||||
<span style="font-size: 15px; color: #8a8b8d;">
|
||||
{{ $t('test_track.comment.no_comment') }}
|
||||
|
@ -253,6 +254,12 @@ export default {
|
|||
type: Object
|
||||
},
|
||||
treeNodes: [],
|
||||
isPublic: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
projectIds() {
|
||||
|
@ -268,7 +275,6 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
path: "/test/case/add",
|
||||
isPublic: false,
|
||||
isXpack: false,
|
||||
projectList: [],
|
||||
result: {},
|
||||
|
@ -292,7 +298,6 @@ export default {
|
|||
},
|
||||
versionData: [],
|
||||
dialogVisible: false,
|
||||
publicEnable: false,
|
||||
maintainerOptions: [],
|
||||
oldLoading: null,
|
||||
newLoading: null,
|
||||
|
|
|
@ -190,7 +190,7 @@ export let CUSTOM_TABLE_HEADER = {
|
|||
{id: 'name', key: '2', label: 'commons.name'},
|
||||
{id: 'reviewStatus', key: '3', label: 'test_track.case.status'},
|
||||
{id: 'tags', key: '4', label: 'commons.tag'},
|
||||
{id: 'versionId', key: 'a', label: 'project.version.name', xpack: true},
|
||||
{id: 'versionId', key: 'b', label: 'project.version.name', xpack: true},
|
||||
{id: 'nodePath', key: '5', label: 'test_track.case.module'},
|
||||
{id: 'projectName', key: 'a', label: 'test_track.review.review_project'},
|
||||
{id: 'updateTime', key: '6', label: 'commons.update_time'},
|
||||
|
|
Loading…
Reference in New Issue