This commit is contained in:
chenjianxing 2020-12-30 22:00:23 +08:00
commit 3f80c98d76
38 changed files with 717 additions and 104 deletions

View File

@ -79,12 +79,23 @@ public class ApiDefinitionController {
apiDefinitionService.deleteBatch(ids);
}
@PostMapping("/deleteBatchByParams")
public void deleteBatchByParams(@RequestBody ApiDefinitionBatchProcessingRequest request) {
apiDefinitionService.deleteByParams(request);
}
@PostMapping("/removeToGc")
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR)
public void removeToGc(@RequestBody List<String> ids) {
apiDefinitionService.removeToGc(ids);
}
@PostMapping("/removeToGcByParams")
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR)
public void removeToGcByParams(@RequestBody ApiDefinitionBatchProcessingRequest request) {
apiDefinitionService.removeToGcByParams(request);
}
@PostMapping("/reduction")
public void reduction(@RequestBody List<SaveApiDefinitionRequest> requests) {
apiDefinitionService.reduction(requests);
@ -137,6 +148,12 @@ public class ApiDefinitionController {
apiDefinitionService.editApiBath(request);
}
@PostMapping("/batch/editByParams")
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
public void editByParams(@RequestBody ApiBatchRequest request) {
apiDefinitionService.editApiByParam(request);
}
@PostMapping("/relevance")
public void testPlanRelevance(@RequestBody ApiCaseRelevanceRequest request) {
apiDefinitionService.testPlanRelevance(request);

View File

@ -3,10 +3,7 @@ package io.metersphere.api.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.ApiCaseBatchRequest;
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.ApiTestCaseResult;
import io.metersphere.api.dto.definition.SaveApiTestCaseRequest;
import io.metersphere.api.dto.definition.*;
import io.metersphere.api.service.ApiTestCaseService;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import io.metersphere.commons.constants.RoleConstants;
@ -81,11 +78,22 @@ public class ApiTestCaseController {
apiTestCaseService.editApiBath(request);
}
@PostMapping("/batch/editByParam")
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
public void editApiBathByParam(@RequestBody ApiTestBatchRequest request) {
apiTestCaseService.editApiBathByParam(request);
}
@PostMapping("/deleteBatch")
public void deleteBatch(@RequestBody List<String> ids) {
apiTestCaseService.deleteBatch(ids);
}
@PostMapping("/deleteBatchByParam")
public void deleteBatchByParam(@RequestBody ApiTestBatchRequest request) {
apiTestCaseService.deleteBatchByParam(request);
}
@PostMapping("/relevance")
public void testPlanRelevance(@RequestBody ApiCaseRelevanceRequest request) {
apiTestCaseService.relevanceByCase(request);

View File

@ -13,4 +13,23 @@ public class ApiBatchRequest extends ApiDefinitionWithBLOBs {
private List<String> ids;
private List<OrderRequest> orders;
private String projectId;
/**
* isSelectAllDate选择的数据是否是全部数据全部数据是不受分页影响的数据
* filters: 数据状态
* name如果是全部数据那么表格如果历经查询查询参数是什么
* moduleIds 哪些模块的数据
* unSelectIds是否在页面上有未勾选的数据有的话他们的ID是哪些
* filters/name/moduleIds/unSeelctIds 只在isSelectAllDate为true时需要为了让程序能明确批量的范围
*/
private boolean isSelectAllDate;
private List<String> filters;
private String name;
private List<String> moduleIds;
private List<String> unSelectIds;
}

View File

@ -0,0 +1,39 @@
package io.metersphere.api.dto.definition;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 接口定义模块-批量处理请求类
* @author song.tianyang
* @Date 2020/12/29 4:13 下午
* @Description
*/
@Getter
@Setter
public class ApiDefinitionBatchProcessingRequest {
/**
* isSelectAllDate选择的数据是否是全部数据全部数据是不受分页影响的数据
* filters: 数据状态
* name如果是全部数据那么表格如果历经查询查询参数是什么
* moduleIds 哪些模块的数据
* unSelectIds是否在页面上有未勾选的数据有的话他们的ID是哪些
* filters/name/moduleIds/unSeelctIds 只在isSelectAllDate为true时需要为了让程序能明确批量的范围
*/
private boolean isSelectAllDate;
private List<String> filters;
private String name;
private List<String> moduleIds;
private List<String> unSelectIds;
private String projectId;
private List<String> dataIds;
}

View File

@ -0,0 +1,51 @@
package io.metersphere.api.dto.definition;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import io.metersphere.controller.request.OrderRequest;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Getter
@Setter
public class ApiTestBatchRequest extends ApiTestCaseWithBLOBs {
private List<String> ids;
private List<OrderRequest> orders;
private String projectId;
/**
* isSelectAllDate选择的数据是否是全部数据全部数据是不受分页影响的数据
* filters: 数据状态
* name如果是全部数据那么表格如果历经查询查询参数是什么
* moduleIds 哪些模块的数据
* unSelectIds是否在页面上有未勾选的数据有的话他们的ID是哪些
* filters/name/moduleIds/unSeelctIds 只在isSelectAllDate为true时需要为了让程序能明确批量的范围
*/
private boolean isSelectAllDate;
private Map<String, List<String>> filters;
private String name;
private List<String> moduleIds;
private List<String> unSelectIds;
private String protocol;
private String status;
public void cleanSelectParam() {
filters = new HashMap<>();
name = null;
moduleIds = new ArrayList<>();
protocol = null;
status = null;
}
}

View File

@ -138,9 +138,9 @@ public abstract class MsTestElement {
}
public Arguments addArguments(ParameterConfig config) {
Arguments arguments = new Arguments();
if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null
&& CollectionUtils.isNotEmpty(config.getConfig().getCommonConfig().getVariables())) {
Arguments arguments = new Arguments();
arguments.setEnabled(true);
arguments.setName(name + "Variables");
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
@ -148,9 +148,8 @@ public abstract class MsTestElement {
config.getConfig().getCommonConfig().getVariables().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue ->
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
);
return arguments;
}
return null;
return arguments;
}
}

View File

@ -189,9 +189,15 @@ public class MsHTTPSamplerProxy extends MsTestElement {
}
final HashTree httpSamplerTree = tree.add(sampler);
if (CollectionUtils.isNotEmpty(this.headers)) {
setHeader(httpSamplerTree);
// 通用请求Headers
if (config != null && config.getConfig() != null && config.getConfig().getHttpConfig() != null
&& CollectionUtils.isNotEmpty(config.getConfig().getHttpConfig().getHeaders())) {
setHeader(httpSamplerTree, config.getConfig().getHttpConfig().getHeaders());
}
if (CollectionUtils.isNotEmpty(this.headers)) {
setHeader(httpSamplerTree, this.headers);
}
//判断是否要开启DNS
if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null
&& config.getConfig().getCommonConfig().isEnableHost()) {
@ -266,7 +272,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
return arguments;
}
public void setHeader(HashTree tree) {
public void setHeader(HashTree tree, List<KeyValue> headers) {
HeaderManager headerManager = new HeaderManager();
headerManager.setEnabled(true);
headerManager.setName(this.getName() + "Headers");

View File

@ -385,6 +385,7 @@ public class ApiAutomationService {
selectRequest.setName(name);
selectRequest.setProjectId(projectId);
selectRequest.setFilters(filters);
selectRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
List<ApiScenarioDTO> list = extApiScenarioMapper.list(selectRequest);
List<String> allIds = list.stream().map(ApiScenarioDTO::getId).collect(Collectors.toList());
List<String> ids = allIds.stream().filter(id -> !unSelectIds.contains(id)).collect(Collectors.toList());

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.APIReportResult;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.ApiScenarioRequest;
import io.metersphere.api.dto.automation.ReferenceDTO;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
@ -404,6 +405,23 @@ public class ApiDefinitionService {
apiDefinitionMapper.updateByExampleSelective(definitionWithBLOBs, definitionExample);
}
public void editApiByParam(ApiBatchRequest request) {
List<String> ids = request.getIds();
if(request.isSelectAllDate()){
ids = this.getAllApiIdsByFontedSelect(request.getFilters(),request.getName(),request.getModuleIds(),request.getProjectId(),request.getUnSelectIds());
}
//name在这里只是查询参数
request.setName(null);
ApiDefinitionExample definitionExample = new ApiDefinitionExample();
definitionExample.createCriteria().andIdIn(ids);
ApiDefinitionWithBLOBs definitionWithBLOBs = new ApiDefinitionWithBLOBs();
BeanUtils.copyBean(definitionWithBLOBs, request);
definitionWithBLOBs.setUpdateTime(System.currentTimeMillis());
apiDefinitionMapper.updateByExampleSelective(definitionWithBLOBs, definitionExample);
}
public void testPlanRelevance(ApiCaseRelevanceRequest request) {
apiTestCaseService.relevanceByApi(request);
}
@ -451,6 +469,40 @@ public class ApiDefinitionService {
return apiDefinitionMapper.selectByExample(example);
}
public void deleteByParams(ApiDefinitionBatchProcessingRequest request) {
List<String> apiIds = request.getDataIds();
if(request.isSelectAllDate()){
apiIds = this.getAllApiIdsByFontedSelect(request.getFilters(),request.getName(),request.getModuleIds(),request.getProjectId(),request.getUnSelectIds());
}
ApiDefinitionExample example = new ApiDefinitionExample();
example.createCriteria().andIdIn(apiIds);
apiDefinitionMapper.deleteByExample(example);
}
private List<String> getAllApiIdsByFontedSelect(List<String> filter,String name,List<String> moduleIds,String projectId,List<String>unSelectIds) {
ApiDefinitionRequest request = new ApiDefinitionRequest();
request.setFilters(filter);
request.setName(name);
request.setModuleIds(moduleIds);
request.setProjectId(projectId);
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
List<ApiDefinitionResult> resList = extApiDefinitionMapper.list(request);
List<String> ids = new ArrayList<>(0);
if (!resList.isEmpty()) {
List<String> allIds = resList.stream().map(ApiDefinitionResult::getId).collect(Collectors.toList());
ids = allIds.stream().filter(id -> !unSelectIds.contains(id)).collect(Collectors.toList());
}
return ids;
}
public void removeToGcByParams(ApiDefinitionBatchProcessingRequest request) {
List<String> apiIds = request.getDataIds();
if(request.isSelectAllDate()){
apiIds = this.getAllApiIdsByFontedSelect(request.getFilters(),request.getName(),request.getModuleIds(),request.getProjectId(),request.getUnSelectIds());
}
extApiDefinitionMapper.removeToGc(apiIds);
}
public List<ApiDefinitionResult> listRelevance(ApiDefinitionRequest request) {
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
List<ApiDefinitionResult> resList = extApiDefinitionMapper.listRelevance(request);

View File

@ -1,12 +1,11 @@
package io.metersphere.api.service;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.ApiScenarioRequest;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.ApiTestCaseResult;
import io.metersphere.api.dto.definition.SaveApiTestCaseRequest;
import io.metersphere.api.dto.definition.*;
import io.metersphere.api.dto.ApiCaseBatchRequest;
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiDefinitionMapper;
import io.metersphere.base.mapper.ApiTestCaseMapper;
@ -26,6 +25,7 @@ import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.aspectj.util.FileUtil;
import org.python.antlr.ast.Str;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@ -348,4 +348,41 @@ public class ApiTestCaseService {
List<ApiTestCaseWithBLOBs> list = extApiTestCaseMapper.getRequest(request);
return list.stream().collect(Collectors.toMap(ApiTestCaseWithBLOBs::getId, ApiTestCaseWithBLOBs::getRequest));
}
public void deleteBatchByParam(ApiTestBatchRequest request) {
List<String> ids = request.getIds();
if(request.isSelectAllDate()){
ids = this.getAllApiCaseIdsByFontedSelect(request.getFilters(),request.getModuleIds(),request.getName(),request.getProjectId(),request.getProtocol(),request.getUnSelectIds(),request.getStatus());
}
this.deleteBatch(ids);
}
public void editApiBathByParam(ApiTestBatchRequest request) {
List<String> ids = request.getIds();
if(request.isSelectAllDate()){
ids = this.getAllApiCaseIdsByFontedSelect(request.getFilters(),request.getModuleIds(),request.getName(),request.getProjectId(),request.getProtocol(),request.getUnSelectIds(),request.getStatus());
}
request.cleanSelectParam();
ApiTestCaseExample apiDefinitionExample = new ApiTestCaseExample();
apiDefinitionExample.createCriteria().andIdIn(ids);
ApiTestCaseWithBLOBs apiDefinitionWithBLOBs = new ApiTestCaseWithBLOBs();
BeanUtils.copyBean(apiDefinitionWithBLOBs, request);
apiDefinitionWithBLOBs.setUpdateTime(System.currentTimeMillis());
apiTestCaseMapper.updateByExampleSelective(apiDefinitionWithBLOBs, apiDefinitionExample);
}
private List<String> getAllApiCaseIdsByFontedSelect(Map<String, List<String>> filters,List<String>moduleIds, String name, String projectId, String protocol,List<String> unSelectIds,String status) {
ApiTestCaseRequest selectRequest = new ApiTestCaseRequest();
selectRequest.setFilters(filters);
selectRequest.setModuleIds(moduleIds);
selectRequest.setName(name);
selectRequest.setProjectId(projectId);
selectRequest.setProtocol(protocol);
selectRequest.setStatus(status);
selectRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
List<ApiTestCaseResult> list = extApiTestCaseMapper.list(selectRequest);
List<String> allIds = list.stream().map(ApiTestCaseResult::getId).collect(Collectors.toList());
List<String> ids = allIds.stream().filter(id -> !unSelectIds.contains(id)).collect(Collectors.toList());
return ids;
}
}

View File

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

View File

@ -1233,6 +1233,76 @@ public class TestPlanExample {
addCriterion("creator not between", value1, value2, "creator");
return (Criteria) this;
}
public Criteria andProjectIdIsNull() {
addCriterion("project_id is null");
return (Criteria) this;
}
public Criteria andProjectIdIsNotNull() {
addCriterion("project_id is not null");
return (Criteria) this;
}
public Criteria andProjectIdEqualTo(String value) {
addCriterion("project_id =", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotEqualTo(String value) {
addCriterion("project_id <>", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdGreaterThan(String value) {
addCriterion("project_id >", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdGreaterThanOrEqualTo(String value) {
addCriterion("project_id >=", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLessThan(String value) {
addCriterion("project_id <", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLessThanOrEqualTo(String value) {
addCriterion("project_id <=", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLike(String value) {
addCriterion("project_id like", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotLike(String value) {
addCriterion("project_id not like", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdIn(List<String> values) {
addCriterion("project_id in", values, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotIn(List<String> values) {
addCriterion("project_id not in", values, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdBetween(String value1, String value2) {
addCriterion("project_id between", value1, value2, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotBetween(String value1, String value2) {
addCriterion("project_id not between", value1, value2, "projectId");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -19,6 +19,7 @@
<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="project_id" jdbcType="VARCHAR" property="projectId" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.TestPlan">
<result column="tags" jdbcType="LONGVARCHAR" property="tags" />
@ -84,7 +85,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, project_id
</sql>
<sql id="Blob_Column_List">
tags
@ -143,15 +144,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, project_id,
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}, #{projectId,jdbcType=VARCHAR},
#{tags,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlan">
insert into test_plan
@ -207,6 +208,9 @@
<if test="creator != null">
creator,
</if>
<if test="projectId != null">
project_id,
</if>
<if test="tags != null">
tags,
</if>
@ -263,6 +267,9 @@
<if test="creator != null">
#{creator,jdbcType=VARCHAR},
</if>
<if test="projectId != null">
#{projectId,jdbcType=VARCHAR},
</if>
<if test="tags != null">
#{tags,jdbcType=LONGVARCHAR},
</if>
@ -328,6 +335,9 @@
<if test="record.creator != null">
creator = #{record.creator,jdbcType=VARCHAR},
</if>
<if test="record.projectId != null">
project_id = #{record.projectId,jdbcType=VARCHAR},
</if>
<if test="record.tags != null">
tags = #{record.tags,jdbcType=LONGVARCHAR},
</if>
@ -355,6 +365,7 @@
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
creator = #{record.creator,jdbcType=VARCHAR},
project_id = #{record.projectId,jdbcType=VARCHAR},
tags = #{record.tags,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -378,7 +389,8 @@
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},
project_id = #{record.projectId,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -434,6 +446,9 @@
<if test="creator != null">
creator = #{creator,jdbcType=VARCHAR},
</if>
<if test="projectId != null">
project_id = #{projectId,jdbcType=VARCHAR},
</if>
<if test="tags != null">
tags = #{tags,jdbcType=LONGVARCHAR},
</if>
@ -458,6 +473,7 @@
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
creator = #{creator,jdbcType=VARCHAR},
project_id = #{projectId,jdbcType=VARCHAR},
tags = #{tags,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
@ -478,7 +494,8 @@
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},
project_id = #{projectId,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -98,9 +98,9 @@
<select id="list" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric"
parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
select DISTINCT test_plan.*, user.name as user_name from test_plan
select DISTINCT test_plan.*, user.name as user_name, project.name as projectName from test_plan
LEFT JOIN user ON user.id = test_plan.principal
JOIN test_plan_project on test_plan.id = test_plan_id JOIN project on project.id = project_id
JOIN project on project.id = test_plan.project_id
<where>
<if test="request.combine != null">
<include refid="combine">
@ -115,7 +115,7 @@
AND test_plan.workspace_id = #{request.workspaceId}
</if>
<if test="request.projectId != null">
AND test_plan_project.project_id = #{request.projectId}
AND test_plan.project_id = #{request.projectId}
</if>
<if test="request.id != null">
AND test_plan.id = #{request.id}
@ -164,11 +164,10 @@
<select id="listRelate" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric">
select distinct test_plan.* from test_plan
inner join test_plan_project on test_plan.id = test_plan_project.test_plan_id
<where>
test_plan.workspace_id = #{request.workspaceId}
<if test="request.projectId != null">
and test_plan_project.project_id = #{request.projectId}
and test_plan.project_id = #{request.projectId}
</if>
and (test_plan.principal = #{request.principal}
<if test="request.planIds != null and request.planIds.size() > 0">
@ -190,7 +189,8 @@
</select>
<select id="checkIsHave" resultType="int">
SELECT COUNT(1)
select sum(c) from (
SELECT COUNT(1) as c
FROM test_plan_project, project
WHERE project_id = project.id AND test_plan_id = #{planId}
<if test="workspaceIds != null and workspaceIds.size() > 0">
@ -199,6 +199,15 @@
#{id}
</foreach>
</if>
union
select count(1) as c from test_plan, project
WHERE project_id = project.id AND test_plan.id = #{planId}
<if test="workspaceIds != null and workspaceIds.size() > 0">
AND project.workspace_id IN
<foreach collection="workspaceIds" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</if>) as temp
</select>
<select id="selectTestPlanByRelevancy" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">

View File

@ -272,13 +272,11 @@
select distinct plan_id from test_plan_test_case
inner join test_plan
on test_plan_test_case.plan_id = test_plan.id
inner join test_plan_project
on test_plan.id = test_plan_project.test_plan_id
<where>
test_plan_test_case.executor = #{userId}
and test_plan.workspace_id = #{workspaceId}
<if test="projectId != null">
and test_plan_project.project_id = #{projectId}
and test_plan.project_id = #{projectId}
</if>
</where>
</select>

View File

@ -27,4 +27,6 @@ public class QueryTestPlanRequest extends TestPlan {
private Map<String, Object> combine;
private String projectId;
private String projectName;
}

View File

@ -1,10 +1,8 @@
package io.metersphere.track.service;
import io.metersphere.base.domain.Project;
import io.metersphere.base.domain.ProjectExample;
import io.metersphere.base.domain.TestPlanProject;
import io.metersphere.base.domain.TestPlanProjectExample;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ProjectMapper;
import io.metersphere.base.mapper.TestPlanMapper;
import io.metersphere.base.mapper.TestPlanProjectMapper;
import io.metersphere.track.request.testplancase.TestCaseRelevanceRequest;
import org.apache.commons.lang3.StringUtils;
@ -24,15 +22,22 @@ public class TestPlanProjectService {
TestPlanProjectMapper testPlanProjectMapper;
@Resource
ProjectMapper projectMapper;
@Resource
private TestPlanMapper testPlanMapper;
public List<String> getProjectIdsByPlanId(String planId) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(planId);
TestPlanProjectExample example = new TestPlanProjectExample();
example.createCriteria().andTestPlanIdEqualTo(planId);
List<String> projectIds = testPlanProjectMapper.selectByExample(example)
.stream()
.map(TestPlanProject::getProjectId)
.collect(Collectors.toList());
if (testPlan != null && StringUtils.isNotBlank(testPlan.getProjectId())) {
if (!projectIds.contains(testPlan.getProjectId())) {
projectIds.add(testPlan.getProjectId());
}
}
if (projectIds.isEmpty()) {
return null;
}

View File

@ -111,6 +111,7 @@ public class TestPlanService {
testPlan.setCreateTime(System.currentTimeMillis());
testPlan.setUpdateTime(System.currentTimeMillis());
testPlan.setCreator(SessionUtils.getUser().getId());
testPlan.setProjectId(SessionUtils.getCurrentProjectId());
testPlanMapper.insert(testPlan);
List<String> userIds = new ArrayList<>();
@ -177,8 +178,16 @@ public class TestPlanService {
}
private void editTestPlanProject(TestPlanDTO testPlan) {
// 将要进行关联的项目ID
List<String> projectIds = testPlan.getProjectIds();
// 如果将要关联的项目ID中包含测试计划所属ID则进行剔除
if (!CollectionUtils.isEmpty(projectIds)) {
if (projectIds.contains(testPlan.getProjectId())) {
projectIds.remove(testPlan.getProjectId());
}
}
// todo 优化 TestPlanList intoPlan 方法会触发此更新
if (StringUtils.isNotBlank(testPlan.getProjectId())) {
TestPlanProjectExample testPlanProjectExample1 = new TestPlanProjectExample();
testPlanProjectExample1.createCriteria().andTestPlanIdEqualTo(testPlan.getId());
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample1);
@ -195,16 +204,25 @@ public class TestPlanService {
});
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
testPlanProjectExample.createCriteria().andTestPlanIdEqualTo(testPlan.getId()).andProjectIdNotIn(projectIds);
TestPlanProjectExample.Criteria criteria1 = testPlanProjectExample.createCriteria();
criteria1.andTestPlanIdEqualTo(testPlan.getId());
if (!CollectionUtils.isEmpty(projectIds)) {
criteria1.andProjectIdNotIn(projectIds);
}
testPlanProjectMapper.deleteByExample(testPlanProjectExample);
// 关联的项目下的用例idList
TestCaseExample example = new TestCaseExample();
example.createCriteria().andProjectIdIn(projectIds);
List<TestCase> caseList = testCaseMapper.selectByExample(example);
List<String> caseIds = caseList.stream().map(TestCase::getId).collect(Collectors.toList());
List<String> caseIds = null;
// 测试计划所属项目下的用例不解除关联
projectIds.add(testPlan.getProjectId());
if (!CollectionUtils.isEmpty(projectIds)) {
TestCaseExample example = new TestCaseExample();
example.createCriteria().andProjectIdIn(projectIds);
List<TestCase> caseList = testCaseMapper.selectByExample(example);
caseIds = caseList.stream().map(TestCase::getId).collect(Collectors.toList());
}
// 取消关联所属项目下的用例和计划的关系
// 取消关联项目下的用例和计划的关系
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
TestPlanTestCaseExample.Criteria criteria = testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(testPlan.getId());
if (!CollectionUtils.isEmpty(caseIds)) {
@ -415,13 +433,13 @@ public class TestPlanService {
if (StringUtils.isBlank(currentWorkspaceId)) {
return null;
}
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
TestPlanProjectExample.Criteria criteria = testPlanProjectExample.createCriteria();
if (StringUtils.isNotBlank(SessionUtils.getCurrentProjectId())) {
TestPlanExample testPlanExample = new TestPlanExample();
TestPlanExample.Criteria criteria = testPlanExample.createCriteria();
criteria.andProjectIdEqualTo(SessionUtils.getCurrentProjectId());
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample);
if (!CollectionUtils.isEmpty(testPlanProjects)) {
List<String> testPlanIds = testPlanProjects.stream().map(TestPlanProject::getTestPlanId).collect(Collectors.toList());
List<TestPlan> testPlans = testPlanMapper.selectByExample(testPlanExample);
if (!CollectionUtils.isEmpty(testPlans)) {
List<String> testPlanIds = testPlans.stream().map(TestPlan::getId).collect(Collectors.toList());
TestPlanExample testPlanTestCaseExample = new TestPlanExample();
testPlanTestCaseExample.createCriteria().andWorkspaceIdEqualTo(currentWorkspaceId)
.andIdIn(testPlanIds)
@ -434,18 +452,18 @@ public class TestPlanService {
}
public List<TestPlan> listTestAllPlan(String currentWorkspaceId) {
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
TestPlanProjectExample.Criteria criteria = testPlanProjectExample.createCriteria();
if (StringUtils.isNotBlank(SessionUtils.getCurrentProjectId())) {
TestPlanExample testPlanExample = new TestPlanExample();
TestPlanExample.Criteria criteria = testPlanExample.createCriteria();
criteria.andProjectIdEqualTo(SessionUtils.getCurrentProjectId());
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample);
if (!CollectionUtils.isEmpty(testPlanProjects)) {
List<String> testPlanIds = testPlanProjects.stream().map(TestPlanProject::getTestPlanId).collect(Collectors.toList());
TestPlanExample testPlanExample = new TestPlanExample();
TestPlanExample.Criteria testPlanCriteria = testPlanExample.createCriteria();
List<TestPlan> testPlans = testPlanMapper.selectByExample(testPlanExample);
if (!CollectionUtils.isEmpty(testPlans)) {
List<String> testPlanIds = testPlans.stream().map(TestPlan::getId).collect(Collectors.toList());
TestPlanExample testPlanExample1 = new TestPlanExample();
TestPlanExample.Criteria testPlanCriteria = testPlanExample1.createCriteria();
testPlanCriteria.andWorkspaceIdEqualTo(currentWorkspaceId);
testPlanCriteria.andIdIn(testPlanIds);
return testPlanMapper.selectByExample(testPlanExample);
return testPlanMapper.selectByExample(testPlanExample1);
}
}

@ -1 +1 @@
Subproject commit f27d1609d77f7d6c988d37d709466e844d350e17
Subproject commit 068127ce59ea8b016434ed52a9de4a7a4b13bdb4

View File

@ -0,0 +1,55 @@
alter table test_plan add project_id varchar(50) null comment '测试计划所属项目';
DROP PROCEDURE IF EXISTS test_cursor;
DELIMITER //
CREATE PROCEDURE test_cursor()
BEGIN
DECLARE planId VARCHAR(64);
DECLARE done INT DEFAULT 0;
DECLARE cursor1 CURSOR FOR (SELECT id
FROM test_plan
WHERE project_id IS NULL);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cursor1;
outer_loop:
LOOP
FETCH cursor1 INTO planId;
IF done
THEN
LEAVE outer_loop;
END IF;
select count(1) as s, project_id
into @num, @projectId
from test_plan_test_case
join test_case on case_id = test_case.id
where plan_id = planId
group by project_id
order by s desc
limit 1;
IF @projectId = ''
THEN
select test_plan_project.project_id
into @projectId
from test_plan
join test_plan_project on test_plan.id = test_plan_project.test_plan_id
where test_plan.id = planId
limit 1;
END IF;
UPDATE test_plan SET test_plan.project_id = @projectId WHERE test_plan.id = planId;
DELETE FROM test_plan_project
WHERE test_plan_project.project_id = @projectId
AND test_plan_project.test_plan_id = planId;
SET @projectId = '';
SET done = 0;
END LOOP;
CLOSE cursor1;
END //
DELIMITER ;
CALL test_cursor();
DROP PROCEDURE IF EXISTS test_cursor;

View File

@ -230,9 +230,7 @@
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);
})
}

View File

@ -63,7 +63,7 @@
<!-- 添加/编辑测试窗口-->
<div v-else-if="item.type=== 'ADD'" class="ms-api-div">
<ms-api-config @runTest="runTest" @saveApi="saveApi" ref="apiConfig"
<ms-api-config @runTest="runTest" @saveApi="saveApi" @createRootModel="createRootModel" ref="apiConfig"
:current-api="item.api"
:currentProtocol="currentProtocol"
:moduleOptions="moduleOptions"/>
@ -215,6 +215,10 @@
this.apiTabs = tabs.filter(tab => tab.name !== targetName);
this.refresh();
},
//
createRootModel(){
this.$refs.nodeTree.createRootModel();
},
handleTabsEdit(targetName, action, api) {
if (!getCurrentProjectID()) {
this.$warning(this.$t('commons.check_project_tip'));

View File

@ -2,16 +2,16 @@
<div class="card-container">
<!-- HTTP 请求参数 -->
<ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" :request="request" :response="response"
<ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" @createRootModelInTree="createRootModelInTree" :request="request" :response="response"
:basisData="currentApi" :moduleOptions="moduleOptions" v-if="currentProtocol === 'HTTP'"/>
<!-- TCP -->
<ms-edit-complete-tcp-api :request="request" @runTest="runTest" @saveApi="saveApi" :basisData="currentApi"
<ms-edit-complete-tcp-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" v-if="currentProtocol === 'TCP'"/>
<!--DUBBO-->
<ms-edit-complete-dubbo-api :request="request" @runTest="runTest" @saveApi="saveApi" :basisData="currentApi"
<ms-edit-complete-dubbo-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" v-if="currentProtocol === 'DUBBO'"/>
<!--SQL-->
<ms-edit-complete-sql-api :request="request" @runTest="runTest" @saveApi="saveApi" :basisData="currentApi"
<ms-edit-complete-sql-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" v-if="currentProtocol === 'SQL'"/>
</div>
</template>
@ -75,6 +75,9 @@
this.$emit('runTest', data);
})
},
createRootModelInTree(){
this.$emit("createRootModel");
},
getMaintainerOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {

View File

@ -11,7 +11,17 @@
<el-col :span="12">
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
<el-select class="ms-http-input" size="small" v-model="basicForm.moduleId" style="width: 100%" @change="reload">
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
<div v-if="moduleOptions.length>0">
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
</div>
<div v-else>
<el-option :key="0" :value="''">
<div style="margin-left: 40px">
<span style="font-size: 14px;color: #606266;font-weight: 48.93">{{$t('api_test.definition.select_comp.no_data')}},
</span><el-link type="primary" @click="createModules">{{$t('api_test.definition.select_comp.add_data')}}</el-link>
</div>
</el-option>
</div>
</el-select>
</el-form-item>
</el-col>
@ -115,7 +125,10 @@
this.$emit('callback');
}
})
}
},
createModules(){
this.$emit("createRootModelInTree");
},
}
}
</script>

View File

@ -16,7 +16,7 @@
<br/>
<el-row>
<el-col>
<ms-basis-api :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
<ms-basis-api @createRootModelInTree="createRootModelInTree" :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
</el-col>
</el-row>
@ -71,7 +71,10 @@
this.basisData.request = this.request;
this.$emit('runTest', this.basisData);
}
}
},
createRootModelInTree(){
this.$emit("createRootModelInTree");
},
},
computed: {}

View File

@ -36,7 +36,17 @@
<el-col :span="8">
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
<el-select class="ms-http-select" size="small" v-model="httpForm.moduleId">
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
<div v-if="moduleOptions.length>0">
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
</div>
<div v-else>
<el-option :key="0" :value="''">
<div style="margin-left: 40px">
<span style="font-size: 14px;color: #606266;font-weight: 48.93">{{$t('api_test.definition.select_comp.no_data')}},
</span><el-link type="primary" @click="createModules">{{$t('api_test.definition.select_comp.add_data')}}</el-link>
</div>
</el-option>
</div>
</el-select>
</el-form-item>
</el-col>
@ -96,6 +106,7 @@
import {REQ_METHOD, API_STATUS} from "../../model/JsonData";
import MsJsr233Processor from "../processor/Jsr233Processor";
import {KeyValue} from "../../model/ApiTestModel";
// import {append} from "./../../../../track/common/NodeTree";
export default {
name: "MsAddCompleteHttpApi",
@ -161,6 +172,9 @@
}
})
},
createModules(){
this.$emit("createRootModelInTree");
},
getPath(id) {
if (id === null) {
return null;

View File

@ -15,7 +15,7 @@
<br/>
<el-row>
<el-col>
<ms-basis-api :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
<ms-basis-api @createRootModelInTree="createRootModelInTree" :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
</el-col>
</el-row>
@ -70,6 +70,9 @@
this.$emit('runTest', this.basisData);
}
},
createRootModelInTree(){
this.$emit("createRootModelInTree");
},
},
}
</script>

View File

@ -15,7 +15,7 @@
<br/>
<el-row>
<el-col>
<ms-basis-api :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
<ms-basis-api @createRootModelInTree="createRootModelInTree" :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
</el-col>
</el-row>
@ -70,7 +70,10 @@
this.basisData.request = this.request;
this.$emit('runTest', this.basisData);
}
}
},
createRootModelInTree(){
this.$emit("createRootModelInTree");
},
},
}
</script>

View File

@ -7,6 +7,7 @@
<el-input placeholder="搜索" @blur="search" @keyup.enter.native="search" class="search-input" size="small" v-model="condition.name"/>
<el-table v-loading="result.loading"
ref="caseTable"
border
:data="tableData" row-key="id" class="test-content adjust-table"
@select-all="handleSelectAll"
@ -15,8 +16,21 @@
@select="handleSelect" :height="screenHeight">
<el-table-column type="selection"/>
<el-table-column width="40" :resizable="false" align="center">
<el-dropdown slot="header" style="width: 14px">
<span class="el-dropdown-link" style="width: 14px">
<i class="el-icon-arrow-down el-icon--right" style="margin-left: 0px"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native.stop="isSelectDataAll(true)">
{{$t('api_test.batch_menus.select_all_data',[total])}}
</el-dropdown-item>
<el-dropdown-item @click.native.stop="isSelectDataAll(false)">
{{$t('api_test.batch_menus.select_show_data',[tableData.length])}}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<template v-slot:default="scope">
<show-more-btn :is-show="scope.row.showMore && !isReadOnly" :buttons="buttons" :size="selectRows.size"/>
<show-more-btn :is-show="scope.row.showMore && !isReadOnly" :buttons="buttons" :size="selectDataCounts"/>
</template>
</el-table-column>
@ -143,7 +157,10 @@
pageSize: 10,
total: 0,
screenHeight: document.documentElement.clientHeight - 330,//
environmentId: undefined
environmentId: undefined,
selectAll: false,
unSelection:[],
selectDataCounts:0,
}
},
props: {
@ -216,7 +233,9 @@
this.condition.status = "Trash";
this.condition.moduleIds = [];
}
this.selectAll = false;
this.unSelection = [];
this.selectDataCounts = 0;
this.condition.projectId = getCurrentProjectID();
if (this.currentProtocol != null) {
@ -226,6 +245,7 @@
this.result = this.$post('/api/testcase/list/' + this.currentPage + "/" + this.pageSize, this.condition, response => {
this.total = response.data.itemCount;
this.tableData = response.data.listObject;
this.unSelection = response.data.listObject.map(s=>s.id);
});
}
},
@ -237,6 +257,7 @@
// },
handleSelect(selection, row) {
_handleSelect(this, selection, row, this.selectRows);
this.selectRowsCount(this.selectRows)
},
showExecResult(row) {
this.visible = false;
@ -256,6 +277,7 @@
},
handleSelectAll(selection) {
_handleSelectAll(this, selection, this.tableData, this.selectRows);
this.selectRowsCount(this.selectRows)
},
search() {
this.initTable();
@ -294,7 +316,13 @@
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
this.$post('/api/testcase/deleteBatch/', Array.from(this.selectRows).map(row => row.id), () => {
let obj = {};
obj.projectId = getCurrentProjectID();
obj.selectAllDate = this.isSelectAllDate;
obj.unSelectIds = this.unSelection;
obj.ids = Array.from(this.selectRows).map(row => row.id);
obj = Object.assign(obj, this.condition);
this.$post('/api/testcase/deleteBatchByParam/', obj , () => {
this.selectRows.clear();
this.initTable();
this.$success(this.$t('commons.delete_success'));
@ -327,7 +355,12 @@
let param = {};
param[form.type] = form.value;
param.ids = ids;
this.$post('/api/testcase/batch/edit', param, () => {
param.projectId = getCurrentProjectID();
param.selectAllDate = this.isSelectAllDate;
param.unSelectIds = this.unSelection;
param = Object.assign(param, this.condition);
this.$post('/api/testcase/batch/editByParam', param, () => {
this.$success(this.$t('commons.save_success'));
this.initTable();
});
@ -355,6 +388,31 @@
},
setEnvironment(data) {
this.environmentId = data.id;
},
selectRowsCount(selection){
let selectedIDs = this.getIds(selection);
let allIDs = this.tableData.map(s=>s.id);
this.unSelection = allIDs.filter(function (val) {
return selectedIDs.indexOf(val) === -1
});
if(this.isSelectAllDate){
this.selectDataCounts =this.total - this.unSelection.length;
}else {
this.selectDataCounts =selection.size;
}
},
isSelectDataAll(dataType) {
this.isSelectAllDate = dataType;
this.selectRowsCount(this.selectRows)
//
if (this.selectRows.size != this.tableData.length) {
this.$refs.caseTable.toggleAllSelection(true);
}
},
getIds(rowSets){
let rowArray = Array.from(rowSets)
let ids = rowArray.map(s=>s.id);
return ids;
}
},
}

View File

@ -7,14 +7,28 @@
<el-input placeholder="搜索" @blur="search" class="search-input" size="small" @keyup.enter.native="search" v-model="condition.name"/>
<el-table v-loading="result.loading"
ref="apiDefinitionTable"
border
:data="tableData" row-key="id" class="test-content adjust-table"
@select-all="handleSelectAll"
@select="handleSelect" :height="screenHeight">
<el-table-column type="selection"/>
<el-table-column width="40" :resizable="false" align="center">
<el-dropdown slot="header" style="width: 14px">
<span class="el-dropdown-link" style="width: 14px">
<i class="el-icon-arrow-down el-icon--right" style="margin-left: 0px"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native.stop="isSelectDataAll(true)">
{{$t('api_test.batch_menus.select_all_data',[total])}}
</el-dropdown-item>
<el-dropdown-item @click.native.stop="isSelectDataAll(false)">
{{$t('api_test.batch_menus.select_show_data',[tableData.length])}}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<template v-slot:default="scope">
<show-more-btn :is-show="scope.row.showMore && !isReadOnly" :buttons="buttons" :size="selectRows.size"/>
<show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectDataCounts"/>
</template>
</el-table-column>
@ -157,7 +171,10 @@
pageSize: 10,
total: 0,
screenHeight: document.documentElement.clientHeight - 330,//,
environmentId: undefined
environmentId: undefined,
selectAll: false,
unSelection:[],
selectDataCounts:0,
}
},
props: {
@ -204,6 +221,11 @@
},
initTable() {
this.selectRows = new Set();
this.selectAll = false;
this.unSelection = [];
this.selectDataCounts = 0;
this.condition.filters = ["Prepare", "Underway", "Completed"];
this.condition.moduleIds = this.selectNodeIds;
@ -220,6 +242,7 @@
this.result = this.$post("/api/definition/list/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
this.total = response.data.itemCount;
this.tableData = response.data.listObject;
this.unSelection = response.data.listObject.map(s=>s.id);
});
}
},
@ -247,6 +270,7 @@
this.$set(row, "showMore", true);
})
}
this.selectRowsCount(this.selectRows)
},
handleSelectAll(selection) {
if (selection.length > 0) {
@ -266,6 +290,7 @@
this.$set(row, "showMore", false);
})
}
this.selectRowsCount(this.selectRows)
},
search() {
this.initTable();
@ -292,8 +317,14 @@
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
let deleteParam = {};
let ids = Array.from(this.selectRows).map(row => row.id);
this.$post('/api/definition/deleteBatch/', ids, () => {
deleteParam.dataIds = ids;
deleteParam.projectId = getCurrentProjectID();
deleteParam.selectAllDate = this.isSelectAllDate;
deleteParam.unSelectIds = this.unSelection;
deleteParam = Object.assign(deleteParam, this.condition);
this.$post('/api/definition/deleteBatchByParams/', deleteParam, () => {
this.selectRows.clear();
this.initTable();
this.$success(this.$t('commons.delete_success'));
@ -307,7 +338,13 @@
callback: (action) => {
if (action === 'confirm') {
let ids = Array.from(this.selectRows).map(row => row.id);
this.$post('/api/definition/removeToGc/', ids, () => {
let deleteParam = {};
deleteParam.dataIds = ids;
deleteParam.projectId = getCurrentProjectID();
deleteParam.selectAllDate = this.isSelectAllDate;
deleteParam.unSelectIds = this.unSelection;
deleteParam = Object.assign(deleteParam, this.condition);
this.$post('/api/definition/removeToGcByParams/', deleteParam, () => {
this.selectRows.clear();
this.initTable();
this.$success(this.$t('commons.delete_success'));
@ -327,7 +364,13 @@
let param = {};
param[form.type] = form.value;
param.ids = ids;
this.$post('/api/definition/batch/edit', param, () => {
param.projectId = getCurrentProjectID();
param.selectAllDate = this.isSelectAllDate;
param.unSelectIds = this.unSelection;
param = Object.assign(param, this.condition);
this.$post('/api/definition/batch/editByParams', param, () => {
this.$success(this.$t('commons.save_success'));
this.initTable();
});
@ -376,6 +419,31 @@
showExecResult(row) {
this.$emit('showExecResult', row);
},
selectRowsCount(selection){
let selectedIDs = this.getIds(selection);
let allIDs = this.tableData.map(s=>s.id);
this.unSelection = allIDs.filter(function (val) {
return selectedIDs.indexOf(val) === -1
});
if(this.isSelectAllDate){
this.selectDataCounts =this.total - this.unSelection.length;
}else {
this.selectDataCounts =selection.size;
}
},
isSelectDataAll(dataType) {
this.isSelectAllDate = dataType;
this.selectRowsCount(this.selectRows)
//
if (this.selectRows.size != this.tableData.length) {
this.$refs.apiDefinitionTable.toggleAllSelection(true);
}
},
getIds(rowSets){
let rowArray = Array.from(rowSets)
let ids = rowArray.map(s=>s.id);
return ids;
}
},
}
</script>

View File

@ -176,6 +176,13 @@
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
}
},
//---使
createRootModel(){
let dataArr = this.$refs.nodeTree.extendTreeNodes;
if(dataArr.length>0){
this.$refs.nodeTree.append({},dataArr[0]);
}
},
exportAPI() {
this.$emit('exportAPI');
},

View File

@ -66,7 +66,7 @@
</el-form-item>
<el-form-item :label="$t('test_resource_pool.type')" prop="type">
<el-select v-model="form.type" :placeholder="$t('test_resource_pool.select_pool_type')"
@change="changeResourceType()">
@change="changeResourceType(form.type)">
<el-option key="NODE" value="NODE" label="Node">Node</el-option>
<el-option key="K8S" value="K8S" label="Kubernetes" v-xpack>Kubernetes</el-option>
</el-select>
@ -89,6 +89,14 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-form-item label="Namespace"
:rules="requiredRules">
<el-input v-model="item.namespace" type="text"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-form-item :label="$t('test_resource_pool.max_threads')"
@ -205,9 +213,20 @@ export default {
this.total = data.itemCount;
})
},
changeResourceType() {
changeResourceType(type) {
this.infoList = [];
this.infoList.push({})
let info = {};
if (type === 'NODE') {
info.ip = '';
info.port = '8082';
}
if (type === 'K8S') {
info.masterUrl = '';
info.token = '';
info.namespace = '';
}
info.maxConcurrency = 100;
this.infoList.push(info);
},
addResourceInfo() {

View File

@ -58,11 +58,11 @@
<plan-stage-table-item :stage="scope.row.stage"/>
</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-->
<!-- prop="projectName"-->
<!-- :label="$t('test_track.plan.plan_project')"-->
<!-- show-overflow-tooltip>-->
<!-- </el-table-column>-->
</el-table>
@ -94,12 +94,12 @@
}
this.result = this.$post('/test/plan/list/all/relate', {}, response => {
this.tableData = response.data;
for (let i = 0; i < this.tableData.length; i++) {
let path = "/test/plan/project/name/" + this.tableData[i].id;
this.$get(path, res => {
this.$set(this.tableData[i], "projectName", res.data);
})
}
// for (let i = 0; i < this.tableData.length; i++) {
// let path = "/test/plan/project/name/" + this.tableData[i].id;
// this.$get(path, res => {
// this.$set(this.tableData[i], "projectName", res.data);
// })
// }
});
},
intoPlan(row, event, column) {

View File

@ -21,10 +21,10 @@
</el-col>
<el-col :span="11" :offset="2">
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectIds">
<el-form-item :label="$t('test_track.plan.related_project')" :label-width="formLabelWidth" prop="projectIds">
<el-select
v-model="form.projectIds"
:placeholder="$t('test_track.plan.input_plan_project')"
:placeholder="$t('test_track.plan.input_related_project')"
multiple
style="width: 100%"
filterable>
@ -134,7 +134,7 @@
import {WORKSPACE_ID} from '@/common/js/constants';
import TestPlanStatusButton from "../common/TestPlanStatusButton";
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
import {getCurrentProjectID, listenGoBack, removeGoBackListener} from "@/common/js/utils";
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
export default {
@ -158,7 +158,7 @@ export default {
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
{max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur'}
],
projectIds: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
// projectIds: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
principal: [{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}],
stage: [{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}],
description: [{max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}]
@ -248,7 +248,7 @@ export default {
getProjects() {
this.$get("/project/listAll", (response) => {
if (response.success) {
this.projects = response.data;
this.projects = response.data.filter(da => da.id !== getCurrentProjectID());
} else {
this.$warning()(response.message);
}

View File

@ -228,9 +228,7 @@ export default {
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);
let projectIds = arr.filter(d => d.id !== this.tableData[i].projectId).map(data => data.id);
this.$set(this.tableData[i], "projectIds", projectIds);
})
}

View File

@ -505,6 +505,10 @@ export default {
api_case_status: "Ise case status",
api_case_passing_rate: "Use case pass rate",
create_tip: "Note: Detailed interface information can be filled out on the edit page",
select_comp:{
no_data:"No Data",
add_data:"Add Data"
},
request: {
grade_info: "Filter by rank",
run_env: "Operating environment",
@ -1053,6 +1057,7 @@ export default {
edit_plan: "Edit test plan",
plan_name: "Test plan name",
plan_project: "Project",
related_project: "Related Project",
plan_stage: "Stage",
plan_status: "Status",
smoke_test: "Smoke test",
@ -1065,6 +1070,7 @@ export default {
input_plan_name: "Please input plan name",
input_plan_principal: "Please select principal",
input_plan_project: "Please select project",
input_related_project: "Please Related project",
input_plan_stage: "Please select stage",
plan_status_prepare: "Not started",
plan_status_running: "Starting",

View File

@ -503,6 +503,10 @@ export default {
api_case_status: "用例状态",
api_case_passing_rate: "用例通过率",
create_tip: "注: 详细的接口信息可以在编辑页面填写",
select_comp:{
no_data:"无数据",
add_data:"去添加"
},
request: {
grade_info: "按等级筛选",
run_env: "运行环境",
@ -1054,6 +1058,7 @@ export default {
edit_plan: "编辑测试计划",
plan_name: "计划名称",
plan_project: "所属项目",
related_project: "关联项目",
plan_stage: "测试阶段",
plan_status: "当前状态",
smoke_test: "冒烟测试",
@ -1066,6 +1071,7 @@ export default {
input_plan_name: "请输入测试计划名称",
input_plan_principal: "请选择负责人",
input_plan_project: "请选择所属项目",
input_related_project: "请选择关联项目",
input_plan_stage: "请选择测试阶段",
plan_status_prepare: "未开始",
plan_status_running: "进行中",

View File

@ -503,6 +503,10 @@ export default {
api_case_status: "用例狀態",
api_case_passing_rate: "用例通過率",
create_tip: "註: 詳細的接口信息可以在編輯頁面填寫",
select_comp:{
no_data:"無數據",
add_data:"去添加"
},
request: {
grade_info: "按等級筛选",
run_env: "運行環境",
@ -1053,6 +1057,7 @@ export default {
edit_plan: "編輯測試計劃",
plan_name: "計劃名稱",
plan_project: "所屬項目",
related_project: "關聯項目",
plan_stage: "測試階段",
plan_status: "當前狀態",
smoke_test: "冒煙測試",
@ -1065,6 +1070,7 @@ export default {
input_plan_name: "請輸入測試計劃名稱",
input_plan_principal: "請選擇負責人",
input_plan_project: "請選擇所屬項目",
input_related_project: "請選擇關聯項目",
input_plan_stage: "請選擇測試階段",
plan_status_prepare: "未開始",
plan_status_running: "進行中",