feat(测试计划): 测试计划新增批量开启/关闭定时任务功能
This commit is contained in:
parent
89fd47bace
commit
9289719449
|
@ -3,6 +3,8 @@ package io.metersphere.api.dto.datacount.request;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author song.tianyang
|
* @author song.tianyang
|
||||||
* @Date 2020/12/17 5:04 下午
|
* @Date 2020/12/17 5:04 下午
|
||||||
|
@ -13,4 +15,5 @@ import lombok.Setter;
|
||||||
public class ScheduleInfoRequest {
|
public class ScheduleInfoRequest {
|
||||||
private String taskID;
|
private String taskID;
|
||||||
private boolean enable;
|
private boolean enable;
|
||||||
|
private List<String> taskIds;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@
|
||||||
</include>
|
</include>
|
||||||
</if>
|
</if>
|
||||||
<if test="${condition}.principal != null">
|
<if test="${condition}.principal != null">
|
||||||
and test_plan.id in (SELECT test_plan_id FROM test_plan_principal WHERE principal_id
|
and test_plan.id in (SELECT test_plan_id FROM test_plan_principal WHERE principal_id
|
||||||
<include refid="condition">
|
<include refid="condition">
|
||||||
<property name="object" value="${condition}.principal"/>
|
<property name="object" value="${condition}.principal"/>
|
||||||
</include>
|
</include>
|
||||||
|
@ -114,8 +114,8 @@
|
||||||
<select id="list" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric"
|
<select id="list" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric"
|
||||||
parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
||||||
select DISTINCT test_plan.*, project.name as projectName,schedule.id as scheduleId,
|
select DISTINCT test_plan.*, project.name as projectName,schedule.id as scheduleId,
|
||||||
(select name from user where user.id = test_plan.creator) as createUser,
|
(select name from user where user.id = test_plan.creator) as createUser,
|
||||||
IF(schedule.enable = true,true,false) as scheduleOpen,
|
IF(schedule.enable = true,true,false) as scheduleOpen,
|
||||||
(select COUNT(*) from test_plan_test_case t
|
(select COUNT(*) from test_plan_test_case t
|
||||||
inner join test_case on t.case_id = test_case.id
|
inner join test_case on t.case_id = test_case.id
|
||||||
left join test_case_node on test_case_node.id = test_case.node_id
|
left join test_case_node on test_case_node.id = test_case.node_id
|
||||||
|
@ -176,21 +176,23 @@
|
||||||
<when test="key=='status'">
|
<when test="key=='status'">
|
||||||
<choose>
|
<choose>
|
||||||
<when test="request.executorOrPrincipal != null">
|
<when test="request.executorOrPrincipal != null">
|
||||||
AND (( test_plan_principal.principal_id = '${@io.metersphere.commons.utils.SessionUtils@getUserId()}' and
|
AND (( test_plan_principal.principal_id =
|
||||||
test_plan.status in
|
'${@io.metersphere.commons.utils.SessionUtils@getUserId()}' and
|
||||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
test_plan.status in
|
||||||
#{value}
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
</foreach>
|
#{value}
|
||||||
)
|
</foreach>
|
||||||
or
|
)
|
||||||
(test_plan_test_case.executor = '${@io.metersphere.commons.utils.SessionUtils@getUserId()}' and
|
or
|
||||||
test_plan_test_case.status in
|
(test_plan_test_case.executor =
|
||||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
'${@io.metersphere.commons.utils.SessionUtils@getUserId()}' and
|
||||||
#{value}
|
test_plan_test_case.status in
|
||||||
</foreach>
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
))
|
#{value}
|
||||||
|
</foreach>
|
||||||
|
))
|
||||||
</when>
|
</when>
|
||||||
<otherwise >
|
<otherwise>
|
||||||
and test_plan.status in
|
and test_plan.status in
|
||||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
#{value}
|
#{value}
|
||||||
|
@ -198,6 +200,20 @@
|
||||||
</otherwise>
|
</otherwise>
|
||||||
</choose>
|
</choose>
|
||||||
</when>
|
</when>
|
||||||
|
<when test="key=='schedule_status'">
|
||||||
|
and
|
||||||
|
<foreach collection="values" item="value" separator="or" open="(" close=")">
|
||||||
|
<if test="value == 'OPEN'">
|
||||||
|
schedule.`enable` = 1
|
||||||
|
</if>
|
||||||
|
<if test="value == 'SHUT'">
|
||||||
|
schedule.`enable` = 0
|
||||||
|
</if>
|
||||||
|
<if test="value == 'NOTSET' ">
|
||||||
|
schedule.id is null
|
||||||
|
</if>
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
</choose>
|
</choose>
|
||||||
</if>
|
</if>
|
||||||
</foreach>
|
</foreach>
|
||||||
|
@ -277,14 +293,17 @@
|
||||||
<foreach collection="projectIds" item="id" separator="," open="(" close=")">
|
<foreach collection="projectIds" item="id" separator="," open="(" close=")">
|
||||||
#{id}
|
#{id}
|
||||||
</foreach>
|
</foreach>
|
||||||
</if>) as temp
|
</if>
|
||||||
|
) as temp
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectTestPlanByRelevancy" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
<select id="selectTestPlanByRelevancy" resultMap="BaseResultMap"
|
||||||
|
parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
||||||
SELECT * FROM test_plan p
|
SELECT * FROM test_plan p
|
||||||
<where>
|
<where>
|
||||||
<if test="request.scenarioId != null">
|
<if test="request.scenarioId != null">
|
||||||
AND p.id IN (SELECT test_plan_id FROM test_plan_api_scenario WHERE api_scenario_id = #{request.scenarioId} )
|
AND p.id IN (SELECT test_plan_id FROM test_plan_api_scenario WHERE api_scenario_id =
|
||||||
|
#{request.scenarioId} )
|
||||||
</if>
|
</if>
|
||||||
<if test="request.apiId != null">
|
<if test="request.apiId != null">
|
||||||
AND p.id IN (SELECT test_plan_id FROM test_plan_api_case WHERE api_case_id = #{request.apiId})
|
AND p.id IN (SELECT test_plan_id FROM test_plan_api_case WHERE api_case_id = #{request.apiId})
|
||||||
|
@ -295,18 +314,24 @@
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
<select id="findTestProjectNameByTestPlanID" resultType="java.lang.String">
|
<select id="findTestProjectNameByTestPlanID" resultType="java.lang.String">
|
||||||
SELECT p.name FROM test_plan tp INNER JOIN project p ON p.id =tp.project_id
|
SELECT p.name
|
||||||
WHERE tp.id = #{0} limit 1;
|
FROM test_plan tp
|
||||||
|
INNER JOIN project p ON p.id = tp.project_id
|
||||||
|
WHERE tp.id = #{0}
|
||||||
|
limit 1;
|
||||||
</select>
|
</select>
|
||||||
<select id="findScheduleCreateUserById" resultType="java.lang.String">
|
<select id="findScheduleCreateUserById" resultType="java.lang.String">
|
||||||
SELECT user_id FROM `schedule`
|
SELECT user_id
|
||||||
|
FROM `schedule`
|
||||||
WHERE resource_id = #{0}
|
WHERE resource_id = #{0}
|
||||||
limit 1;
|
limit 1;
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="findIdByPerformanceReportId" resultType="java.lang.String">
|
<select id="findIdByPerformanceReportId" resultType="java.lang.String">
|
||||||
SELECT report.id FROM test_plan_report report INNER JOIN test_plan_report_data reportData ON report.id = reportData.test_plan_report_id
|
SELECT report.id
|
||||||
WHERE reportData.performance_info like CONCAT('%', #{0},'%')
|
FROM test_plan_report report
|
||||||
|
INNER JOIN test_plan_report_data reportData ON report.id = reportData.test_plan_report_id
|
||||||
|
WHERE reportData.performance_info like CONCAT('%', #{0}, '%')
|
||||||
AND report.is_performance_executing = true;
|
AND report.is_performance_executing = true;
|
||||||
</select>
|
</select>
|
||||||
<select id="listRecent" resultType="io.metersphere.base.domain.TestPlan">
|
<select id="listRecent" resultType="io.metersphere.base.domain.TestPlan">
|
||||||
|
@ -316,7 +341,7 @@
|
||||||
<if test="projectId != null">
|
<if test="projectId != null">
|
||||||
and test_plan.project_id = #{projectId}
|
and test_plan.project_id = #{projectId}
|
||||||
</if>
|
</if>
|
||||||
and (test_plan.creator = #{userId} or test_plan.principal = #{userId})
|
and (test_plan.creator = #{userId} or test_plan.principal = #{userId})
|
||||||
</where>
|
</where>
|
||||||
order by test_plan.update_time desc
|
order by test_plan.update_time desc
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
|
public enum ScheduleStatus {
|
||||||
|
OPEN,SHUT,NOTSET
|
||||||
|
}
|
|
@ -277,4 +277,9 @@ public class TestPlanController {
|
||||||
public List<User> getPlanFollow(@PathVariable String planId) {
|
public List<User> getPlanFollow(@PathVariable String planId) {
|
||||||
return testPlanService.getPlanFollow(planId);
|
return testPlanService.getPlanFollow(planId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/schedule/Batch/updateEnable")
|
||||||
|
public void updateBatchScheduleEnable(@RequestBody ScheduleInfoRequest request) {
|
||||||
|
testPlanService.batchUpdateScheduleEnable(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,16 @@ public class TestPlanDTO extends TestPlanWithBLOBs {
|
||||||
* 定时任务是否开启
|
* 定时任务是否开启
|
||||||
*/
|
*/
|
||||||
private boolean scheduleOpen;
|
private boolean scheduleOpen;
|
||||||
|
/**
|
||||||
|
* 定时任务状态
|
||||||
|
*/
|
||||||
|
private String scheduleStatus;
|
||||||
|
/**
|
||||||
|
* 定时任务规则
|
||||||
|
*/
|
||||||
|
private String scheduleCorn;
|
||||||
|
/**
|
||||||
|
* 定时任务下一次执行时间
|
||||||
|
*/
|
||||||
|
private Long scheduleExecuteTime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.google.gson.Gson;
|
||||||
import io.metersphere.api.dto.APIReportResult;
|
import io.metersphere.api.dto.APIReportResult;
|
||||||
import io.metersphere.api.dto.EnvironmentType;
|
import io.metersphere.api.dto.EnvironmentType;
|
||||||
import io.metersphere.api.dto.automation.*;
|
import io.metersphere.api.dto.automation.*;
|
||||||
|
import io.metersphere.api.dto.datacount.request.ScheduleInfoRequest;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||||
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
|
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
|
||||||
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||||
|
@ -55,6 +56,10 @@ import org.apache.ibatis.session.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.mybatis.spring.SqlSessionUtils;
|
import org.mybatis.spring.SqlSessionUtils;
|
||||||
|
import org.quartz.CronExpression;
|
||||||
|
import org.quartz.CronScheduleBuilder;
|
||||||
|
import org.quartz.CronTrigger;
|
||||||
|
import org.quartz.TriggerBuilder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
@ -431,6 +436,18 @@ public class TestPlanService {
|
||||||
TestPlanReportExample example = new TestPlanReportExample();
|
TestPlanReportExample example = new TestPlanReportExample();
|
||||||
example.createCriteria().andTestPlanIdEqualTo(item.getId());
|
example.createCriteria().andTestPlanIdEqualTo(item.getId());
|
||||||
item.setExecutionTimes((int) testPlanReportMapper.countByExample(example));
|
item.setExecutionTimes((int) testPlanReportMapper.countByExample(example));
|
||||||
|
if (StringUtils.isNotBlank(item.getScheduleId())) {
|
||||||
|
if (item.isScheduleOpen()) {
|
||||||
|
item.setScheduleStatus(ScheduleStatus.OPEN.name());
|
||||||
|
Schedule schedule = scheduleService.getScheduleByResource(item.getId(), ScheduleGroup.TEST_PLAN_TEST.name());
|
||||||
|
item.setScheduleCorn(schedule.getValue());
|
||||||
|
item.setScheduleExecuteTime(getNextTriggerTime(schedule.getValue()));
|
||||||
|
} else {
|
||||||
|
item.setScheduleStatus(ScheduleStatus.SHUT.name());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.setScheduleStatus(ScheduleStatus.NOTSET.name());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
calcTestPlanRate(testPlans);
|
calcTestPlanRate(testPlans);
|
||||||
return testPlans;
|
return testPlans;
|
||||||
|
@ -1983,4 +2000,23 @@ public class TestPlanService {
|
||||||
}
|
}
|
||||||
return JSONArray.parseArray(customFields.get(0).getOptions());
|
return JSONArray.parseArray(customFields.get(0).getOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void batchUpdateScheduleEnable(ScheduleInfoRequest request) {
|
||||||
|
for (String id : request.getTaskIds()) {
|
||||||
|
Schedule schedule = scheduleService.getSchedule(id);
|
||||||
|
schedule.setEnable(request.isEnable());
|
||||||
|
apiAutomationService.updateSchedule(schedule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取下次执行时间(getFireTimeAfter,也可以下下次...)
|
||||||
|
private static long getNextTriggerTime(String cron) {
|
||||||
|
if (!CronExpression.isValidExpression(cron)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("Caclulate Date").withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
|
||||||
|
Date time0 = trigger.getStartTime();
|
||||||
|
Date time1 = trigger.getFireTimeAfter(time0);
|
||||||
|
return time1.getTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<el-dialog :visible.sync="dialogFormVisible"
|
||||||
|
:before-close="close"
|
||||||
|
width="14%">
|
||||||
|
<div>
|
||||||
|
<el-switch
|
||||||
|
v-model="schedule.enable"
|
||||||
|
:inactive-text="$t('test_track.plan.batch_update_schedule_enable', [size])"
|
||||||
|
active-color="#783887">
|
||||||
|
</el-switch>
|
||||||
|
<p style="font-size: 10px;color: gray;margin-bottom: -10px">
|
||||||
|
{{ $t('test_track.plan.batch_update_schedule_enable_alert') }}</p>
|
||||||
|
</div>
|
||||||
|
<template v-slot:footer>
|
||||||
|
<ms-dialog-footer
|
||||||
|
@cancel="close"
|
||||||
|
@confirm="saveTest"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsDialogFooter from "../../../common/components/MsDialogFooter";
|
||||||
|
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {MsDialogFooter},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
name: "MsTestPlanScheduleBatchSwitch",
|
||||||
|
schedule: {
|
||||||
|
enable: true,
|
||||||
|
taskIds: []
|
||||||
|
},
|
||||||
|
size: 0,
|
||||||
|
selectRows: new Set(),
|
||||||
|
allDataRows: new Set(),
|
||||||
|
dialogFormVisible: false,
|
||||||
|
test: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
treeNodes: {
|
||||||
|
type: Array
|
||||||
|
},
|
||||||
|
currentProject: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open(ids, size) {
|
||||||
|
if (size) {
|
||||||
|
this.size = size;
|
||||||
|
} else {
|
||||||
|
this.size = this.$parent.selectDataCounts;
|
||||||
|
}
|
||||||
|
this.schedule.taskIds = ids;
|
||||||
|
listenGoBack(this.close);
|
||||||
|
this.dialogFormVisible = true;
|
||||||
|
},
|
||||||
|
saveTest() {
|
||||||
|
this.$post("/test/plan/schedule/Batch/updateEnable", this.schedule, () => {
|
||||||
|
this.$success(this.$t('commons.modify_success'));
|
||||||
|
this.dialogFormVisible = false;
|
||||||
|
this.$emit("refreshTable");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
removeGoBackListener(this.close);
|
||||||
|
this.dialogFormVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -255,6 +255,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.taskID = paramTestId;
|
this.taskID = paramTestId;
|
||||||
this.findSchedule(paramTestId);
|
this.findSchedule(paramTestId);
|
||||||
|
this.$emit("refreshTable");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
initUserList() {
|
initUserList() {
|
||||||
|
|
|
@ -7,267 +7,297 @@
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table
|
<ms-table
|
||||||
border
|
|
||||||
class="adjust-table"
|
|
||||||
:data="tableData"
|
|
||||||
@filter-change="filter"
|
|
||||||
@sort-change="sort"
|
|
||||||
:height="screenHeight"
|
|
||||||
v-loading="result.loading"
|
v-loading="result.loading"
|
||||||
@row-click="intoPlan">
|
operator-width="170px"
|
||||||
<template v-for="(item, index) in tableLabel">
|
row-key="id"
|
||||||
<el-table-column
|
:data="tableData"
|
||||||
v-if="item.id == 'name'"
|
:condition="condition"
|
||||||
|
:total="total"
|
||||||
|
:page-size.sync="pageSize"
|
||||||
|
:operators="operators"
|
||||||
|
:screen-height="screenHeight"
|
||||||
|
:batch-operators="batchButtons"
|
||||||
|
:remember-order="true"
|
||||||
|
:fields.sync="fields"
|
||||||
|
:field-key="tableHeaderKey"
|
||||||
|
@handlePageChange="intoPlan"
|
||||||
|
@refresh="initTableData"
|
||||||
|
ref="testPlanLitTable">
|
||||||
|
|
||||||
|
<span v-for="item in fields" :key="item.key">
|
||||||
|
|
||||||
|
<ms-table-column
|
||||||
prop="name"
|
prop="name"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:label="$t('commons.name')"
|
:label="$t('commons.name')"
|
||||||
show-overflow-tooltip
|
min-width="200px">
|
||||||
:key="index">
|
</ms-table-column>
|
||||||
</el-table-column>
|
<ms-table-column
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'userName'"
|
|
||||||
prop="principalName"
|
prop="principalName"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:label="$t('test_track.plan.plan_principal')"
|
:label="$t('test_track.plan.plan_principal')"
|
||||||
show-overflow-tooltip
|
min-width="200px">
|
||||||
:key="index">
|
</ms-table-column>
|
||||||
</el-table-column>
|
<ms-table-column
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'createUser'"
|
|
||||||
prop="createUser"
|
prop="createUser"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:label="$t('commons.create_user')"
|
:label="$t('commons.create_user')"
|
||||||
show-overflow-tooltip
|
min-width="200px">
|
||||||
:key="index">
|
</ms-table-column>
|
||||||
</el-table-column>
|
<ms-table-column
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'status'"
|
|
||||||
prop="status"
|
prop="status"
|
||||||
column-key="status"
|
|
||||||
:filters="statusFilters"
|
:filters="statusFilters"
|
||||||
:label="$t('test_track.plan.plan_status')"
|
column-key="status"
|
||||||
show-overflow-tooltip
|
:field="item"
|
||||||
:min-width="100"
|
:fields-width="fieldsWidth"
|
||||||
:key="index">
|
min-width="120px"
|
||||||
<template v-slot:default="scope">
|
:label="$t('test_track.plan.plan_status')">
|
||||||
<span @click.stop="clickt = 'stop'">
|
<template v-slot:default="scope">
|
||||||
<el-dropdown class="test-case-status" @command="statusChange">
|
<span @click.stop="clickt = 'stop'">
|
||||||
<span class="el-dropdown-link">
|
<el-dropdown class="test-case-status" @command="statusChange">
|
||||||
<plan-status-table-item :value="scope.row.status"/>
|
<span class="el-dropdown-link">
|
||||||
</span>
|
<plan-status-table-item :value="scope.row.status"/>
|
||||||
<el-dropdown-menu slot="dropdown" chang>
|
</span>
|
||||||
<el-dropdown-item :disabled="!hasEditPermission" :command="{item: scope.row, status: 'Prepare'}">
|
<el-dropdown-menu slot="dropdown" chang>
|
||||||
{{ $t('test_track.plan.plan_status_prepare') }}
|
<el-dropdown-item :disabled="!hasEditPermission" :command="{item: scope.row, status: 'Prepare'}">
|
||||||
</el-dropdown-item>
|
{{ $t('test_track.plan.plan_status_prepare') }}
|
||||||
<el-dropdown-item :disabled="!hasEditPermission"
|
</el-dropdown-item>
|
||||||
:command="{item: scope.row, status: 'Underway'}">
|
<el-dropdown-item :disabled="!hasEditPermission"
|
||||||
{{ $t('test_track.plan.plan_status_running') }}
|
:command="{item: scope.row, status: 'Underway'}">
|
||||||
</el-dropdown-item>
|
{{ $t('test_track.plan.plan_status_running') }}
|
||||||
<el-dropdown-item :disabled="!hasEditPermission"
|
</el-dropdown-item>
|
||||||
:command="{item: scope.row, status: 'Finished'}">
|
<el-dropdown-item :disabled="!hasEditPermission"
|
||||||
{{ $t('test_track.plan.plan_status_finished') }}
|
:command="{item: scope.row, status: 'Finished'}">
|
||||||
</el-dropdown-item>
|
{{ $t('test_track.plan.plan_status_finished') }}
|
||||||
<el-dropdown-item :disabled="!hasEditPermission"
|
</el-dropdown-item>
|
||||||
:command="{item: scope.row, status: 'Completed'}">
|
<el-dropdown-item :disabled="!hasEditPermission"
|
||||||
{{ $t('test_track.plan.plan_status_completed') }}
|
:command="{item: scope.row, status: 'Completed'}">
|
||||||
</el-dropdown-item>
|
{{ $t('test_track.plan.plan_status_completed') }}
|
||||||
</el-dropdown-menu>
|
</el-dropdown-item>
|
||||||
</el-dropdown>
|
</el-dropdown-menu>
|
||||||
</span>
|
</el-dropdown>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</ms-table-column>
|
||||||
|
<ms-table-column
|
||||||
|
prop="scheduleStatus"
|
||||||
|
:filters="scheduleFilters"
|
||||||
|
column-key="scheduleStatus"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
min-width="200px"
|
||||||
|
:label="$t('commons.trigger_mode.schedule')">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span v-if="scope.row.scheduleStatus === 'OPEN'">
|
||||||
|
<el-tooltip placement="bottom-start" effect="light">
|
||||||
|
<div slot="content">
|
||||||
|
{{ $t('api_test.home_page.running_task_list.table_coloum.run_rule') }}: {{
|
||||||
|
scope.row.scheduleCorn
|
||||||
|
}}<br/>
|
||||||
|
{{ $t('test_track.plan.next_run_time') }}:<span>{{
|
||||||
|
scope.row.scheduleExecuteTime | timestampFormatDate
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row.scheduleOpen"
|
||||||
|
inactive-color="#DCDFE6"
|
||||||
|
@change="scheduleChange(scope.row)">
|
||||||
|
</el-switch>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
<span v-else-if="scope.row.scheduleStatus === 'SHUT'">
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row.scheduleOpen"
|
||||||
|
inactive-color="#DCDFE6"
|
||||||
|
@change="scheduleChange(scope.row)">
|
||||||
|
</el-switch>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
<el-link @click.stop="scheduleTask(scope.row)" style="color:#783887;">{{
|
||||||
|
$t('schedule.not_set')
|
||||||
|
}}</el-link>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</ms-table-column>
|
||||||
<el-table-column
|
<ms-table-column
|
||||||
v-if="item.id=='follow'"
|
|
||||||
prop="follow"
|
prop="follow"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:label="$t('test_track.plan.follow_people')"
|
:label="$t('test_track.plan.follow_people')"
|
||||||
show-overflow-tooltip
|
min-width="200px">
|
||||||
:key="index"
|
</ms-table-column>
|
||||||
>
|
<ms-table-column
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'stage'"
|
|
||||||
prop="stage"
|
prop="stage"
|
||||||
column-key="stage"
|
column-key="stage"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:filters="stageFilters"
|
:filters="stageFilters"
|
||||||
:label="$t('test_track.plan.plan_stage')"
|
:label="$t('test_track.plan.plan_stage')"
|
||||||
show-overflow-tooltip
|
min-width="120px">
|
||||||
:min-width="110"
|
|
||||||
:key="index">
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<plan-stage-table-item :option="stageOption" :stage="scope.row.stage"/>
|
<plan-stage-table-item :option="stageOption" :stage="scope.row.stage"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</ms-table-column>
|
||||||
<el-table-column
|
<ms-table-column
|
||||||
v-if="item.id == 'testRate'"
|
|
||||||
prop="testRate"
|
prop="testRate"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
:label="$t('test_track.home.test_rate')"
|
:label="$t('test_track.home.test_rate')"
|
||||||
min-width="100"
|
min-width="120px">
|
||||||
show-overflow-tooltip
|
|
||||||
:key="index">
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<el-progress :percentage="scope.row.testRate"></el-progress>
|
<el-progress :percentage="scope.row.testRate"></el-progress>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</ms-table-column>
|
||||||
<el-table-column
|
<ms-table-column
|
||||||
v-if="item.id == 'projectName'"
|
|
||||||
prop="projectName"
|
prop="projectName"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
:label="$t('test_track.plan.plan_project')"
|
:label="$t('test_track.plan.plan_project')"
|
||||||
show-overflow-tooltip
|
min-width="200px">
|
||||||
:key="index">
|
</ms-table-column>
|
||||||
</el-table-column>
|
<ms-table-column
|
||||||
<el-table-column v-if="item.id == 'tags'" prop="tags"
|
prop="tags"
|
||||||
:label="$t('api_test.automation.tag')" :key="index">
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
|
:label="$t('api_test.automation.tag')"
|
||||||
|
min-width="200px">
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain"
|
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain"
|
||||||
:content="itemName" style="margin-left: 0px; margin-right: 2px"></ms-tag>
|
:content="itemName" style="margin-left: 0px; margin-right: 2px"></ms-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</ms-table-column>
|
||||||
<el-table-column
|
<ms-table-column
|
||||||
v-if="item.id == 'executionTimes'"
|
|
||||||
prop="executionTimes"
|
prop="executionTimes"
|
||||||
:label="$t('commons.execution_times')"
|
:field="item"
|
||||||
show-overflow-tooltip
|
:fields-width="fieldsWidth"
|
||||||
:min-width="100"
|
|
||||||
:key="index">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'testPlanTestCaseCount'"
|
|
||||||
prop="testPlanTestCaseCount"
|
|
||||||
:label="$t('test_track.plan.test_plan_test_case_count')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
:min-width="100"
|
|
||||||
:key="index">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'testPlanApiCaseCount'"
|
|
||||||
prop="testPlanApiCaseCount"
|
|
||||||
:label="$t('test_track.plan.test_plan_api_case_count')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
:min-width="100"
|
|
||||||
:key="index">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'testPlanApiScenarioCount'"
|
|
||||||
prop="testPlanApiScenarioCount"
|
|
||||||
:label="$t('test_track.plan.test_plan_api_scenario_count')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
:min-width="100"
|
|
||||||
:key="index">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'testPlanLoadCaseCount'"
|
|
||||||
prop="testPlanLoadCaseCount"
|
|
||||||
:label="$t('test_track.plan.test_plan_load_case_count')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
:min-width="100"
|
|
||||||
:key="index">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'passRate'"
|
|
||||||
prop="passRate"
|
|
||||||
:label="$t('commons.pass_rate')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
:key="index">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
v-if="item.id == 'plannedStartTime'"
|
|
||||||
sortable
|
sortable
|
||||||
|
:label="$t('commons.execution_times')"
|
||||||
|
min-width="160px">
|
||||||
|
</ms-table-column>
|
||||||
|
<ms-table-column
|
||||||
|
prop="testPlanTestCaseCount"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
:label="$t('test_track.plan.test_plan_test_case_count')"
|
||||||
|
min-width="200px">
|
||||||
|
</ms-table-column>
|
||||||
|
<ms-table-column
|
||||||
|
prop="testPlanApiCaseCount"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
:label="$t('test_track.plan.test_plan_api_case_count')"
|
||||||
|
min-width="200px">
|
||||||
|
</ms-table-column>
|
||||||
|
<ms-table-column
|
||||||
|
prop="testPlanApiScenarioCount"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
:label="$t('test_track.plan.test_plan_api_scenario_count')"
|
||||||
|
min-width="200px">
|
||||||
|
</ms-table-column>
|
||||||
|
<ms-table-column
|
||||||
|
prop="testPlanLoadCaseCount"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
:label="$t('test_track.plan.test_plan_load_case_count')"
|
||||||
|
min-width="200px">
|
||||||
|
</ms-table-column>
|
||||||
|
<ms-table-column
|
||||||
|
prop="passRate"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
|
:label="$t('commons.pass_rate')"
|
||||||
|
min-width="120px">
|
||||||
|
</ms-table-column>
|
||||||
|
<ms-table-column
|
||||||
prop="plannedStartTime"
|
prop="plannedStartTime"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:label="$t('test_track.plan.planned_start_time')"
|
:label="$t('test_track.plan.planned_start_time')"
|
||||||
show-overflow-tooltip
|
min-width="200px">
|
||||||
:min-width="110"
|
|
||||||
:key="index">
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span>{{ scope.row.plannedStartTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.plannedStartTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</ms-table-column>
|
||||||
<el-table-column
|
<ms-table-column
|
||||||
v-if="item.id == 'plannedEndTime'"
|
|
||||||
sortable
|
|
||||||
prop="plannedEndTime"
|
prop="plannedEndTime"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:label="$t('test_track.plan.planned_end_time')"
|
:label="$t('test_track.plan.planned_end_time')"
|
||||||
show-overflow-tooltip
|
min-width="160px">
|
||||||
:min-width="110"
|
|
||||||
:key="index">
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span>{{ scope.row.plannedEndTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.plannedEndTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</ms-table-column>
|
||||||
<el-table-column
|
<ms-table-column
|
||||||
v-if="item.id == 'actualStartTime'"
|
|
||||||
sortable
|
|
||||||
prop="actualStartTime"
|
prop="actualStartTime"
|
||||||
:min-width="110"
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:label="$t('test_track.plan.actual_start_time')"
|
:label="$t('test_track.plan.actual_start_time')"
|
||||||
show-overflow-tooltip
|
min-width="200px">
|
||||||
:key="index">
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span>{{ scope.row.actualStartTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.actualStartTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</ms-table-column>
|
||||||
<el-table-column
|
<ms-table-column
|
||||||
v-if="item.id == 'actualEndTime'"
|
|
||||||
sortable
|
|
||||||
:min-width="110"
|
|
||||||
prop="actualEndTime"
|
prop="actualEndTime"
|
||||||
|
:field="item"
|
||||||
|
:fields-width="fieldsWidth"
|
||||||
|
sortable
|
||||||
:label="$t('test_track.plan.actual_end_time')"
|
:label="$t('test_track.plan.actual_end_time')"
|
||||||
show-overflow-tooltip
|
min-width="200px">
|
||||||
:key="index">
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span>{{ scope.row.actualEndTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.actualEndTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</ms-table-column>
|
||||||
|
</span>
|
||||||
|
<template v-slot:opt-before="scope">
|
||||||
|
<ms-table-operator-button :tip="$t('api_test.run')" icon="el-icon-video-play" class="run-button"
|
||||||
|
@exec="handleRun(scope.row)" v-permission="['PROJECT_TRACK_PLAN:READ+RUN']"
|
||||||
|
style="margin-right: 10px;"/>
|
||||||
|
</template>
|
||||||
|
<template v-slot:opt-behind="scope">
|
||||||
|
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!scope.row.showFollow">
|
||||||
|
<i class="el-icon-star-off"
|
||||||
|
style="color: #783987; font-size: 25px; cursor: pointer;padding-left: 5px;width: 28px;height: 28px; top: 5px; position: relative"
|
||||||
|
@click="saveFollow(scope.row)"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="scope.row.showFollow">
|
||||||
|
<i class="el-icon-star-on"
|
||||||
|
style="color: #783987; font-size: 30px; cursor: pointer;padding-left: 5px;width: 28px;height: 28px; top: 6px; position: relative"
|
||||||
|
@click="saveFollow(scope.row)"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-dropdown @command="handleCommand($event, scope.row)" class="scenario-ext-btn"
|
||||||
|
v-permission="['PROJECT_TRACK_PLAN:READ+DELETE','PROJECT_TRACK_PLAN:READ+SCHEDULE']">
|
||||||
|
<el-link type="primary" :underline="false">
|
||||||
|
<el-icon class="el-icon-more"></el-icon>
|
||||||
|
</el-link>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item command="delete" v-permission="['PROJECT_TRACK_PLAN:READ+DELETE']">
|
||||||
|
{{ $t('commons.delete') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="schedule_task" v-permission="['PROJECT_TRACK_PLAN:READ+SCHEDULE']">
|
||||||
|
{{ $t('commons.trigger_mode.schedule') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
<el-table-column
|
|
||||||
min-width="200"
|
|
||||||
:label="$t('commons.operating')">
|
|
||||||
<template slot="header">
|
|
||||||
<header-label-operate @exec="customHeader"/>
|
|
||||||
</template>
|
|
||||||
<template v-slot:default="scope">
|
|
||||||
<div>
|
|
||||||
<ms-table-operator :edit-permission="['PROJECT_TRACK_PLAN:READ+EDIT']"
|
|
||||||
:show-delete="false"
|
|
||||||
@editClick="handleEdit(scope.row)">
|
|
||||||
<template v-slot:front>
|
|
||||||
<ms-table-operator-button :tip="$t('api_test.run')" icon="el-icon-video-play" class="run-button"
|
|
||||||
@exec="handleRun(scope.row)" v-permission="['PROJECT_TRACK_PLAN:READ+RUN']"/>
|
|
||||||
</template>
|
|
||||||
<template v-slot:middle>
|
|
||||||
<ms-table-operator-button :tip="$t('commons.copy')" icon="el-icon-copy-document"
|
|
||||||
@exec="handleCopy(scope.row)" v-permission="['PROJECT_TRACK_PLAN:READ+COPY']"/>
|
|
||||||
<ms-table-operator-button v-permission="['PROJECT_TRACK_PLAN:READ+EDIT']"
|
|
||||||
:tip="$t('test_track.plan_view.view_report')" icon="el-icon-s-data"
|
|
||||||
@exec="openReport(scope.row)"/>
|
|
||||||
</template>
|
|
||||||
</ms-table-operator>
|
|
||||||
<template>
|
|
||||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!scope.row.showFollow">
|
|
||||||
<i class="el-icon-star-off" style="color: #783987; font-size: 25px; cursor: pointer;padding-left: 5px;width: 28px;height: 28px; top: 5px; position: relative" @click="saveFollow(scope.row)"></i>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="scope.row.showFollow" >
|
|
||||||
<i class="el-icon-star-on" style="color: #783987; font-size: 30px; cursor: pointer;padding-left: 5px;width: 28px;height: 28px; top: 6px; position: relative" @click="saveFollow(scope.row)"></i>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-dropdown @command="handleCommand($event, scope.row)" class="scenario-ext-btn" v-permission="['PROJECT_TRACK_PLAN:READ+DELETE','PROJECT_TRACK_PLAN:READ+SCHEDULE']">
|
|
||||||
<el-link type="primary" :underline="false">
|
|
||||||
<el-icon class="el-icon-more"></el-icon>
|
|
||||||
</el-link>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="delete" v-permission="['PROJECT_TRACK_PLAN:READ+DELETE']">
|
|
||||||
{{ $t('commons.delete') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="schedule_task" v-permission="['PROJECT_TRACK_PLAN:READ+SCHEDULE']">
|
|
||||||
{{ $t('commons.trigger_mode.schedule') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<header-custom ref="headerCustom" :initTableData="init" :optionalFields=headerItems
|
|
||||||
:type=type></header-custom>
|
|
||||||
|
|
||||||
|
|
||||||
|
</ms-table>
|
||||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||||
:total="total"/>
|
:total="total"/>
|
||||||
<ms-delete-confirm :title="$t('test_track.plan.plan_delete')" @delete="_handleDelete" ref="deleteConfirm"
|
<ms-delete-confirm :title="$t('test_track.plan.plan_delete')" @delete="_handleDelete" ref="deleteConfirm"
|
||||||
|
@ -275,7 +305,9 @@
|
||||||
{{ $t('test_track.plan.plan_delete_tip') }}
|
{{ $t('test_track.plan.plan_delete_tip') }}
|
||||||
</ms-delete-confirm>
|
</ms-delete-confirm>
|
||||||
<ms-test-plan-schedule-maintain ref="scheduleMaintain" @refreshTable="initTableData"/>
|
<ms-test-plan-schedule-maintain ref="scheduleMaintain" @refreshTable="initTableData"/>
|
||||||
<plan-run-mode-with-env @handleRunBatch="_handleRun" ref="runMode" :plan-case-ids="[]" :type="'plan'" :plan-id="currentPlanId"/>
|
<ms-test-plan-schedule-batch-switch ref="scheduleBatchSwitch" @refreshTable="initTableData"/>
|
||||||
|
<plan-run-mode-with-env @handleRunBatch="_handleRun" ref="runMode" :plan-case-ids="[]" :type="'plan'"
|
||||||
|
:plan-id="currentPlanId"/>
|
||||||
<test-plan-report-review ref="testCaseReportView"/>
|
<test-plan-report-review ref="testCaseReportView"/>
|
||||||
<ms-task-center ref="taskCenter" :show-menu="false"/>
|
<ms-task-center ref="taskCenter" :show-menu="false"/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
@ -294,13 +326,11 @@ import {TEST_PLAN_CONFIGS} from "../../../common/components/search/search-compon
|
||||||
import {
|
import {
|
||||||
_filter,
|
_filter,
|
||||||
_sort,
|
_sort,
|
||||||
deepClone,
|
deepClone, getCustomTableHeader, getCustomTableWidth,
|
||||||
getLabel,
|
|
||||||
getLastTableSortField,
|
getLastTableSortField,
|
||||||
saveLastTableSortField
|
saveLastTableSortField
|
||||||
} from "@/common/js/tableUtils";
|
} from "@/common/js/tableUtils";
|
||||||
import {TEST_PLAN_LIST} from "@/common/js/constants";
|
import {TEST_PLAN_LIST} from "@/common/js/constants";
|
||||||
import {Test_Plan_List} from "@/business/components/common/model/JsonData";
|
|
||||||
import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
||||||
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
|
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
|
||||||
import MsTag from "@/business/components/common/components/MsTag";
|
import MsTag from "@/business/components/common/components/MsTag";
|
||||||
|
@ -315,6 +345,10 @@ import PlanRunModeWithEnv from "@/business/components/track/plan/common/PlanRunM
|
||||||
import TestPlanReportReview from "@/business/components/track/report/components/TestPlanReportReview";
|
import TestPlanReportReview from "@/business/components/track/report/components/TestPlanReportReview";
|
||||||
import MsTaskCenter from "@/business/components/task/TaskCenter";
|
import MsTaskCenter from "@/business/components/task/TaskCenter";
|
||||||
import {getPlanStageOption} from "@/network/test-plan";
|
import {getPlanStageOption} from "@/network/test-plan";
|
||||||
|
import MsTableColumn from "@/business/components/common/components/table/MsTableColumn";
|
||||||
|
import MsTable from "@/business/components/common/components/table/MsTable";
|
||||||
|
import MsTestPlanScheduleBatchSwitch from "@/business/components/track/plan/components/ScheduleBatchSwitch";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TestPlanList",
|
name: "TestPlanList",
|
||||||
|
@ -329,14 +363,15 @@ export default {
|
||||||
MsTestPlanScheduleMaintain,
|
MsTestPlanScheduleMaintain,
|
||||||
MsTableOperator, MsTableOperatorButton,
|
MsTableOperator, MsTableOperatorButton,
|
||||||
MsDialogFooter, MsTableHeader,
|
MsDialogFooter, MsTableHeader,
|
||||||
MsTablePagination, PlanRunModeWithEnv, MsTaskCenter
|
MsTablePagination, PlanRunModeWithEnv, MsTaskCenter,
|
||||||
|
MsTableColumn,
|
||||||
|
MsTable,
|
||||||
|
MsTestPlanScheduleBatchSwitch
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
createUser: "",
|
createUser: "",
|
||||||
type: TEST_PLAN_LIST,
|
tableHeaderKey: "TEST_PLAN_LIST",
|
||||||
headerItems: Test_Plan_List,
|
|
||||||
tableHeaderKey:"TEST_PLAN_LIST",
|
|
||||||
tableLabel: [],
|
tableLabel: [],
|
||||||
result: {},
|
result: {},
|
||||||
cardResult: {},
|
cardResult: {},
|
||||||
|
@ -351,6 +386,8 @@ export default {
|
||||||
hasEditPermission: false,
|
hasEditPermission: false,
|
||||||
total: 0,
|
total: 0,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
|
fields: getCustomTableHeader('TEST_PLAN_LIST'),
|
||||||
|
fieldsWidth: getCustomTableWidth('TEST_PLAN_LIST'),
|
||||||
screenHeight: 'calc(100vh - 200px)',
|
screenHeight: 'calc(100vh - 200px)',
|
||||||
statusFilters: [
|
statusFilters: [
|
||||||
{text: this.$t('test_track.plan.plan_status_prepare'), value: 'Prepare'},
|
{text: this.$t('test_track.plan.plan_status_prepare'), value: 'Prepare'},
|
||||||
|
@ -363,8 +400,41 @@ export default {
|
||||||
{text: this.$t('test_track.plan.system_test'), value: 'system'},
|
{text: this.$t('test_track.plan.system_test'), value: 'system'},
|
||||||
{text: this.$t('test_track.plan.regression_test'), value: 'regression'},
|
{text: this.$t('test_track.plan.regression_test'), value: 'regression'},
|
||||||
],
|
],
|
||||||
|
scheduleFilters: [
|
||||||
|
{text: this.$t('test_track.plan.schedule_enabled'), value: 'OPEN'},
|
||||||
|
{text: this.$t('test_track.issue.status_closed'), value: 'SHUT'},
|
||||||
|
{text: this.$t('schedule.not_set'), value: 'NOTSET'}
|
||||||
|
],
|
||||||
currentPlanId: "",
|
currentPlanId: "",
|
||||||
stageOption: []
|
stageOption: [],
|
||||||
|
operators: [],
|
||||||
|
batchButtons: [],
|
||||||
|
publicButtons: [
|
||||||
|
{
|
||||||
|
name: this.$t('test_track.plan.test_plan_batch_switch'),
|
||||||
|
handleClick: this.handleBatchSwitch
|
||||||
|
}
|
||||||
|
],
|
||||||
|
simpleOperators: [
|
||||||
|
{
|
||||||
|
tip: this.$t('commons.edit'),
|
||||||
|
icon: "el-icon-edit",
|
||||||
|
exec: this.handleEdit,
|
||||||
|
permissions: ['PROJECT_TRACK_PLAN:READ+EDIT']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tip: this.$t('commons.copy'),
|
||||||
|
icon: "el-icon-copy-document",
|
||||||
|
exec: this.handleCopy,
|
||||||
|
permission: ['PROJECT_TRACK_PLAN:READ+COPY']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tip: this.$t('test_track.plan_view.view_report'),
|
||||||
|
icon: "el-icon-s-data",
|
||||||
|
exec: this.openReport,
|
||||||
|
permission: ['PROJECT_TRACK_PLAN:READ+EDIT']
|
||||||
|
},
|
||||||
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -376,6 +446,8 @@ export default {
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.projectId = this.$route.params.projectId;
|
this.projectId = this.$route.params.projectId;
|
||||||
|
this.batchButtons = this.publicButtons;
|
||||||
|
this.operators = this.simpleOperators;
|
||||||
if (!this.projectId) {
|
if (!this.projectId) {
|
||||||
this.projectId = getCurrentProjectID();
|
this.projectId = getCurrentProjectID();
|
||||||
}
|
}
|
||||||
|
@ -455,7 +527,7 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
follow = follow + d.name;
|
follow = follow + d.name;
|
||||||
}
|
}
|
||||||
if(this.currentUser().id===d.id){
|
if (this.currentUser().id === d.id) {
|
||||||
showFollow = true;
|
showFollow = true;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -467,8 +539,6 @@ export default {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
getLabel(this, TEST_PLAN_LIST);
|
|
||||||
|
|
||||||
},
|
},
|
||||||
copyData(status) {
|
copyData(status) {
|
||||||
return JSON.parse(JSON.stringify(this.dataMap.get(status)));
|
return JSON.parse(JSON.stringify(this.dataMap.get(status)));
|
||||||
|
@ -486,6 +556,18 @@ export default {
|
||||||
handleEdit(testPlan) {
|
handleEdit(testPlan) {
|
||||||
this.$emit('testPlanEdit', testPlan);
|
this.$emit('testPlanEdit', testPlan);
|
||||||
},
|
},
|
||||||
|
handleBatchSwitch() {
|
||||||
|
let param = [];
|
||||||
|
let size = 0;
|
||||||
|
let row = this.$refs.testPlanLitTable.selectRows.size;
|
||||||
|
this.$refs.testPlanLitTable.selectRows.forEach((item) => {
|
||||||
|
if (item.scheduleStatus != null && item.scheduleStatus != 'NOTSET') {
|
||||||
|
param.push(item.scheduleId);
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.$refs.scheduleBatchSwitch.open(param, size);
|
||||||
|
},
|
||||||
statusChange(data) {
|
statusChange(data) {
|
||||||
if (!hasPermission('PROJECT_TRACK_PLAN:READ+EDIT')) {
|
if (!hasPermission('PROJECT_TRACK_PLAN:READ+EDIT')) {
|
||||||
return;
|
return;
|
||||||
|
@ -514,6 +596,26 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
scheduleChange(row) {
|
||||||
|
let param = {};
|
||||||
|
let message = this.$t('api_test.home_page.running_task_list.confirm.close_title');
|
||||||
|
param.taskID = row.scheduleId;
|
||||||
|
param.enable = row.scheduleOpen;
|
||||||
|
if (row.scheduleOpen) {
|
||||||
|
message = this.$t('api_test.home_page.running_task_list.confirm.open_title');
|
||||||
|
}
|
||||||
|
this.$confirm(message, this.$t('commons.prompt'), {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
cancelButtonText: this.$t('commons.cancel'),
|
||||||
|
type: 'warning',
|
||||||
|
}).then(() => {
|
||||||
|
this.result = this.$post('/test/plan/schedule/updateEnableByPrimyKey', param, response => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
});
|
||||||
|
}).catch(() => {
|
||||||
|
row.scheduleOpen = param.enable = !param.enable;
|
||||||
|
});
|
||||||
|
},
|
||||||
handleDelete(testPlan) {
|
handleDelete(testPlan) {
|
||||||
this.enableDeleteTip = testPlan.status === 'Underway' ? true : false;
|
this.enableDeleteTip = testPlan.status === 'Underway' ? true : false;
|
||||||
this.$refs.deleteConfirm.open(testPlan);
|
this.$refs.deleteConfirm.open(testPlan);
|
||||||
|
@ -525,6 +627,10 @@ export default {
|
||||||
this.$success(this.$t('commons.delete_success'));
|
this.$success(this.$t('commons.delete_success'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
refresh() {
|
||||||
|
this.$refs.table.clear();
|
||||||
|
this.$emit('refresh');
|
||||||
|
},
|
||||||
intoPlan(row, column, event) {
|
intoPlan(row, column, event) {
|
||||||
if (column.label !== this.$t('commons.operating')) {
|
if (column.label !== this.$t('commons.operating')) {
|
||||||
this.$router.push('/track/plan/view/' + row.id);
|
this.$router.push('/track/plan/view/' + row.id);
|
||||||
|
@ -540,7 +646,7 @@ export default {
|
||||||
this.condition.orders = [];
|
this.condition.orders = [];
|
||||||
}
|
}
|
||||||
_sort(column, this.condition);
|
_sort(column, this.condition);
|
||||||
this.saveSortField(this.tableHeaderKey,this.condition.orders);
|
this.saveSortField(this.tableHeaderKey, this.condition.orders);
|
||||||
this.initTableData();
|
this.initTableData();
|
||||||
},
|
},
|
||||||
openReport(plan) {
|
openReport(plan) {
|
||||||
|
@ -550,8 +656,8 @@ export default {
|
||||||
row.redirectFrom = "testPlan";
|
row.redirectFrom = "testPlan";
|
||||||
this.$refs.scheduleMaintain.open(row);
|
this.$refs.scheduleMaintain.open(row);
|
||||||
},
|
},
|
||||||
saveSortField(key,orders){
|
saveSortField(key, orders) {
|
||||||
saveLastTableSortField(key,JSON.stringify(orders));
|
saveLastTableSortField(key, JSON.stringify(orders));
|
||||||
},
|
},
|
||||||
handleCommand(cmd, row) {
|
handleCommand(cmd, row) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
@ -565,7 +671,7 @@ export default {
|
||||||
},
|
},
|
||||||
handleCopy(row) {
|
handleCopy(row) {
|
||||||
this.cardResult.loading = true;
|
this.cardResult.loading = true;
|
||||||
this.$post('test/plan/copy/' + row.id, {},() => {
|
this.$post('test/plan/copy/' + row.id, {}, () => {
|
||||||
this.initTableData();
|
this.initTableData();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -581,7 +687,16 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
_handleRun(config) {
|
_handleRun(config) {
|
||||||
let {mode, reportType, onSampleError, runWithinResourcePool, resourcePoolId, envMap, environmentType, environmentGroupId} = config;
|
let {
|
||||||
|
mode,
|
||||||
|
reportType,
|
||||||
|
onSampleError,
|
||||||
|
runWithinResourcePool,
|
||||||
|
resourcePoolId,
|
||||||
|
envMap,
|
||||||
|
environmentType,
|
||||||
|
environmentGroupId
|
||||||
|
} = config;
|
||||||
let param = {mode, reportType, onSampleError, runWithinResourcePool, resourcePoolId, envMap};
|
let param = {mode, reportType, onSampleError, runWithinResourcePool, resourcePoolId, envMap};
|
||||||
param.testPlanId = this.currentPlanId;
|
param.testPlanId = this.currentPlanId;
|
||||||
param.projectId = getCurrentProjectID();
|
param.projectId = getCurrentProjectID();
|
||||||
|
@ -591,33 +706,33 @@ export default {
|
||||||
param.environmentGroupId = environmentGroupId;
|
param.environmentGroupId = environmentGroupId;
|
||||||
param.requestOriginator = "TEST_PLAN";
|
param.requestOriginator = "TEST_PLAN";
|
||||||
this.$refs.taskCenter.open();
|
this.$refs.taskCenter.open();
|
||||||
this.result = this.$post('test/plan/run/', param,() => {
|
this.result = this.$post('test/plan/run/', param, () => {
|
||||||
this.$success(this.$t('commons.run_success'));
|
this.$success(this.$t('commons.run_success'));
|
||||||
}, error => {
|
}, error => {
|
||||||
// this.$error(error.message);
|
// this.$error(error.message);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveFollow(row){
|
saveFollow(row) {
|
||||||
if(row.showFollow){
|
if (row.showFollow) {
|
||||||
row.showFollow = false;
|
row.showFollow = false;
|
||||||
for (let i = 0; i < row.follows.length; i++) {
|
for (let i = 0; i < row.follows.length; i++) {
|
||||||
if(row.follows[i]===this.currentUser().id){
|
if (row.follows[i] === this.currentUser().id) {
|
||||||
row.follows.splice(i,1)
|
row.follows.splice(i, 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$post('/test/plan/edit/follows/' + row.id, row.follows,() => {
|
this.$post('/test/plan/edit/follows/' + row.id, row.follows, () => {
|
||||||
this.$success(this.$t('commons.cancel_follow_success'));
|
this.$success(this.$t('commons.cancel_follow_success'));
|
||||||
});
|
});
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(!row.showFollow){
|
if (!row.showFollow) {
|
||||||
row.showFollow = true;
|
row.showFollow = true;
|
||||||
if(!row.follows){
|
if (!row.follows) {
|
||||||
row.follows = [];
|
row.follows = [];
|
||||||
}
|
}
|
||||||
row.follows.push(this.currentUser().id);
|
row.follows.push(this.currentUser().id);
|
||||||
this.$post('/test/plan/edit/follows/' + row.id, row.follows,() => {
|
this.$post('/test/plan/edit/follows/' + row.id, row.follows, () => {
|
||||||
this.$success(this.$t('commons.follow_success'));
|
this.$success(this.$t('commons.follow_success'));
|
||||||
});
|
});
|
||||||
return
|
return
|
||||||
|
@ -642,7 +757,7 @@ export default {
|
||||||
|
|
||||||
.schedule-btn >>> .el-button {
|
.schedule-btn >>> .el-button {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
color:#85888E;
|
color: #85888E;
|
||||||
border-color: #85888E;
|
border-color: #85888E;
|
||||||
border-width: thin;
|
border-width: thin;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,8 +118,9 @@ export let CUSTOM_TABLE_HEADER = {
|
||||||
{id: 'plannedStartTime', key: '7', label: 'test_track.plan.planned_start_time'},
|
{id: 'plannedStartTime', key: '7', label: 'test_track.plan.planned_start_time'},
|
||||||
{id: 'plannedEndTime', key: '8', label: 'test_track.plan.planned_end_time'},
|
{id: 'plannedEndTime', key: '8', label: 'test_track.plan.planned_end_time'},
|
||||||
{id: 'actualStartTime', key: '9', label: 'test_track.plan.actual_start_time'},
|
{id: 'actualStartTime', key: '9', label: 'test_track.plan.actual_start_time'},
|
||||||
{id: 'actualEndTime', key: 'a', label: 'test_track.plan.actual_end_time'},
|
{id: 'actualEndTime', key: '10', label: 'test_track.plan.actual_end_time'},
|
||||||
{id: 'tags', key: 'b', label: 'commons.tag'},
|
{id: 'tags', key: 'a', label: 'commons.tag'},
|
||||||
|
{id: 'scheduleStatus', key: 'b', label: 'commons.trigger_mode.schedule'},
|
||||||
{id: 'executionTimes', key: 'c', label: 'commons.execution_times'},
|
{id: 'executionTimes', key: 'c', label: 'commons.execution_times'},
|
||||||
{id: 'passRate', key: 'd', label: 'commons.pass_rate'},
|
{id: 'passRate', key: 'd', label: 'commons.pass_rate'},
|
||||||
{id: 'createUser', key: 'e', label: 'commons.create_user'},
|
{id: 'createUser', key: 'e', label: 'commons.create_user'},
|
||||||
|
|
|
@ -1823,6 +1823,7 @@ export default {
|
||||||
swagger_schedule: "swagger",
|
swagger_schedule: "swagger",
|
||||||
confirm: {
|
confirm: {
|
||||||
close_title: "Do you want to close this scheduled task?",
|
close_title: "Do you want to close this scheduled task?",
|
||||||
|
open_title: "Do you want to start this scheduled task??",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2109,6 +2110,11 @@ export default {
|
||||||
test_plan_load_case_count: "Load case count",
|
test_plan_load_case_count: "Load case count",
|
||||||
test_plan_component_case_count: "Component Case Count",
|
test_plan_component_case_count: "Component Case Count",
|
||||||
data_name: "Data Name",
|
data_name: "Data Name",
|
||||||
|
test_plan_batch_switch: "batch on/off scheduled tasks",
|
||||||
|
batch_update_schedule_enable: 'update the scheduled task status of {0} test plans',
|
||||||
|
batch_update_schedule_enable_alert: 'note: only test plans with scheduled tasks can be updated',
|
||||||
|
next_run_time: 'next running time',
|
||||||
|
schedule_enabled: 'enabled',
|
||||||
load_case: {
|
load_case: {
|
||||||
case: "Load Case",
|
case: "Load Case",
|
||||||
execution_status: "Execution status",
|
execution_status: "Execution status",
|
||||||
|
|
|
@ -1828,6 +1828,7 @@ export default {
|
||||||
swagger_schedule: "swagger",
|
swagger_schedule: "swagger",
|
||||||
confirm: {
|
confirm: {
|
||||||
close_title: "要关闭这条定时任务吗?",
|
close_title: "要关闭这条定时任务吗?",
|
||||||
|
open_title: "要开启这条定时任务吗?",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2109,6 +2110,11 @@ export default {
|
||||||
test_plan_load_case_count: "性能用例数",
|
test_plan_load_case_count: "性能用例数",
|
||||||
test_plan_component_case_count: "步骤用例数",
|
test_plan_component_case_count: "步骤用例数",
|
||||||
data_name: "数据名称",
|
data_name: "数据名称",
|
||||||
|
test_plan_batch_switch: "批量开/关定时任务",
|
||||||
|
batch_update_schedule_enable: '更新{0}个测试计划的定时任务状态为',
|
||||||
|
batch_update_schedule_enable_alert: '注意:只能更新已设置了定时任务的测试计划',
|
||||||
|
next_run_time: '下次运行时间',
|
||||||
|
schedule_enabled: '已开启',
|
||||||
load_case: {
|
load_case: {
|
||||||
case: "性能用例",
|
case: "性能用例",
|
||||||
execution_status: "执行状态",
|
execution_status: "执行状态",
|
||||||
|
|
|
@ -1828,6 +1828,7 @@ export default {
|
||||||
swagger_schedule: "swagger",
|
swagger_schedule: "swagger",
|
||||||
confirm: {
|
confirm: {
|
||||||
close_title: "要關閉這條定時任務嗎?",
|
close_title: "要關閉這條定時任務嗎?",
|
||||||
|
open_title: "要開啟這條定時任務嗎?",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2108,6 +2109,11 @@ export default {
|
||||||
test_plan_load_case_count: "性能用例數",
|
test_plan_load_case_count: "性能用例數",
|
||||||
test_plan_component_case_count: "步驟用例數",
|
test_plan_component_case_count: "步驟用例數",
|
||||||
data_name: "數據名稱",
|
data_name: "數據名稱",
|
||||||
|
test_plan_batch_switch: "批量開/關定時任務",
|
||||||
|
batch_update_schedule_enable: '更新{0}個測試計畫的定時任務狀態為',
|
||||||
|
batch_update_schedule_enable_alert: '注意:只能更新已設定了定時任務的測試計畫',
|
||||||
|
next_run_time: '下次運行時間',
|
||||||
|
schedule_enabled: '已開啟',
|
||||||
load_case: {
|
load_case: {
|
||||||
case: "性能用例",
|
case: "性能用例",
|
||||||
execution_status: "執行狀態",
|
execution_status: "執行狀態",
|
||||||
|
|
Loading…
Reference in New Issue