This commit is contained in:
fit2-zhao 2021-01-26 13:35:19 +08:00
commit 431de613b2
30 changed files with 447 additions and 281 deletions

View File

@ -290,7 +290,9 @@ public class Swagger2Parser extends SwaggerAbstractParser {
} }
refSet.add(simpleRef); refSet.add(simpleRef);
Model model = definitions.get(simpleRef); Model model = definitions.get(simpleRef);
jsonObject.put(key, getBodyParameters(model.getProperties(), refSet)); if (model != null) {
jsonObject.put(key, getBodyParameters(model.getProperties(), refSet));
}
} else { } else {
jsonObject.put(key, getDefaultValueByPropertyType(value)); jsonObject.put(key, getDefaultValueByPropertyType(value));
} }

View File

@ -0,0 +1,4 @@
package io.metersphere.base.mapper.ext;
public interface ExtBaseMapper {
}

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="io.metersphere.base.mapper.ext.ExtBaseMapper">
<sql id="orders">
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
${order.name} ${order.type}
</foreach>
</if>
</sql>
<sql id="condition">
<choose>
<when test='${object}.operator == "like"'>
like CONCAT('%', #{${object}.value},'%')
</when>
<when test='${object}.operator == "not like"'>
not like CONCAT('%', #{${object}.value},'%')
</when>
<when test='${object}.operator == "in"'>
in
<foreach collection="${object}.value" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</when>
<when test='${object}.operator == "not in"'>
not in
<foreach collection="${object}.value" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</when>
<when test='${object}.operator == "between"'>
between #{${object}.value[0]} and #{${object}.value[1]}
</when>
<when test='${object}.operator == "gt"'>
&gt; #{${object}.value}
</when>
<when test='${object}.operator == "lt"'>
&lt; #{${object}.value}
</when>
<when test='${object}.operator == "ge"'>
&gt;= #{${object}.value}
</when>
<when test='${object}.operator == "le"'>
&lt;= #{${object}.value}
</when>
<when test='${object}.operator == "current user"'>
= '${@io.metersphere.commons.utils.SessionUtils@getUserId()}'
</when>
<otherwise>
= #{${object}.value}
</otherwise>
</choose>
</sql>
</mapper>

View File

@ -1,6 +1,7 @@
package io.metersphere.base.mapper.ext; package io.metersphere.base.mapper.ext;
import io.metersphere.base.domain.TestCase; import io.metersphere.base.domain.TestCase;
import io.metersphere.controller.request.BaseQueryRequest;
import io.metersphere.track.dto.TestCaseDTO; import io.metersphere.track.dto.TestCaseDTO;
import io.metersphere.track.request.testcase.QueryTestCaseRequest; import io.metersphere.track.request.testcase.QueryTestCaseRequest;
import io.metersphere.track.request.testcase.TestCaseBatchRequest; import io.metersphere.track.request.testcase.TestCaseBatchRequest;
@ -46,4 +47,5 @@ public interface ExtTestCaseMapper {
*/ */
int checkIsHave(@Param("caseId") String caseId, @Param("workspaceIds") Set<String> workspaceIds); int checkIsHave(@Param("caseId") String caseId, @Param("workspaceIds") Set<String> workspaceIds);
List<String> selectIds(@Param("request") BaseQueryRequest condition);
} }

View File

@ -2,102 +2,58 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestCaseMapper"> <mapper namespace="io.metersphere.base.mapper.ext.ExtTestCaseMapper">
<sql id="condition">
<choose>
<when test='${object}.operator == "like"'>
like CONCAT('%', #{${object}.value},'%')
</when>
<when test='${object}.operator == "not like"'>
not like CONCAT('%', #{${object}.value},'%')
</when>
<when test='${object}.operator == "in"'>
in
<foreach collection="${object}.value" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</when>
<when test='${object}.operator == "not in"'>
not in
<foreach collection="${object}.value" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</when>
<when test='${object}.operator == "between"'>
between #{${object}.value[0]} and #{${object}.value[1]}
</when>
<when test='${object}.operator == "gt"'>
&gt; #{${object}.value}
</when>
<when test='${object}.operator == "lt"'>
&lt; #{${object}.value}
</when>
<when test='${object}.operator == "ge"'>
&gt;= #{${object}.value}
</when>
<when test='${object}.operator == "le"'>
&lt;= #{${object}.value}
</when>
<when test='${object}.operator == "current user"'>
= '${@io.metersphere.commons.utils.SessionUtils@getUserId()}'
</when>
<otherwise>
= #{${object}.value}
</otherwise>
</choose>
</sql>
<sql id="combine"> <sql id="combine">
<if test='${condition}.name != null and (${name} == null or ${name} == "")'> <if test='${condition}.name != null and (${name} == null or ${name} == "")'>
and test_case.name and test_case.name
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.name"/> <property name="object" value="${condition}.name"/>
</include> </include>
</if> </if>
<if test="${condition}.module != null"> <if test="${condition}.module != null">
and test_case.node_path and test_case.node_path
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.module"/> <property name="object" value="${condition}.module"/>
</include> </include>
</if> </if>
<if test="${condition}.priority != null"> <if test="${condition}.priority != null">
and test_case.priority and test_case.priority
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.priority"/> <property name="object" value="${condition}.priority"/>
</include> </include>
</if> </if>
<if test="${condition}.createTime != null"> <if test="${condition}.createTime != null">
and test_case.create_time and test_case.create_time
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.createTime"/> <property name="object" value="${condition}.createTime"/>
</include> </include>
</if> </if>
<if test="${condition}.type != null"> <if test="${condition}.type != null">
and test_case.type and test_case.type
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.type"/> <property name="object" value="${condition}.type"/>
</include> </include>
</if> </if>
<if test="${condition}.updateTime != null"> <if test="${condition}.updateTime != null">
and test_case.update_time and test_case.update_time
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.updateTime"/> <property name="object" value="${condition}.updateTime"/>
</include> </include>
</if> </if>
<if test="${condition}.method != null"> <if test="${condition}.method != null">
and test_case.method and test_case.method
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.method"/> <property name="object" value="${condition}.method"/>
</include> </include>
</if> </if>
<if test="${condition}.creator != null"> <if test="${condition}.creator != null">
and test_case.maintainer and test_case.maintainer
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.creator"/> <property name="object" value="${condition}.creator"/>
</include> </include>
</if> </if>
<if test="${condition}.tags != null"> <if test="${condition}.tags != null">
and test_case.tags and test_case.tags
<include refid="condition"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
<property name="object" value="${condition}.tags"/> <property name="object" value="${condition}.tags"/>
</include> </include>
</if> </if>
@ -129,32 +85,7 @@
#{nodeId} #{nodeId}
</foreach> </foreach>
</if> </if>
<if test="request.filters != null and request.filters.size() > 0"> <include refid="filters"/>
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='priority'">
and test_case.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='status'">
and test_case.review_status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<otherwise>
and test_case.type in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</otherwise>
</choose>
</if>
</foreach>
</if>
</where> </where>
ORDER BY test_case.update_time DESC ORDER BY test_case.update_time DESC
</select> </select>
@ -184,32 +115,7 @@
#{nodeId} #{nodeId}
</foreach> </foreach>
</if> </if>
<if test="request.filters != null and request.filters.size() > 0"> <include refid="filters"/>
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='priority'">
and test_case.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='status'">
and test_case.review_status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<otherwise>
and test_case.type in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</otherwise>
</choose>
</if>
</foreach>
</if>
</where> </where>
ORDER BY test_case.update_time DESC ORDER BY test_case.update_time DESC
</select> </select>
@ -236,32 +142,7 @@
#{nodeId} #{nodeId}
</foreach> </foreach>
</if> </if>
<if test="request.filters != null and request.filters.size() > 0"> <include refid="filters"/>
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='priority'">
and test_case.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='status'">
and test_case.review_status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<otherwise>
and test_case.type in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</otherwise>
</choose>
</if>
</foreach>
</if>
</where> </where>
ORDER BY test_case.update_time DESC ORDER BY test_case.update_time DESC
</select> </select>
@ -277,66 +158,8 @@
<include refid="io.metersphere.base.mapper.TestCaseMapper.Base_Column_List"/> <include refid="io.metersphere.base.mapper.TestCaseMapper.Base_Column_List"/>
</if> </if>
from test_case from test_case
<where> <include refid="queryWhereCondition"/>
<if test="request.combine != null"> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="name" value="request.name"/>
</include>
</if>
<if test="request.name != null">
and (test_case.name like CONCAT('%', #{request.name},'%')
or test_case.num like CONCAT('%', #{request.name},'%')
or test_case.tags like CONCAT('%', #{request.name},'%'))
</if>
<if test="request.nodeIds != null and request.nodeIds.size() > 0">
and test_case.node_id in
<foreach collection="request.nodeIds" item="nodeId" separator="," open="(" close=")">
#{nodeId}
</foreach>
</if>
<if test="request.projectId != null">
and test_case.project_id = #{request.projectId}
</if>
<if test="request.filters != null and request.filters.size() > 0">
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='priority'">
and test_case.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='type'">
and test_case.type in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='status'">
and test_case.review_status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<otherwise>
and test_case.method in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</otherwise>
</choose>
</if>
</foreach>
</if>
</where>
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
${order.name} ${order.type}
</foreach>
</if>
</select> </select>
<select id="listByMethod" resultType="io.metersphere.track.dto.TestCaseDTO"> <select id="listByMethod" resultType="io.metersphere.track.dto.TestCaseDTO">
SELECT id,name,project_id,"api" as type from api_test SELECT id,name,project_id,"api" as type from api_test
@ -416,4 +239,74 @@
</if> </if>
AND test_case.id = #{caseId} AND test_case.id = #{caseId}
</select> </select>
<select id="selectIds" resultType="java.lang.String">
select
id
from test_case
<include refid="queryWhereCondition"/>
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
</select>
<sql id="filters">
<if test="request.filters != null and request.filters.size() > 0">
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='priority'">
and test_case.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='type'">
and test_case.type in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='status'">
and test_case.review_status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='method'">
and test_case.method in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
</choose>
</if>
</foreach>
</if>
</sql>
<sql id="queryWhereCondition">
<where>
<if test="request.combine != null">
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="name" value="request.name"/>
</include>
</if>
<if test="request.name != null">
and (test_case.name like CONCAT('%', #{request.name},'%')
or test_case.num like CONCAT('%', #{request.name},'%')
or test_case.tags like CONCAT('%', #{request.name},'%'))
</if>
<if test="request.nodeIds != null and request.nodeIds.size() > 0">
and test_case.node_id in
<foreach collection="request.nodeIds" item="nodeId" separator="," open="(" close=")">
#{nodeId}
</foreach>
</if>
<if test="request.projectId != null">
and test_case.project_id = #{request.projectId}
</if>
<include refid="filters"/>
</where>
</sql>
</mapper> </mapper>

View File

@ -1,9 +1,12 @@
package io.metersphere.commons.utils; package io.metersphere.commons.utils;
import io.metersphere.controller.request.BaseQueryRequest;
import io.metersphere.controller.request.OrderRequest; import io.metersphere.controller.request.OrderRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ServiceUtils { public class ServiceUtils {
@ -18,4 +21,22 @@ public class ServiceUtils {
} }
return orders; return orders;
} }
/**
* 获取前端全选的id列表
* @param queryRequest 查询条件
* @param func 查询id列表的数据库查询
* @return
*/
public static void getSelectAllIds(BaseQueryRequest queryRequest, Function<BaseQueryRequest, List<String>> func) {
if (queryRequest.isSelectAll()) {
List<String> ids = func.apply(queryRequest);
if (!ids.isEmpty()) {
ids = ids.stream()
.filter(id -> !queryRequest.getUnSelectIds().contains(id))
.collect(Collectors.toList());
}
queryRequest.setIds(ids);
}
}
} }

View File

@ -0,0 +1,55 @@
package io.metersphere.controller.request;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
@Getter
@Setter
public class BaseQueryRequest {
private String projectId;
private String name;
private String workspaceId;
private List<String> ids;
private List<String> moduleIds;
private List<String> nodeIds;
/**
* 是否选中所有数据
*/
private boolean selectAll;
/**
* 全选之后取消选中的id
*/
private List<String> unSelectIds;
/**
* 排序条件
*/
private List<OrderRequest> orders;
/**
* 过滤条件
*/
private Map<String, List<String>> filters;
/**
* 高级搜索
*/
private Map<String, Object> combine;
/**
* 要查询的字段
*/
private List<String> selectFields;
}

View File

@ -46,9 +46,22 @@ public class NodeResourcePoolService {
}) })
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
if (nodeIps.size() < testResourcePool.getResources().size()) { List<Integer> nodePorts = testResourcePool.getResources().stream()
.map(resource -> {
NodeDTO nodeDTO = JSON.parseObject(resource.getConfiguration(), NodeDTO.class);
return nodeDTO.getPort();
})
.distinct()
.collect(Collectors.toList());
if (nodeIps.size() < testResourcePool.getResources().size() && nodePorts.size() < testResourcePool.getResources().size()) {
MSException.throwException(Translator.get("duplicate_node_ip_port"));
}
else if (nodeIps.size() < testResourcePool.getResources().size()) {
MSException.throwException(Translator.get("duplicate_node_ip")); MSException.throwException(Translator.get("duplicate_node_ip"));
} }
else if (nodePorts.size() < testResourcePool.getResources().size()) {
MSException.throwException(Translator.get("duplicate_node_port"));
}
testResourcePool.setStatus(VALID.name()); testResourcePool.setStatus(VALID.name());
boolean isValid = true; boolean isValid = true;
for (TestResource resource : testResourcePool.getResources()) { for (TestResource resource : testResourcePool.getResources()) {

View File

@ -1,6 +1,7 @@
package io.metersphere.track.request.testcase; package io.metersphere.track.request.testcase;
import io.metersphere.base.domain.TestCase; import io.metersphere.base.domain.TestCase;
import io.metersphere.controller.request.BaseQueryRequest;
import io.metersphere.controller.request.OrderRequest; import io.metersphere.controller.request.OrderRequest;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -10,27 +11,15 @@ import java.util.Map;
@Getter @Getter
@Setter @Setter
public class QueryTestCaseRequest extends TestCase { public class QueryTestCaseRequest extends BaseQueryRequest {
private String name; private String name;
private List<String> nodeIds;
private List<String> testCaseIds; private List<String> testCaseIds;
private List<OrderRequest> orders;
private Map<String, List<String>> filters;
private List<String> selectFields;
private String planId; private String planId;
private String workspaceId;
private String userId; private String userId;
private Map<String, Object> combine;
private String reviewId; private String reviewId;
} }

View File

@ -1,6 +1,7 @@
package io.metersphere.track.request.testcase; package io.metersphere.track.request.testcase;
import io.metersphere.base.domain.TestCaseWithBLOBs; import io.metersphere.base.domain.TestCaseWithBLOBs;
import io.metersphere.controller.request.BaseQueryRequest;
import io.metersphere.controller.request.OrderRequest; import io.metersphere.controller.request.OrderRequest;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -13,4 +14,6 @@ public class TestCaseBatchRequest extends TestCaseWithBLOBs {
private List<String> ids; private List<String> ids;
private List<OrderRequest> orders; private List<OrderRequest> orders;
private String projectId; private String projectId;
private BaseQueryRequest condition;
} }

View File

@ -528,6 +528,7 @@ public class TestCaseService {
public void editTestCaseBath(TestCaseBatchRequest request) { public void editTestCaseBath(TestCaseBatchRequest request) {
getSelectAllIds(request);
TestCaseExample testCaseExample = new TestCaseExample(); TestCaseExample testCaseExample = new TestCaseExample();
testCaseExample.createCriteria().andIdIn(request.getIds()); testCaseExample.createCriteria().andIdIn(request.getIds());
@ -541,12 +542,21 @@ public class TestCaseService {
} }
public void deleteTestCaseBath(TestCaseBatchRequest request) { public void deleteTestCaseBath(TestCaseBatchRequest request) {
getSelectAllIds(request);
deleteTestPlanTestCaseBath(request.getIds()); deleteTestPlanTestCaseBath(request.getIds());
TestCaseExample example = new TestCaseExample(); TestCaseExample example = new TestCaseExample();
example.createCriteria().andIdIn(request.getIds()); example.createCriteria().andIdIn(request.getIds());
testCaseMapper.deleteByExample(example); testCaseMapper.deleteByExample(example);
} }
public void getSelectAllIds(TestCaseBatchRequest request) {
if (request.getCondition().isSelectAll()) {
ServiceUtils.getSelectAllIds(request.getCondition(),
(query) -> extTestCaseMapper.selectIds(query));
request.setIds(request.getCondition().getIds());
}
}
public void deleteTestPlanTestCaseBath(List<String> caseIds) { public void deleteTestPlanTestCaseBath(List<String> caseIds) {
TestPlanTestCaseExample example = new TestPlanTestCaseExample(); TestPlanTestCaseExample example = new TestPlanTestCaseExample();
example.createCriteria().andCaseIdIn(caseIds); example.createCriteria().andCaseIdIn(caseIds);

@ -1 +1 @@
Subproject commit e4521190f0f1be113c8b84fbdcdf8ff273bf274e Subproject commit 647e945828e9f15de61cf19e726424bec06051f8

View File

@ -43,6 +43,8 @@ test_not_running=Test is not running
load_test_already_exists=Duplicate load test name load_test_already_exists=Duplicate load test name
no_nodes_message=No node message no_nodes_message=No node message
duplicate_node_ip=Duplicate IPs duplicate_node_ip=Duplicate IPs
duplicate_node_port=Duplicate Ports
duplicate_node_ip_port=Duplicate IPs & Ports
max_thread_insufficient=The number of concurrent users exceeds max_thread_insufficient=The number of concurrent users exceeds
related_case_del_fail_prefix=Connected to related_case_del_fail_prefix=Connected to
related_case_del_fail_suffix=TestCase, please disassociate first related_case_del_fail_suffix=TestCase, please disassociate first

View File

@ -43,6 +43,8 @@ test_not_running=测试未运行
load_test_already_exists=测试名称不能重复 load_test_already_exists=测试名称不能重复
no_nodes_message=没有节点信息 no_nodes_message=没有节点信息
duplicate_node_ip=节点 IP 重复 duplicate_node_ip=节点 IP 重复
duplicate_node_port=节点 Port 重复
duplicate_node_ip_port=节点 IP、Port 重复
max_thread_insufficient=并发用户数超额 max_thread_insufficient=并发用户数超额
related_case_del_fail_prefix=已关联到 related_case_del_fail_prefix=已关联到
related_case_del_fail_suffix=测试用例,请先解除关联 related_case_del_fail_suffix=测试用例,请先解除关联

View File

@ -43,6 +43,8 @@ test_not_running=測試未運行
load_test_already_exists=測試名稱不能重復 load_test_already_exists=測試名稱不能重復
no_nodes_message=沒有節點信息 no_nodes_message=沒有節點信息
duplicate_node_ip=節點 IP 重復 duplicate_node_ip=節點 IP 重復
duplicate_node_port=節點 Port 重復
duplicate_node_ip_port=節點 IP、Port 重復
max_thread_insufficient=並發用戶數超額 max_thread_insufficient=並發用戶數超額
related_case_del_fail_prefix=已關聯到 related_case_del_fail_prefix=已關聯到
related_case_del_fail_suffix=測試用例,請先解除關聯 related_case_del_fail_suffix=測試用例,請先解除關聯

View File

@ -35,7 +35,7 @@
closable> closable>
<div class="ms-api-scenario-div"> <div class="ms-api-scenario-div">
<ms-edit-api-scenario @refresh="refresh" :currentScenario="item.currentScenario" <ms-edit-api-scenario @refresh="refresh" :currentScenario="item.currentScenario"
:moduleOptions="moduleOptions"/> :moduleOptions="moduleOptions" ref="autoScenarioConfig"/>
</div> </div>
</el-tab-pane> </el-tab-pane>
@ -111,6 +111,16 @@
// DOM my-component // DOM my-component
this.renderComponent = true; this.renderComponent = true;
}); });
},
'$route'(to, from) { // ctrl s
if (to.path.indexOf('/api/automation') == -1) {
if (this.$refs && this.$refs.autoScenarioConfig) {
console.log(this.$refs.autoScenarioConfig);
this.$refs.autoScenarioConfig.forEach(item => {
item.removeListener();
});
}
}
} }
}, },
methods: { methods: {
@ -158,6 +168,20 @@
label = tab.currentScenario.name; label = tab.currentScenario.name;
this.tabs.push({label: label, name: name, currentScenario: tab.currentScenario}); this.tabs.push({label: label, name: name, currentScenario: tab.currentScenario});
} }
if (this.$refs && this.$refs.autoScenarioConfig) {
this.$refs.autoScenarioConfig.forEach(item => {
item.removeListener();
}); // tab ctrl + s
this.addListener();
}
},
addListener() {
let index = this.tabs.findIndex(item => item.name === this.activeName); // tabindex
if(index != -1) { // tab
this.$nextTick(()=>{
this.$refs.autoScenarioConfig[index].addListener();
});
}
}, },
handleTabClose() { handleTabClose() {
this.tabs = []; this.tabs = [];
@ -181,6 +205,7 @@
this.tabs = this.tabs.filter(tab => tab.name !== targetName); this.tabs = this.tabs.filter(tab => tab.name !== targetName);
if (this.tabs.length > 0) { if (this.tabs.length > 0) {
this.activeName = this.tabs[this.tabs.length - 1].name; this.activeName = this.tabs[this.tabs.length - 1].name;
this.addListener(); //
} else { } else {
this.activeName = "default" this.activeName = "default"
} }

View File

@ -5,7 +5,7 @@
<!--操作按钮--> <!--操作按钮-->
<div class="ms-opt-btn"> <div class="ms-opt-btn">
<el-button type="primary" size="small" @click="editScenario">{{$t('commons.save')}}</el-button> <el-button type="primary" size="small" @click="editScenario" title="ctrl + s">{{$t('commons.save')}}</el-button>
</div> </div>
<div class="tip">{{$t('test_track.plan_view.base_info')}}</div> <div class="tip">{{$t('test_track.plan_view.base_info')}}</div>
@ -222,6 +222,7 @@
import ScenarioApiRelevance from "./api/ApiRelevance"; import ScenarioApiRelevance from "./api/ApiRelevance";
import ScenarioRelevance from "./api/ScenarioRelevance"; import ScenarioRelevance from "./api/ScenarioRelevance";
import MsComponentConfig from "./component/ComponentConfig"; import MsComponentConfig from "./component/ComponentConfig";
import {handleCtrlSEvent} from "../../../../../common/js/utils";
export default { export default {
name: "EditApiScenario", name: "EditApiScenario",
@ -295,6 +296,7 @@
this.operatingElements = ELEMENTS.get("ALL"); this.operatingElements = ELEMENTS.get("ALL");
this.getMaintainerOptions(); this.getMaintainerOptions();
this.getApiScenario(); this.getApiScenario();
this.addListener(); // ctrl s
}, },
directives: {OutsideClick}, directives: {OutsideClick},
computed: { computed: {
@ -413,6 +415,17 @@
} }
}, },
methods: { methods: {
addListener() {
document.addEventListener("keydown", this.createCtrlSHandle);
// document.addEventListener("keydown", (even => handleCtrlSEvent(even, this.$refs.httpApi.saveApi)));
},
removeListener() {
document.removeEventListener("keydown", this.createCtrlSHandle);
},
createCtrlSHandle(event) {
console.log("create ctrl + s");
handleCtrlSEvent(event, this.editScenario);
},
getIdx(index) { getIdx(index) {
return index - 0.33 return index - 0.33
}, },
@ -822,15 +835,13 @@
} }
return bodyUploadFiles; return bodyUploadFiles;
}, },
editScenario(showMessage) { editScenario() {
this.$refs['currentScenario'].validate((valid) => { this.$refs['currentScenario'].validate((valid) => {
if (valid) { if (valid) {
this.setParameter(); this.setParameter();
let bodyFiles = this.getBodyUploadFiles(this.currentScenario); let bodyFiles = this.getBodyUploadFiles(this.currentScenario);
this.$fileUpload(this.path, null, bodyFiles, this.currentScenario, response => { this.$fileUpload(this.path, null, bodyFiles, this.currentScenario, response => {
if (showMessage) { this.$success(this.$t('commons.save_success'));
this.$success(this.$t('commons.save_success'));
}
this.path = "/api/automation/update"; this.path = "/api/automation/update";
if (response.data) { if (response.data) {
this.currentScenario.id = response.data.id; this.currentScenario.id = response.data.id;

View File

@ -198,6 +198,15 @@
// DOM my-component // DOM my-component
this.renderComponent = true; this.renderComponent = true;
}); });
},
'$route'(to, from) { // ctrl s
if (to.path.indexOf('/api/definition') == -1) {
if (this.$refs && this.$refs.apiConfig) {
this.$refs.apiConfig.forEach(item => {
item.removeListener();
});
}
}
} }
}, },
methods: { methods: {
@ -211,6 +220,17 @@
if (tab.name === 'add') { if (tab.name === 'add') {
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug"); this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug");
} }
if(this.$refs.apiConfig) {
this.$refs.apiConfig.forEach(item => {
console.log(item);
item.removeListener();
}); // tab ctrl + s
let tabs = this.apiTabs;
let index = tabs.findIndex(item => item.name === tab.name); // tabindex
if(index != -1) {
this.$refs.apiConfig[index - 1].addListener(); // tab ctrl + s index-1tab
}
}
}, },
handleCommand(e) { handleCommand(e) {
switch (e) { switch (e) {

View File

@ -3,16 +3,16 @@
<div class="card-container"> <div class="card-container">
<!-- HTTP 请求参数 --> <!-- HTTP 请求参数 -->
<ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" @createRootModelInTree="createRootModelInTree" :request="request" :response="response" <ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" @createRootModelInTree="createRootModelInTree" :request="request" :response="response"
:basisData="currentApi" :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'HTTP'"/> :basisData="currentApi" :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'HTTP'" ref="httpApi"/>
<!-- TCP --> <!-- TCP -->
<ms-edit-complete-tcp-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi" <ms-edit-complete-tcp-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'TCP'"/> :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'TCP'" ref="tcpApi"/>
<!--DUBBO--> <!--DUBBO-->
<ms-edit-complete-dubbo-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi" <ms-edit-complete-dubbo-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'DUBBO'"/> :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'DUBBO'" ref="dubboApi"/>
<!--SQL--> <!--SQL-->
<ms-edit-complete-sql-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi" <ms-edit-complete-sql-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'SQL'"/> :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'SQL'" ref="sqlApi"/>
</div> </div>
</template> </template>
@ -27,6 +27,7 @@
import {createComponent, Request} from "./jmeter/components"; import {createComponent, Request} from "./jmeter/components";
import Sampler from "./jmeter/components/sampler/sampler"; import Sampler from "./jmeter/components/sampler/sampler";
import {WORKSPACE_ID} from '@/common/js/constants'; import {WORKSPACE_ID} from '@/common/js/constants';
import {handleCtrlSEvent} from "../../../../../common/js/utils";
export default { export default {
name: "ApiConfig", name: "ApiConfig",
@ -65,8 +66,30 @@
break; break;
} }
this.formatApi(); this.formatApi();
this.addListener();
}, },
methods: { methods: {
addListener() {
document.addEventListener("keydown", this.createCtrlSHandle);
// document.addEventListener("keydown", (even => handleCtrlSEvent(even, this.$refs.httpApi.saveApi)));
},
removeListener() {
document.removeEventListener("keydown", this.createCtrlSHandle);
},
createCtrlSHandle(event) {
if(this.$refs.httpApi) {
handleCtrlSEvent(event, this.$refs.httpApi.saveApi);
}
else if(this.$refs.tcpApi) {
handleCtrlSEvent(event, this.$refs.tcpApi.saveApi);
}
else if(this.$refs.dubboApi) {
handleCtrlSEvent(event, this.$refs.dubboApi.saveApi);
}
else if(this.$refs.sqlApi) {
handleCtrlSEvent(event, this.$refs.sqlApi.saveApi);
}
},
runTest(data) { runTest(data) {
this.setParameters(data); this.setParameters(data);
let bodyFiles = this.getBodyUploadFiles(data); let bodyFiles = this.getBodyUploadFiles(data);

View File

@ -6,7 +6,7 @@
<el-col> <el-col>
<!--操作按钮--> <!--操作按钮-->
<div style="float: right;margin-right: 20px;margin-top: 20px"> <div style="float: right;margin-right: 20px;margin-top: 20px">
<el-button type="primary" size="small" @click="saveApi">{{ $t('commons.save') }}</el-button> <el-button type="primary" size="small" @click="saveApi" title="ctrl + s">{{ $t('commons.save') }}</el-button>
<el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button> <el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button>
</div> </div>
</el-col> </el-col>

View File

@ -6,7 +6,7 @@
<el-form :model="httpForm" :rules="rule" ref="httpForm" label-width="80px" label-position="right"> <el-form :model="httpForm" :rules="rule" ref="httpForm" label-width="80px" label-position="right">
<!-- 操作按钮 --> <!-- 操作按钮 -->
<div style="float: right;margin-right: 20px"> <div style="float: right;margin-right: 20px">
<el-button type="primary" size="small" @click="saveApi">{{ $t('commons.save') }}</el-button> <el-button type="primary" size="small" @click="saveApi" title="ctrl + s">{{ $t('commons.save') }}</el-button>
<el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button> <el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button>
</div> </div>
<br/> <br/>

View File

@ -5,7 +5,7 @@
<el-col> <el-col>
<!--操作按钮--> <!--操作按钮-->
<div style="float: right;margin-right: 20px;margin-top: 20px"> <div style="float: right;margin-right: 20px;margin-top: 20px">
<el-button type="primary" size="small" @click="saveApi">{{ $t('commons.save') }}</el-button> <el-button type="primary" size="small" @click="saveApi" title="ctrl + s">{{ $t('commons.save') }}</el-button>
<el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button> <el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button>
</div> </div>
</el-col> </el-col>

View File

@ -5,7 +5,7 @@
<el-col> <el-col>
<!--操作按钮--> <!--操作按钮-->
<div style="float: right;margin-right: 20px;margin-top: 20px"> <div style="float: right;margin-right: 20px;margin-top: 20px">
<el-button type="primary" size="small" @click="saveApi">{{ $t('commons.save') }}</el-button> <el-button type="primary" size="small" @click="saveApi" title="ctrl + s">{{ $t('commons.save') }}</el-button>
<el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button> <el-button type="primary" size="small" @click="runTest">{{ $t('commons.test') }}</el-button>
</div> </div>
</el-col> </el-col>

View File

@ -8,6 +8,7 @@
<el-dropdown-item command="personal">{{ $t('commons.personal_information') }}</el-dropdown-item> <el-dropdown-item command="personal">{{ $t('commons.personal_information') }}</el-dropdown-item>
<el-dropdown-item command="about">{{ $t('commons.about_us') }} <i class="el-icon-info"/></el-dropdown-item> <el-dropdown-item command="about">{{ $t('commons.about_us') }} <i class="el-icon-info"/></el-dropdown-item>
<el-dropdown-item command="help">{{ $t('commons.help_documentation') }}</el-dropdown-item> <el-dropdown-item command="help">{{ $t('commons.help_documentation') }}</el-dropdown-item>
<el-dropdown-item command="ApiHelp">{{ $t('commons.api_help_documentation') }}</el-dropdown-item>
<el-dropdown-item command="old" v-show=isReadOnly @click.native="changeBar('old')"> <el-dropdown-item command="old" v-show=isReadOnly @click.native="changeBar('old')">
{{ $t('commons.cut_back_old_version') }} {{ $t('commons.cut_back_old_version') }}
</el-dropdown-item> </el-dropdown-item>
@ -64,6 +65,9 @@ export default {
case "help": case "help":
window.location.href = "https://metersphere.io/docs/index.html"; window.location.href = "https://metersphere.io/docs/index.html";
break; break;
case "ApiHelp":
window.open('/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config', "_blank");
break;
default: default:
break; break;
} }

View File

@ -12,15 +12,15 @@
<ms-main-container> <ms-main-container>
<test-case-list <test-case-list
:module-options="moduleOptions"
:select-node-ids="selectNodeIds" :select-node-ids="selectNodeIds"
:select-parent-nodes="selectParentNodes" :select-parent-nodes="selectParentNodes"
:tree-nodes="treeNodes"
@testCaseEdit="editTestCase" @testCaseEdit="editTestCase"
@testCaseCopy="copyTestCase" @testCaseCopy="copyTestCase"
@testCaseDetail="showTestCaseDetail" @testCaseDetail="showTestCaseDetail"
@batchMove="batchMove"
@refresh="refresh" @refresh="refresh"
@refreshAll="refreshAll" @refreshAll="refreshAll"
@moveToNode="moveToNode"
@setCondition="setCondition" @setCondition="setCondition"
ref="testCaseList"> ref="testCaseList">
</test-case-list> </test-case-list>
@ -28,6 +28,7 @@
<test-case-edit <test-case-edit
@refresh="refreshTable" @refresh="refreshTable"
@setModuleOptions="setModuleOptions"
:read-only="testCaseReadOnly" :read-only="testCaseReadOnly"
:tree-nodes="treeNodes" :tree-nodes="treeNodes"
:select-node="selectNode" :select-node="selectNode"
@ -35,9 +36,6 @@
ref="testCaseEditDialog"> ref="testCaseEditDialog">
</test-case-edit> </test-case-edit>
<test-case-move @refresh="refresh" ref="testCaseMove"/>
<batch-move @refresh="refresh" @moveSave="moveSave" ref="testBatchMove"/>
</ms-container> </ms-container>
@ -49,12 +47,10 @@ import NodeTree from '../common/NodeTree';
import TestCaseEdit from './components/TestCaseEdit'; import TestCaseEdit from './components/TestCaseEdit';
import TestCaseList from "./components/TestCaseList"; import TestCaseList from "./components/TestCaseList";
import SelectMenu from "../common/SelectMenu"; import SelectMenu from "../common/SelectMenu";
import TestCaseMove from "./components/TestCaseMove";
import MsContainer from "../../common/components/MsContainer"; import MsContainer from "../../common/components/MsContainer";
import MsAsideContainer from "../../common/components/MsAsideContainer"; import MsAsideContainer from "../../common/components/MsAsideContainer";
import MsMainContainer from "../../common/components/MsMainContainer"; import MsMainContainer from "../../common/components/MsMainContainer";
import {checkoutTestManagerOrTestUser, getCurrentProjectID, hasRoles} from "../../../../common/js/utils"; import {checkoutTestManagerOrTestUser, getCurrentProjectID, hasRoles} from "../../../../common/js/utils";
import BatchMove from "./components/BatchMove";
import TestCaseNodeTree from "../common/TestCaseNodeTree"; import TestCaseNodeTree from "../common/TestCaseNodeTree";
import {TrackEvent,LIST_CHANGE} from "@/business/components/common/head/ListEvent"; import {TrackEvent,LIST_CHANGE} from "@/business/components/common/head/ListEvent";
@ -63,7 +59,7 @@ export default {
components: { components: {
TestCaseNodeTree, TestCaseNodeTree,
MsMainContainer, MsMainContainer,
MsAsideContainer, MsContainer, TestCaseMove, TestCaseList, NodeTree, TestCaseEdit, SelectMenu, BatchMove MsAsideContainer, MsContainer, TestCaseList, NodeTree, TestCaseEdit, SelectMenu
}, },
comments: {}, comments: {},
data() { data() {
@ -75,7 +71,8 @@ export default {
selectParentNodes: [], selectParentNodes: [],
testCaseReadOnly: true, testCaseReadOnly: true,
selectNode: {}, selectNode: {},
condition: {} condition: {},
moduleOptions: []
} }
}, },
mounted() { mounted() {
@ -153,32 +150,14 @@ export default {
this.$refs.testCaseEditDialog.open(); this.$refs.testCaseEditDialog.open();
} }
}, },
moveToNode(selectIds) {
if (selectIds.size < 1) {
this.$warning(this.$t('test_track.plan_view.select_manipulate'));
return;
}
this.$refs.testCaseEditDialog.getModuleOptions();
this.$refs.testCaseMove.open(this.$refs.testCaseEditDialog.moduleOptions, selectIds);
},
batchMove(selectIds) {
this.$refs.testBatchMove.open(this.treeNodes, selectIds, this.$refs.testCaseEditDialog.moduleOptions);
},
setTreeNodes(data) { setTreeNodes(data) {
this.treeNodes = data; this.treeNodes = data;
}, },
setCondition(data) { setCondition(data) {
this.condition = data; this.condition = data;
}, },
moveSave(param) { setModuleOptions(data) {
this.result = this.$post('/test/case/batch/edit', param, () => { this.moduleOptions = data;
this.$success(this.$t('commons.save_success'));
this.$refs.testBatchMove.close();
// 广 head
TrackEvent.$emit(LIST_CHANGE);
this.refresh();
});
} }
} }
} }

View File

@ -379,6 +379,9 @@ export default {
treeNodes() { treeNodes() {
this.getModuleOptions(); this.getModuleOptions();
}, },
moduleOptions() {
this.$emit('setModuleOptions', this.moduleOptions);
}
}, },
methods: { methods: {
reload() { reload() {

View File

@ -15,11 +15,6 @@
:content="$t('test_track.case.import.import')" @click="importTestCase"/> :content="$t('test_track.case.import.import')" @click="importTestCase"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2" <ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
:content="$t('test_track.case.export.export')" @click="handleBatch('export')"/> :content="$t('test_track.case.export.export')" @click="handleBatch('export')"/>
<!-- <ms-table-button :is-tester-permission="true" icon="el-icon-right" :content="$t('test_track.case.move')"-->
<!-- @click="handleBatch('move')"/>-->
<!-- <ms-table-button :is-tester-permission="true" icon="el-icon-delete" :content="$t('test_track.case.delete')"-->
<!-- @click="handleBatch('delete')"/>-->
<!--<test-case-export/>-->
</template> </template>
</ms-table-header> </ms-table-header>
@ -33,12 +28,22 @@
@sort-change="sort" @sort-change="sort"
@filter-change="filter" @filter-change="filter"
@select-all="handleSelectAll" @select-all="handleSelectAll"
@select="handleSelectionChange" @select="handleSelect"
@cell-mouse-enter="showPopover" @cell-mouse-enter="showPopover"
row-key="id" row-key="id"
class="test-content adjust-table"> class="test-content adjust-table ms-select-all"
ref="table">
<el-table-column <el-table-column
width="50"
type="selection"/> type="selection"/>
<ms-table-select-all
:page-size="pageSize > total ? total : pageSize"
:total="total"
@selectPageAll="isSelectDataAll(false)"
@selectAll="isSelectDataAll(true)"/>
<el-table-column width="40" :resizable="false" align="center"> <el-table-column width="40" :resizable="false" align="center">
<template v-slot:default="scope"> <template v-slot:default="scope">
<show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectRows.size"/> <show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectRows.size"/>
@ -156,6 +161,8 @@
<batch-edit ref="batchEdit" @batchEdit="batchEdit" <batch-edit ref="batchEdit" @batchEdit="batchEdit"
:typeArr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_case')"/> :typeArr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_case')"/>
<batch-move @refresh="refresh" @moveSave="moveSave" ref="testBatchMove"/>
</div> </div>
</template> </template>
@ -184,10 +191,15 @@ import TestCaseDetail from "./TestCaseDetail";
import ReviewStatus from "@/business/components/track/case/components/ReviewStatus"; import ReviewStatus from "@/business/components/track/case/components/ReviewStatus";
import {getCurrentProjectID} from "../../../../../common/js/utils"; import {getCurrentProjectID} from "../../../../../common/js/utils";
import MsTag from "@/business/components/common/components/MsTag"; import MsTag from "@/business/components/common/components/MsTag";
import MsTableSelectAll from "../../../common/components/table/MsTableSelectAll";
import {_handleSelect, _handleSelectAll} from "../../../../../common/js/tableUtils";
import BatchMove from "./BatchMove";
export default { export default {
name: "TestCaseList", name: "TestCaseList",
components: { components: {
BatchMove,
MsTableSelectAll,
MsTableButton, MsTableButton,
MsTableOperatorButton, MsTableOperatorButton,
MsTableOperator, MsTableOperator,
@ -274,7 +286,7 @@ export default {
maintainer: [], maintainer: [],
}, },
currentCaseId: null, currentCaseId: null,
projectId: "" projectId: "",
} }
}, },
props: { props: {
@ -283,6 +295,12 @@ export default {
}, },
selectParentNodes: { selectParentNodes: {
type: Array type: Array
},
treeNodes: {
type: Array
},
moduleOptions: {
type: Array
} }
}, },
created: function () { created: function () {
@ -303,6 +321,8 @@ export default {
this.projectId = getCurrentProjectID(); this.projectId = getCurrentProjectID();
this.condition.planId = ""; this.condition.planId = "";
this.condition.nodeIds = []; this.condition.nodeIds = [];
this.condition.selectAll = false;
this.condition.unSelectIds = [];
if (this.planId) { if (this.planId) {
// param.planId = this.planId; // param.planId = this.planId;
this.condition.planId = this.planId; this.condition.planId = this.planId;
@ -366,8 +386,10 @@ export default {
confirmButtonText: this.$t('commons.confirm'), confirmButtonText: this.$t('commons.confirm'),
callback: (action) => { callback: (action) => {
if (action === 'confirm') { if (action === 'confirm') {
let ids = Array.from(this.selectRows).map(row => row.id); let param = {};
this.$post('/test/case/batch/delete', {ids: ids}, () => { param.ids = Array.from(this.selectRows).map(row => row.id);
param.condition = this.condition;
this.$post('/test/case/batch/delete', param, () => {
this.selectRows.clear(); this.selectRows.clear();
this.$emit("refresh"); this.$emit("refresh");
this.$success(this.$t('commons.delete_success')); this.$success(this.$t('commons.delete_success'));
@ -401,26 +423,12 @@ export default {
this.$emit('testCaseDetail', row); this.$emit('testCaseDetail', row);
}, },
handleSelectAll(selection) { handleSelectAll(selection) {
if (selection.length > 0) { _handleSelectAll(this, selection, this.tableData, this.selectRows);
this.tableData.forEach(item => { this.setUnSelectIds();
this.$set(item, "showMore", true);
this.selectRows.add(item);
});
} else {
this.selectRows.clear();
this.tableData.forEach(row => {
this.$set(row, "showMore", false);
})
}
}, },
handleSelectionChange(selection, row) { handleSelect(selection, row) {
if (this.selectRows.has(row)) { _handleSelect(this, selection, row, this.selectRows);
this.$set(row, "showMore", false); this.setUnSelectIds();
this.selectRows.delete(row);
} else {
this.$set(row, "showMore", true);
this.selectRows.add(row);
}
}, },
importTestCase() { importTestCase() {
if (!getCurrentProjectID()) { if (!getCurrentProjectID()) {
@ -457,7 +465,6 @@ export default {
}); });
}, },
handleBatch(type) { handleBatch(type) {
if (this.selectRows.size < 1) { if (this.selectRows.size < 1) {
if (type === 'export') { if (type === 'export') {
this.$alert(this.$t('test_track.case.export_all_cases'), '', { this.$alert(this.$t('test_track.case.export_all_cases'), '', {
@ -489,6 +496,7 @@ export default {
let param = {}; let param = {};
param[form.type] = form.value; param[form.type] = form.value;
param.ids = ids; param.ids = ids;
param.condition = this.condition;
this.$post('/test/case/batch/edit', param, () => { this.$post('/test/case/batch/edit', param, () => {
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
this.refresh(); this.refresh();
@ -513,7 +521,7 @@ export default {
this.$refs.batchEdit.open(); this.$refs.batchEdit.open();
}, },
handleBatchMove() { handleBatchMove() {
this.$emit("batchMove", Array.from(this.selectRows).map(row => row.id)); this.$refs.testBatchMove.open(this.treeNodes, Array.from(this.selectRows).map(row => row.id), this.moduleOptions);
}, },
getMaintainerOptions() { getMaintainerOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID); let workspaceId = localStorage.getItem(WORKSPACE_ID);
@ -525,6 +533,31 @@ export default {
if (column.property === 'name') { if (column.property === 'name') {
this.currentCaseId = row.id; this.currentCaseId = row.id;
} }
},
isSelectDataAll(data) {
this.condition.selectAll = data;
this.setUnSelectIds();
//
if (this.selectRows.size != this.tableData.length) {
this.$refs.table.toggleAllSelection(true);
}
},
setUnSelectIds() {
let ids = Array.from(this.selectRows).map(o => o.id);
let allIDs = this.tableData.map(o => o.id);
this.condition.unSelectIds = allIDs.filter(function (val) {
return ids.indexOf(val) === -1
});
},
moveSave(param) {
param.condition = this.condition;
this.result = this.$post('/test/case/batch/edit', param, () => {
this.$success(this.$t('commons.save_success'));
this.$refs.testBatchMove.close();
// 广 head
TrackEvent.$emit(LIST_CHANGE);
this.refresh();
});
} }
} }
} }

View File

@ -356,3 +356,12 @@ export function _getBodyUploadFiles(request, bodyUploadFiles, obj) {
} }
} }
} }
export function handleCtrlSEvent(event, func) {
if (event.keyCode === 83 && event.ctrlKey) {
// console.log('拦截到 ctrl + s');//ctrl+s
func();
event.preventDefault();
event.returnValue = false;
return false;
}
}

View File

@ -8,6 +8,7 @@ export default {
comment: '评论', comment: '评论',
examples: '示例', examples: '示例',
help_documentation: '帮助文档', help_documentation: '帮助文档',
api_help_documentation: 'API文档',
delete_cancelled: '已取消删除', delete_cancelled: '已取消删除',
workspace: '工作空间', workspace: '工作空间',
organization: '组织', organization: '组织',

View File

@ -8,6 +8,7 @@ export default {
comment: '評論', comment: '評論',
examples: '示例', examples: '示例',
help_documentation: '幫助文檔', help_documentation: '幫助文檔',
api_help_documentation: 'API文檔',
delete_cancelled: '已取消刪除', delete_cancelled: '已取消刪除',
workspace: '工作空間', workspace: '工作空間',
organization: '組織', organization: '組織',