feat(接口自动化): 完成场景添加到测试计划几查看引用功能

This commit is contained in:
fit2-zhao 2020-12-09 17:26:52 +08:00
parent c0c37a7aa1
commit c021bb5647
19 changed files with 653 additions and 63 deletions

View File

@ -2,10 +2,7 @@ package io.metersphere.api.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.ApiScenarioRequest;
import io.metersphere.api.dto.automation.RunScenarioRequest;
import io.metersphere.api.dto.automation.SaveApiScenarioRequest;
import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.base.domain.ApiScenario;
@ -82,9 +79,14 @@ public class ApiAutomationController {
}
@PostMapping("/getReference")
public List<ApiScenario> getReference(@RequestBody ApiScenarioRequest request) {
public ReferenceDTO getReference(@RequestBody ApiScenarioRequest request) {
return apiAutomationService.getReference(request);
}
@PostMapping("/scenario/plan")
public String addScenarioToPlan(@RequestBody SaveApiPlanRequest request) {
return apiAutomationService.addScenarioToPlan(request);
}
}

View File

@ -62,7 +62,6 @@ public class ApiDefinitionController {
apiDefinitionService.removeToGc(ids);
}
@GetMapping("/get/{id}")
public ApiDefinition get(@PathVariable String id) {
return apiDefinitionService.get(id);

View File

@ -0,0 +1,16 @@
package io.metersphere.api.dto.automation;
import io.metersphere.base.domain.ApiScenario;
import io.metersphere.track.dto.TestPlanDTO;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class ReferenceDTO {
List<ApiScenario> scenarioList;
List<TestPlanDTO> testPlanList;
}

View File

@ -0,0 +1,14 @@
package io.metersphere.api.dto.automation;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class SaveApiPlanRequest {
private List<String> planIds;
private List<String> apiIds;
private List<String> scenarioIds;
}

View File

@ -17,6 +17,7 @@ import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ApiTagMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTriggerMode;
@ -24,8 +25,13 @@ import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.i18n.Translator;
import io.metersphere.track.dto.TestPlanDTO;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.ListedHashTree;
import org.aspectj.util.FileUtil;
@ -35,11 +41,9 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
@Transactional(rollbackFor = Exception.class)
@ -56,6 +60,10 @@ public class ApiAutomationService {
private ApiTestEnvironmentService environmentService;
@Resource
private ApiScenarioReportService apiReportService;
@Resource
private ExtTestPlanMapper extTestPlanMapper;
@Resource
SqlSessionFactory sqlSessionFactory;
private static final String BODY_FILE_DIR = "/opt/metersphere/data/body";
@ -306,7 +314,54 @@ public class ApiAutomationService {
return request.getId();
}
public List<ApiScenario> getReference(ApiScenarioRequest request) {
return extApiScenarioMapper.selectReference(request);
public ReferenceDTO getReference(ApiScenarioRequest request) {
ReferenceDTO dto = new ReferenceDTO();
dto.setScenarioList(extApiScenarioMapper.selectReference(request));
QueryTestPlanRequest planRequest = new QueryTestPlanRequest();
planRequest.setScenarioId(request.getId());
planRequest.setProjectId(request.getProjectId());
dto.setTestPlanList(extTestPlanMapper.selectReference(planRequest));
return dto;
}
public String addScenarioToPlan(SaveApiPlanRequest request) {
if (CollectionUtils.isEmpty(request.getPlanIds())) {
MSException.throwException(Translator.get("plan id is null "));
}
List<TestPlanDTO> list = extTestPlanMapper.selectByIds(request.getPlanIds());
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ExtTestPlanMapper mapper = sqlSession.getMapper(ExtTestPlanMapper.class);
list.forEach(item -> {
if (CollectionUtils.isNotEmpty(request.getApiIds())) {
if (CollectionUtils.isNotEmpty(request.getApiIds())) {
if (StringUtils.isEmpty(item.getApiIds())) {
item.setApiIds(JSON.toJSONString(request.getApiIds()));
} else {
// 合并api
List<String> dbApiIDs = JSON.parseArray(item.getApiIds(), String.class);
List<String> result = Stream.of(request.getApiIds(), dbApiIDs)
.flatMap(Collection::stream).distinct().collect(Collectors.toList());
item.setApiIds(JSON.toJSONString(result));
}
}
}
if (CollectionUtils.isNotEmpty(request.getScenarioIds())) {
if (CollectionUtils.isNotEmpty(request.getScenarioIds())) {
if (StringUtils.isEmpty(item.getScenarioIds())) {
item.setScenarioIds(JSON.toJSONString(request.getScenarioIds()));
} else {
// 合并场景ID
List<String> dbScenarioIDs = JSON.parseArray(item.getScenarioIds(), String.class);
List<String> result = Stream.of(request.getScenarioIds(), dbScenarioIDs)
.flatMap(Collection::stream).distinct().collect(Collectors.toList());
item.setScenarioIds(JSON.toJSONString(result));
}
}
}
mapper.updatePlan(item);
});
sqlSession.flushStatements();
return "success";
}
}

View File

@ -1,8 +1,9 @@
package io.metersphere.base.domain;
import java.io.Serializable;
import lombok.Data;
import java.io.Serializable;
@Data
public class TestPlan implements Serializable {
private String id;
@ -39,6 +40,10 @@ public class TestPlan implements Serializable {
private String creator;
private String apiIds;
private String scenarioIds;
private String tags;
private static final long serialVersionUID = 1L;

View File

@ -1233,6 +1233,146 @@ public class TestPlanExample {
addCriterion("creator not between", value1, value2, "creator");
return (Criteria) this;
}
public Criteria andApiIdsIsNull() {
addCriterion("api_ids is null");
return (Criteria) this;
}
public Criteria andApiIdsIsNotNull() {
addCriterion("api_ids is not null");
return (Criteria) this;
}
public Criteria andApiIdsEqualTo(String value) {
addCriterion("api_ids =", value, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsNotEqualTo(String value) {
addCriterion("api_ids <>", value, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsGreaterThan(String value) {
addCriterion("api_ids >", value, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsGreaterThanOrEqualTo(String value) {
addCriterion("api_ids >=", value, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsLessThan(String value) {
addCriterion("api_ids <", value, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsLessThanOrEqualTo(String value) {
addCriterion("api_ids <=", value, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsLike(String value) {
addCriterion("api_ids like", value, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsNotLike(String value) {
addCriterion("api_ids not like", value, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsIn(List<String> values) {
addCriterion("api_ids in", values, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsNotIn(List<String> values) {
addCriterion("api_ids not in", values, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsBetween(String value1, String value2) {
addCriterion("api_ids between", value1, value2, "apiIds");
return (Criteria) this;
}
public Criteria andApiIdsNotBetween(String value1, String value2) {
addCriterion("api_ids not between", value1, value2, "apiIds");
return (Criteria) this;
}
public Criteria andScenarioIdsIsNull() {
addCriterion("scenario_ids is null");
return (Criteria) this;
}
public Criteria andScenarioIdsIsNotNull() {
addCriterion("scenario_ids is not null");
return (Criteria) this;
}
public Criteria andScenarioIdsEqualTo(String value) {
addCriterion("scenario_ids =", value, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsNotEqualTo(String value) {
addCriterion("scenario_ids <>", value, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsGreaterThan(String value) {
addCriterion("scenario_ids >", value, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsGreaterThanOrEqualTo(String value) {
addCriterion("scenario_ids >=", value, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsLessThan(String value) {
addCriterion("scenario_ids <", value, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsLessThanOrEqualTo(String value) {
addCriterion("scenario_ids <=", value, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsLike(String value) {
addCriterion("scenario_ids like", value, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsNotLike(String value) {
addCriterion("scenario_ids not like", value, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsIn(List<String> values) {
addCriterion("scenario_ids in", values, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsNotIn(List<String> values) {
addCriterion("scenario_ids not in", values, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsBetween(String value1, String value2) {
addCriterion("scenario_ids between", value1, value2, "scenarioIds");
return (Criteria) this;
}
public Criteria andScenarioIdsNotBetween(String value1, String value2) {
addCriterion("scenario_ids not between", value1, value2, "scenarioIds");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -19,6 +19,8 @@
<result column="planned_end_time" jdbcType="BIGINT" property="plannedEndTime" />
<result column="actual_start_time" jdbcType="BIGINT" property="actualStartTime" />
<result column="creator" jdbcType="VARCHAR" property="creator" />
<result column="api_ids" jdbcType="VARCHAR" property="apiIds" />
<result column="scenario_ids" jdbcType="VARCHAR" property="scenarioIds" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.TestPlan">
<result column="tags" jdbcType="LONGVARCHAR" property="tags" />
@ -84,7 +86,7 @@
<sql id="Base_Column_List">
id, workspace_id, report_id, `name`, description, `status`, stage, principal, test_case_match_rule,
executor_match_rule, create_time, update_time, actual_end_time, planned_start_time,
planned_end_time, actual_start_time, creator
planned_end_time, actual_start_time, creator, api_ids, scenario_ids
</sql>
<sql id="Blob_Column_List">
tags
@ -143,15 +145,15 @@
stage, principal, test_case_match_rule,
executor_match_rule, create_time, update_time,
actual_end_time, planned_start_time, planned_end_time,
actual_start_time, creator, tags
)
actual_start_time, creator, api_ids,
scenario_ids, tags)
values (#{id,jdbcType=VARCHAR}, #{workspaceId,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
#{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
#{stage,jdbcType=VARCHAR}, #{principal,jdbcType=VARCHAR}, #{testCaseMatchRule,jdbcType=VARCHAR},
#{executorMatchRule,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{actualEndTime,jdbcType=BIGINT}, #{plannedStartTime,jdbcType=BIGINT}, #{plannedEndTime,jdbcType=BIGINT},
#{actualStartTime,jdbcType=BIGINT}, #{creator,jdbcType=VARCHAR}, #{tags,jdbcType=LONGVARCHAR}
)
#{actualStartTime,jdbcType=BIGINT}, #{creator,jdbcType=VARCHAR}, #{apiIds,jdbcType=VARCHAR},
#{scenarioIds,jdbcType=VARCHAR}, #{tags,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlan">
insert into test_plan
@ -207,6 +209,12 @@
<if test="creator != null">
creator,
</if>
<if test="apiIds != null">
api_ids,
</if>
<if test="scenarioIds != null">
scenario_ids,
</if>
<if test="tags != null">
tags,
</if>
@ -263,6 +271,12 @@
<if test="creator != null">
#{creator,jdbcType=VARCHAR},
</if>
<if test="apiIds != null">
#{apiIds,jdbcType=VARCHAR},
</if>
<if test="scenarioIds != null">
#{scenarioIds,jdbcType=VARCHAR},
</if>
<if test="tags != null">
#{tags,jdbcType=LONGVARCHAR},
</if>
@ -328,6 +342,12 @@
<if test="record.creator != null">
creator = #{record.creator,jdbcType=VARCHAR},
</if>
<if test="record.apiIds != null">
api_ids = #{record.apiIds,jdbcType=VARCHAR},
</if>
<if test="record.scenarioIds != null">
scenario_ids = #{record.scenarioIds,jdbcType=VARCHAR},
</if>
<if test="record.tags != null">
tags = #{record.tags,jdbcType=LONGVARCHAR},
</if>
@ -355,6 +375,8 @@
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
creator = #{record.creator,jdbcType=VARCHAR},
api_ids = #{record.apiIds,jdbcType=VARCHAR},
scenario_ids = #{record.scenarioIds,jdbcType=VARCHAR},
tags = #{record.tags,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -378,7 +400,9 @@
planned_start_time = #{record.plannedStartTime,jdbcType=BIGINT},
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
creator = #{record.creator,jdbcType=VARCHAR}
creator = #{record.creator,jdbcType=VARCHAR},
api_ids = #{record.apiIds,jdbcType=VARCHAR},
scenario_ids = #{record.scenarioIds,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -434,6 +458,12 @@
<if test="creator != null">
creator = #{creator,jdbcType=VARCHAR},
</if>
<if test="apiIds != null">
api_ids = #{apiIds,jdbcType=VARCHAR},
</if>
<if test="scenarioIds != null">
scenario_ids = #{scenarioIds,jdbcType=VARCHAR},
</if>
<if test="tags != null">
tags = #{tags,jdbcType=LONGVARCHAR},
</if>
@ -458,6 +488,8 @@
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
creator = #{creator,jdbcType=VARCHAR},
api_ids = #{apiIds,jdbcType=VARCHAR},
scenario_ids = #{scenarioIds,jdbcType=VARCHAR},
tags = #{tags,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
@ -478,7 +510,9 @@
planned_start_time = #{plannedStartTime,jdbcType=BIGINT},
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
creator = #{creator,jdbcType=VARCHAR}
creator = #{creator,jdbcType=VARCHAR},
api_ids = #{apiIds,jdbcType=VARCHAR},
scenario_ids = #{scenarioIds,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -1,8 +1,8 @@
package io.metersphere.base.mapper.ext;
import io.metersphere.track.dto.TestPlanDTO;
import io.metersphere.track.dto.TestPlanDTOWithMetric;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.dto.TestPlanDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -13,4 +13,11 @@ public interface ExtTestPlanMapper {
List<TestPlanDTOWithMetric> listRelate(@Param("request") QueryTestPlanRequest params);
List<TestPlanDTO> planList(@Param("request") QueryTestPlanRequest params);
List<TestPlanDTO> selectByIds(@Param("list") List<String> ids);
int updatePlan(@Param("plan") TestPlanDTO plan);
List<TestPlanDTO> selectReference(@Param("request") QueryTestPlanRequest params);
}

View File

@ -172,4 +172,38 @@
)
order by test_plan.update_time desc
</select>
<update id="updatePlan" parameterType="io.metersphere.track.dto.TestPlanDTO">
update test_plan
<set>
<if test="plan.apiIds != null">
api_ids = #{plan.apiIds,jdbcType=VARCHAR}
</if>
<if test="plan.scenarioIds != null">
scenario_ids = #{plan.scenarioIds,jdbcType=VARCHAR}
</if>
</set>
<where>
id = #{plan.id}
</where>
</update>
<select id="selectByIds" resultMap="BaseResultMap" parameterType="java.util.List">
SELECT * FROM TEST_PLAN p where p.id in
<foreach collection="list" item="planId" open="(" close=")" separator=",">
#{planId}
</foreach>
</select>
<select id="selectReference" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
SELECT * FROM TEST_PLAN p LEFT JOIN test_plan_project t ON t.test_plan_id=p.id
<where>
<if test="request.scenarioId != null">
AND p.scenario_ids like CONCAT('%', #{request.scenarioId},'%')
</if>
<if test="request.apiId != null">
AND p.api_ids like CONCAT('%', #{request.apiId},'%')
</if>
</where>
</select>
</mapper>

View File

@ -16,6 +16,10 @@ public class QueryTestPlanRequest extends TestPlan {
private List<String> planIds;
private String scenarioId;
private String apiId;
private List<OrderRequest> orders;
private Map<String, List<String>> filters;

View File

@ -62,6 +62,10 @@
<el-drawer :visible.sync="runVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('test_track.plan_view.test_result')" :modal="false" size="90%">
<ms-api-report-detail @refresh="search" :infoDb="infoDb" :report-id="reportId" :currentProjectId="currentProject!=undefined ? currentProject.id:''"/>
</el-drawer>
<!--测试计划-->
<el-drawer :visible.sync="planVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('test_track.plan_view.test_result')" :modal="false" size="90%">
<ms-test-plan-list @addTestPlan="addTestPlan"/>
</el-drawer>
</div>
</el-card>
@ -77,11 +81,11 @@
import MsApiReportDetail from "../report/ApiReportDetail";
import MsTableMoreBtn from "./TableMoreBtn";
import MsScenarioExtendButtons from "@/business/components/api/automation/scenario/ScenarioExtendBtns";
import MsTestPlanList from "./testplan/TestPlanList";
export default {
name: "MsApiScenarioList",
components: {MsTablePagination, MsTableMoreBtn, ShowMoreBtn, MsTableHeader, MsTag, MsApiReportDetail, MsScenarioExtendButtons},
components: {MsTablePagination, MsTableMoreBtn, ShowMoreBtn, MsTableHeader, MsTag, MsApiReportDetail, MsScenarioExtendButtons, MsTestPlanList},
props: {
currentProject: Object,
currentModule: Object,
@ -105,6 +109,7 @@
reportId: "",
infoDb: false,
runVisible: false,
planVisible: false,
runData: [],
buttons: [
{
@ -162,7 +167,14 @@
}
},
handleBatchAddCase() {
this.planVisible = true;
},
addTestPlan(plans) {
let obj = {planIds: plans, scenarioIds: this.selection};
this.planVisible = false;
this.$post("/api/automation/scenario/plan", obj, response => {
this.$success(this.$t("commons.save_success"));
});
},
handleBatchExecute() {
this.infoDb = false;
@ -213,42 +225,6 @@
this.infoDb = true;
this.reportId = row.reportId;
},
handleQuote() {
},
handleSchedule(row) {
this.currentScenario = row;
if (row.schedule) {
if (Object.prototype.toString.call(row.schedule).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
this.schedule = row.schedule;
} else {
this.schedule = JSON.parse(row.schedule);
}
}
this.$refs.scheduleEdit.open();
},
saveCronExpression(cronExpression) {
this.schedule.enable = true;
this.schedule.value = cronExpression;
this.saveSchedule();
},
saveSchedule() {
this.checkScheduleEdit();
let param = {};
param = this.schedule;
param.resourceId = this.currentScenario.id;
let url = '/api/automation/schedule/create';
if (param.id) {
url = '/api/automation/schedule/update';
}
this.$post(url, param, () => {
this.$success(this.$t('commons.save_success'));
this.search();
});
},
checkScheduleEdit() {
return true;
},
remove(row) {
if (this.currentModule !== undefined && this.currentModule != null && this.currentModule.id === "gc") {
this.$get('/api/automation/delete/' + row.id, () => {

View File

@ -93,7 +93,6 @@
testPlan.hashTree.push(threadGroup);
let reqObj = {id: this.reportId, reportId: this.reportId, environmentId: this.environment, testElement: testPlan};
let bodyFiles = this.getBodyUploadFiles(reqObj);
console.log(bodyFiles)
let url = "/api/automation/run/debug";
this.$fileUpload(url, null, bodyFiles, reqObj, response => {
this.runId = response.data;

View File

@ -57,7 +57,6 @@
importApiScenario() {
let scenarios = [];
if (this.currentScenario) {
console.log(this.currentScenario)
this.currentScenario.forEach(item => {
let obj = {id: item.id, name: item.name, type: "scenario", referenced: 'REF', resourceId: getUUID()};
scenarios.push(obj);

View File

@ -39,7 +39,8 @@ export default {
this.scenarioLoading = true;
this.scenarioRefs = [];
this.$post("/api/automation/getReference/", row, response => {
this.scenarioRefs = response.data;
this.scenarioRefs = response.data.scenarioList;
this.planRefs = response.data.testPlanList;
this.scenarioLoading = false;
})
},

View File

@ -0,0 +1,302 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<ms-table-header :is-tester-permission="true" :condition.sync="condition"
@search="initTableData" :showCreate="false"
:title="$t('test_track.plan.test_plan')"/>
</template>
<el-table
border
class="adjust-table"
:data="tableData"
@filter-change="filter"
@sort-change="sort"
@select-all="select"
@select="select">
<el-table-column type="selection"/>
<el-table-column
prop="name"
:label="$t('commons.name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="userName"
:label="$t('test_track.plan.plan_principal')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="status"
column-key="status"
:filters="statusFilters"
:label="$t('test_track.plan.plan_status')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span @click.stop="clickt = 'stop'">
<el-dropdown class="test-case-status" @command="statusChange">
<span class="el-dropdown-link">
<plan-status-table-item :value="scope.row.status"/>
</span>
<el-dropdown-menu slot="dropdown" chang>
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Prepare'}">
{{ $t('test_track.plan.plan_status_prepare') }}
</el-dropdown-item>
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
:command="{id: scope.row.id, status: 'Underway'}">
{{ $t('test_track.plan.plan_status_running') }}
</el-dropdown-item>
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
:command="{id: scope.row.id, status: 'Completed'}">
{{ $t('test_track.plan.plan_status_completed') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</template>
</el-table-column>
<el-table-column
prop="stage"
column-key="stage"
:filters="stageFilters"
:label="$t('test_track.plan.plan_stage')"
show-overflow-tooltip>
<template v-slot:default="scope">
<plan-stage-table-item :stage="scope.row.stage"/>
</template>
</el-table-column>
<el-table-column
prop="projectName"
:label="$t('test_track.home.test_rate')"
min-width="100"
show-overflow-tooltip>
<template v-slot:default="scope">
<el-progress :percentage="scope.row.testRate"></el-progress>
</template>
</el-table-column>
<el-table-column
prop="projectName"
:label="$t('test_track.plan.plan_project')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
sortable
prop="plannedStartTime"
:label="$t('test_track.plan.planned_start_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.plannedStartTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
sortable
prop="plannedEndTime"
:label="$t('test_track.plan.planned_end_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.plannedEndTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
sortable
prop="actualStartTime"
:label="$t('test_track.plan.actual_start_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.actualStartTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
sortable
prop="actualEndTime"
:label="$t('test_track.plan.actual_end_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.actualEndTime | timestampFormatDate }}</span>
</template>
</el-table-column>
</el-table>
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
<test-report-template-list @openReport="openReport" ref="testReportTemplateList"/>
<test-case-report-view @refresh="initTableData" ref="testCaseReportView"/>
<ms-delete-confirm :title="$t('test_track.plan.plan_delete')" @delete="_handleDelete" ref="deleteConfirm" :with-tip="enableDeleteTip">
{{$t('test_track.plan.plan_delete_tip')}}
</ms-delete-confirm>
<ms-dialog-footer style="float: right;margin: 20px"
@confirm="confirm">
</ms-dialog-footer>
</el-card>
</template>
<script>
import MsCreateBox from '../../../../settings/CreateBox';
import MsTablePagination from '../../../../../components/common/pagination/TablePagination';
import MsTableHeader from "../../../../common/components/MsTableHeader";
import MsDialogFooter from "../../../../common/components/MsDialogFooter";
import MsTableOperatorButton from "../../../../common/components/MsTableOperatorButton";
import MsTableOperator from "../../../../common/components/MsTableOperator";
import PlanStatusTableItem from "../../../../track/common/tableItems/plan/PlanStatusTableItem";
import PlanStageTableItem from "../../../../track/common/tableItems/plan/PlanStageTableItem";
import {_filter, _sort, checkoutTestManagerOrTestUser} from "@/common/js/utils";
import TestReportTemplateList from "../../../../track/plan/view/comonents/TestReportTemplateList";
import TestCaseReportView from "../../../../track/plan/view/comonents/report/TestCaseReportView";
import MsDeleteConfirm from "../../../../common/components/MsDeleteConfirm";
import {TEST_PLAN_CONFIGS} from "../../../../common/components/search/search-components";
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
export default {
name: "TestPlanList",
components: {
MsDeleteConfirm,
TestCaseReportView,
TestReportTemplateList,
PlanStageTableItem,
PlanStatusTableItem,
MsTableOperator, MsTableOperatorButton, MsDialogFooter, MsTableHeader, MsCreateBox, MsTablePagination
},
data() {
return {
result: {},
selection: [],
enableDeleteTip: false,
queryPath: "/test/plan/list",
deletePath: "/test/plan/delete",
condition: {
components: TEST_PLAN_CONFIGS
},
currentPage: 1,
pageSize: 10,
isTestManagerOrTestUser: false,
total: 0,
tableData: [],
statusFilters: [
{text: this.$t('test_track.plan.plan_status_prepare'), value: 'Prepare'},
{text: this.$t('test_track.plan.plan_status_running'), value: 'Underway'},
{text: this.$t('test_track.plan.plan_status_completed'), value: 'Completed'}
],
stageFilters: [
{text: this.$t('test_track.plan.smoke_test'), value: 'smoke'},
{text: this.$t('test_track.plan.system_test'), value: 'system'},
{text: this.$t('test_track.plan.regression_test'), value: 'regression'},
],
}
},
watch: {
'$route'(to, from) {
if (to.path.indexOf("/track/plan/all") >= 0) {
this.initTableData();
}
}
},
created() {
this.projectId = this.$route.params.projectId;
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
this.initTableData();
},
methods: {
confirm() {
if (this.selection.length==0) {
this.$warning(this.$t("api_test.definition.request.test_plan_select"));
}
this.$emit('addTestPlan', this.selection);
},
select(selection) {
this.selection = selection.map(s => s.id);
this.$emit('selection', selection);
},
initTableData() {
if (this.planId) {
this.condition.planId = this.planId;
}
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
this.condition.nodeIds = this.selectNodeIds;
}
this.result = this.$post(this.buildPagePath(this.queryPath), this.condition, response => {
let data = response.data;
this.total = data.itemCount;
this.tableData = data.listObject;
for (let i = 0; i < this.tableData.length; i++) {
let path = "/test/plan/project";
this.$post(path, {planId: this.tableData[i].id}, res => {
let arr = res.data;
let projectName = arr.map(data => data.name).join("、");
let projectIds = arr.map(data => data.id);
this.$set(this.tableData[i], "projectName", projectName);
this.$set(this.tableData[i], "projectIds", projectIds);
})
}
});
},
buildPagePath(path) {
return path + "/" + this.currentPage + "/" + this.pageSize;
},
testPlanCreate() {
this.$emit('openTestPlanEditDialog');
},
handleEdit(testPlan) {
this.$emit('testPlanEdit', testPlan);
},
statusChange(param) {
this.$post('/test/plan/edit', param, () => {
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i].id == param.id) {
this.tableData[i].status = param.status;
break;
}
}
});
},
handleDelete(testPlan) {
this.enableDeleteTip = testPlan.status === 'Underway' ? true : false;
this.$refs.deleteConfirm.open(testPlan);
},
_handleDelete(testPlan) {
let testPlanId = testPlan.id;
this.$post('/test/plan/delete/' + testPlanId, {}, () => {
this.initTableData();
this.$success(this.$t('commons.delete_success'));
// 广 head
TrackEvent.$emit(LIST_CHANGE);
});
},
intoPlan(row, event, column) {
this.$router.push('/track/plan/view/' + row.id);
},
filter(filters) {
_filter(filters, this.condition);
this.initTableData();
},
sort(column) {
_sort(column, this.condition);
this.initTableData();
},
openTestReportTemplate(data) {
this.$refs.testReportTemplateList.open(data.id);
},
openReport(planId, reportId) {
if (reportId) {
this.$refs.testCaseReportView.open(planId, reportId);
}
},
}
}
</script>
<style scoped>
.table-page {
padding-top: 20px;
margin-right: -9px;
float: right;
}
.el-table {
cursor: pointer;
}
</style>

View File

@ -530,6 +530,7 @@ export default {
extract_param: "Extract parameters",
add_module: "Add module",
edit_api: "Edit Api",
test_plan_select: "Please select test plan",
}
},
automation: {

View File

@ -529,6 +529,7 @@ export default {
extract_param: "提取参数",
add_module: "创建模块",
edit_api: "编辑接口",
test_plan_select: "请选择测试计划",
}
},
automation: {

View File

@ -529,6 +529,7 @@ export default {
extract_param: "提取參數",
add_module: "創建模塊",
edit_api: "编辑接口",
test_plan_select: "請選擇測試計劃",
}
},
automation: {