refactor(测试计划): 测试计划列表查询

This commit is contained in:
WangXu10 2024-04-29 15:14:54 +08:00 committed by 刘瑞斌
parent 03bbdbf15e
commit 2ff25735da
16 changed files with 347 additions and 128 deletions

View File

@ -27,8 +27,10 @@ public class TestPlanConfig implements Serializable {
@NotNull(message = "{test_plan_config.pass_threshold.not_blank}", groups = {Created.class}) @NotNull(message = "{test_plan_config.pass_threshold.not_blank}", groups = {Created.class})
private Double passThreshold; private Double passThreshold;
@Schema(description = "运行模式") @Schema(description = "是否开启测试规划", requiredMode = Schema.RequiredMode.REQUIRED)
private String runModeConfig; @NotBlank(message = "{test_plan_config.test_planning.not_blank}", groups = {Created.class})
@Size(min = 1, max = 1, message = "{test_plan_config.test_planning.length_range}", groups = {Created.class, Updated.class})
private Boolean testPlanning;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -37,7 +39,7 @@ public class TestPlanConfig implements Serializable {
automaticStatusUpdate("automatic_status_update", "automaticStatusUpdate", "BIT", false), automaticStatusUpdate("automatic_status_update", "automaticStatusUpdate", "BIT", false),
repeatCase("repeat_case", "repeatCase", "BIT", false), repeatCase("repeat_case", "repeatCase", "BIT", false),
passThreshold("pass_threshold", "passThreshold", "DOUBLE", false), passThreshold("pass_threshold", "passThreshold", "DOUBLE", false),
runModeConfig("run_mode_config", "runModeConfig", "LONGVARCHAR", false); testPlanning("test_planning", "testPlanning", "BIT", false);
private static final String BEGINNING_DELIMITER = "`"; private static final String BEGINNING_DELIMITER = "`";

View File

@ -353,6 +353,66 @@ public class TestPlanConfigExample {
addCriterion("pass_threshold not between", value1, value2, "passThreshold"); addCriterion("pass_threshold not between", value1, value2, "passThreshold");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestPlanningIsNull() {
addCriterion("test_planning is null");
return (Criteria) this;
}
public Criteria andTestPlanningIsNotNull() {
addCriterion("test_planning is not null");
return (Criteria) this;
}
public Criteria andTestPlanningEqualTo(Boolean value) {
addCriterion("test_planning =", value, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningNotEqualTo(Boolean value) {
addCriterion("test_planning <>", value, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningGreaterThan(Boolean value) {
addCriterion("test_planning >", value, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningGreaterThanOrEqualTo(Boolean value) {
addCriterion("test_planning >=", value, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningLessThan(Boolean value) {
addCriterion("test_planning <", value, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningLessThanOrEqualTo(Boolean value) {
addCriterion("test_planning <=", value, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningIn(List<Boolean> values) {
addCriterion("test_planning in", values, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningNotIn(List<Boolean> values) {
addCriterion("test_planning not in", values, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningBetween(Boolean value1, Boolean value2) {
addCriterion("test_planning between", value1, value2, "testPlanning");
return (Criteria) this;
}
public Criteria andTestPlanningNotBetween(Boolean value1, Boolean value2) {
addCriterion("test_planning not between", value1, value2, "testPlanning");
return (Criteria) this;
}
} }
public static class Criteria extends GeneratedCriteria { public static class Criteria extends GeneratedCriteria {

View File

@ -16,22 +16,16 @@ public interface TestPlanConfigMapper {
int insertSelective(TestPlanConfig record); int insertSelective(TestPlanConfig record);
List<TestPlanConfig> selectByExampleWithBLOBs(TestPlanConfigExample example);
List<TestPlanConfig> selectByExample(TestPlanConfigExample example); List<TestPlanConfig> selectByExample(TestPlanConfigExample example);
TestPlanConfig selectByPrimaryKey(String testPlanId); TestPlanConfig selectByPrimaryKey(String testPlanId);
int updateByExampleSelective(@Param("record") TestPlanConfig record, @Param("example") TestPlanConfigExample example); int updateByExampleSelective(@Param("record") TestPlanConfig record, @Param("example") TestPlanConfigExample example);
int updateByExampleWithBLOBs(@Param("record") TestPlanConfig record, @Param("example") TestPlanConfigExample example);
int updateByExample(@Param("record") TestPlanConfig record, @Param("example") TestPlanConfigExample example); int updateByExample(@Param("record") TestPlanConfig record, @Param("example") TestPlanConfigExample example);
int updateByPrimaryKeySelective(TestPlanConfig record); int updateByPrimaryKeySelective(TestPlanConfig record);
int updateByPrimaryKeyWithBLOBs(TestPlanConfig record);
int updateByPrimaryKey(TestPlanConfig record); int updateByPrimaryKey(TestPlanConfig record);
int batchInsert(@Param("list") List<TestPlanConfig> list); int batchInsert(@Param("list") List<TestPlanConfig> list);

View File

@ -6,9 +6,7 @@
<result column="automatic_status_update" jdbcType="BIT" property="automaticStatusUpdate" /> <result column="automatic_status_update" jdbcType="BIT" property="automaticStatusUpdate" />
<result column="repeat_case" jdbcType="BIT" property="repeatCase" /> <result column="repeat_case" jdbcType="BIT" property="repeatCase" />
<result column="pass_threshold" jdbcType="DOUBLE" property="passThreshold" /> <result column="pass_threshold" jdbcType="DOUBLE" property="passThreshold" />
</resultMap> <result column="test_planning" jdbcType="BIT" property="testPlanning" />
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.plan.domain.TestPlanConfig">
<result column="run_mode_config" jdbcType="LONGVARCHAR" property="runModeConfig" />
</resultMap> </resultMap>
<sql id="Example_Where_Clause"> <sql id="Example_Where_Clause">
<where> <where>
@ -69,27 +67,8 @@
</where> </where>
</sql> </sql>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
test_plan_id, automatic_status_update, repeat_case, pass_threshold test_plan_id, automatic_status_update, repeat_case, pass_threshold, test_planning
</sql> </sql>
<sql id="Blob_Column_List">
run_mode_config
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.plan.domain.TestPlanConfigExample" resultMap="ResultMapWithBLOBs">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from test_plan_config
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanConfigExample" resultMap="BaseResultMap"> <select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanConfigExample" resultMap="BaseResultMap">
select select
<if test="distinct"> <if test="distinct">
@ -104,11 +83,9 @@
order by ${orderByClause} order by ${orderByClause}
</if> </if>
</select> </select>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs"> <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
select select
<include refid="Base_Column_List" /> <include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from test_plan_config from test_plan_config
where test_plan_id = #{testPlanId,jdbcType=VARCHAR} where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
</select> </select>
@ -124,9 +101,9 @@
</delete> </delete>
<insert id="insert" parameterType="io.metersphere.plan.domain.TestPlanConfig"> <insert id="insert" parameterType="io.metersphere.plan.domain.TestPlanConfig">
insert into test_plan_config (test_plan_id, automatic_status_update, repeat_case, insert into test_plan_config (test_plan_id, automatic_status_update, repeat_case,
pass_threshold, run_mode_config) pass_threshold, test_planning)
values (#{testPlanId,jdbcType=VARCHAR}, #{automaticStatusUpdate,jdbcType=BIT}, #{repeatCase,jdbcType=BIT}, values (#{testPlanId,jdbcType=VARCHAR}, #{automaticStatusUpdate,jdbcType=BIT}, #{repeatCase,jdbcType=BIT},
#{passThreshold,jdbcType=DOUBLE}, #{runModeConfig,jdbcType=LONGVARCHAR}) #{passThreshold,jdbcType=DOUBLE}, #{testPlanning,jdbcType=BIT})
</insert> </insert>
<insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanConfig"> <insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanConfig">
insert into test_plan_config insert into test_plan_config
@ -143,8 +120,8 @@
<if test="passThreshold != null"> <if test="passThreshold != null">
pass_threshold, pass_threshold,
</if> </if>
<if test="runModeConfig != null"> <if test="testPlanning != null">
run_mode_config, test_planning,
</if> </if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
@ -160,8 +137,8 @@
<if test="passThreshold != null"> <if test="passThreshold != null">
#{passThreshold,jdbcType=DOUBLE}, #{passThreshold,jdbcType=DOUBLE},
</if> </if>
<if test="runModeConfig != null"> <if test="testPlanning != null">
#{runModeConfig,jdbcType=LONGVARCHAR}, #{testPlanning,jdbcType=BIT},
</if> </if>
</trim> </trim>
</insert> </insert>
@ -186,31 +163,21 @@
<if test="record.passThreshold != null"> <if test="record.passThreshold != null">
pass_threshold = #{record.passThreshold,jdbcType=DOUBLE}, pass_threshold = #{record.passThreshold,jdbcType=DOUBLE},
</if> </if>
<if test="record.runModeConfig != null"> <if test="record.testPlanning != null">
run_mode_config = #{record.runModeConfig,jdbcType=LONGVARCHAR}, test_planning = #{record.testPlanning,jdbcType=BIT},
</if> </if>
</set> </set>
<if test="_parameter != null"> <if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" /> <include refid="Update_By_Example_Where_Clause" />
</if> </if>
</update> </update>
<update id="updateByExampleWithBLOBs" parameterType="map">
update test_plan_config
set test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
automatic_status_update = #{record.automaticStatusUpdate,jdbcType=BIT},
repeat_case = #{record.repeatCase,jdbcType=BIT},
pass_threshold = #{record.passThreshold,jdbcType=DOUBLE},
run_mode_config = #{record.runModeConfig,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map"> <update id="updateByExample" parameterType="map">
update test_plan_config update test_plan_config
set test_plan_id = #{record.testPlanId,jdbcType=VARCHAR}, set test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
automatic_status_update = #{record.automaticStatusUpdate,jdbcType=BIT}, automatic_status_update = #{record.automaticStatusUpdate,jdbcType=BIT},
repeat_case = #{record.repeatCase,jdbcType=BIT}, repeat_case = #{record.repeatCase,jdbcType=BIT},
pass_threshold = #{record.passThreshold,jdbcType=DOUBLE} pass_threshold = #{record.passThreshold,jdbcType=DOUBLE},
test_planning = #{record.testPlanning,jdbcType=BIT}
<if test="_parameter != null"> <if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" /> <include refid="Update_By_Example_Where_Clause" />
</if> </if>
@ -227,35 +194,28 @@
<if test="passThreshold != null"> <if test="passThreshold != null">
pass_threshold = #{passThreshold,jdbcType=DOUBLE}, pass_threshold = #{passThreshold,jdbcType=DOUBLE},
</if> </if>
<if test="runModeConfig != null"> <if test="testPlanning != null">
run_mode_config = #{runModeConfig,jdbcType=LONGVARCHAR}, test_planning = #{testPlanning,jdbcType=BIT},
</if> </if>
</set> </set>
where test_plan_id = #{testPlanId,jdbcType=VARCHAR} where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
</update> </update>
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.plan.domain.TestPlanConfig">
update test_plan_config
set automatic_status_update = #{automaticStatusUpdate,jdbcType=BIT},
repeat_case = #{repeatCase,jdbcType=BIT},
pass_threshold = #{passThreshold,jdbcType=DOUBLE},
run_mode_config = #{runModeConfig,jdbcType=LONGVARCHAR}
where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.plan.domain.TestPlanConfig"> <update id="updateByPrimaryKey" parameterType="io.metersphere.plan.domain.TestPlanConfig">
update test_plan_config update test_plan_config
set automatic_status_update = #{automaticStatusUpdate,jdbcType=BIT}, set automatic_status_update = #{automaticStatusUpdate,jdbcType=BIT},
repeat_case = #{repeatCase,jdbcType=BIT}, repeat_case = #{repeatCase,jdbcType=BIT},
pass_threshold = #{passThreshold,jdbcType=DOUBLE} pass_threshold = #{passThreshold,jdbcType=DOUBLE},
test_planning = #{testPlanning,jdbcType=BIT}
where test_plan_id = #{testPlanId,jdbcType=VARCHAR} where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
</update> </update>
<insert id="batchInsert" parameterType="map"> <insert id="batchInsert" parameterType="map">
insert into test_plan_config insert into test_plan_config
(test_plan_id, automatic_status_update, repeat_case, pass_threshold, run_mode_config (test_plan_id, automatic_status_update, repeat_case, pass_threshold, test_planning
) )
values values
<foreach collection="list" item="item" separator=","> <foreach collection="list" item="item" separator=",">
(#{item.testPlanId,jdbcType=VARCHAR}, #{item.automaticStatusUpdate,jdbcType=BIT}, (#{item.testPlanId,jdbcType=VARCHAR}, #{item.automaticStatusUpdate,jdbcType=BIT},
#{item.repeatCase,jdbcType=BIT}, #{item.passThreshold,jdbcType=DOUBLE}, #{item.runModeConfig,jdbcType=LONGVARCHAR} #{item.repeatCase,jdbcType=BIT}, #{item.passThreshold,jdbcType=DOUBLE}, #{item.testPlanning,jdbcType=BIT}
) )
</foreach> </foreach>
</insert> </insert>
@ -281,8 +241,8 @@
<if test="'pass_threshold'.toString() == column.value"> <if test="'pass_threshold'.toString() == column.value">
#{item.passThreshold,jdbcType=DOUBLE} #{item.passThreshold,jdbcType=DOUBLE}
</if> </if>
<if test="'run_mode_config'.toString() == column.value"> <if test="'test_planning'.toString() == column.value">
#{item.runModeConfig,jdbcType=LONGVARCHAR} #{item.testPlanning,jdbcType=BIT}
</if> </if>
</foreach> </foreach>
) )

View File

@ -8,6 +8,11 @@ ALTER TABLE api_definition_mock ADD COLUMN status_code INT(50) ;
CREATE INDEX idx_scene ON custom_field (scene); CREATE INDEX idx_scene ON custom_field (scene);
CREATE INDEX idx_internal ON custom_field (internal); CREATE INDEX idx_internal ON custom_field (internal);
CREATE INDEX idx_num ON test_plan(num);
ALTER TABLE test_plan_config DROP COLUMN run_mode_config;
ALTER TABLE test_plan_config ADD COLUMN test_planning BIT NOT NULL DEFAULT 0 COMMENT '是否开启测试规划';
-- set innodb lock wait timeout to default -- set innodb lock wait timeout to default
SET SESSION innodb_lock_wait_timeout = DEFAULT; SET SESSION innodb_lock_wait_timeout = DEFAULT;

View File

@ -94,3 +94,4 @@ log.test_plan.update=Update resources
log.test_plan.functional_case=Functional case log.test_plan.functional_case=Functional case
log.test_plan.api_case=Api case log.test_plan.api_case=Api case
log.test_plan.api_scenario=Api scenario log.test_plan.api_scenario=Api scenario
test_plan.type.not_blank=Test plan type cannot be empty

View File

@ -94,3 +94,4 @@ log.test_plan.update=修改了资源
log.test_plan.functional_case=功能用例 log.test_plan.functional_case=功能用例
log.test_plan.api_case=接口用例 log.test_plan.api_case=接口用例
log.test_plan.api_scenario=接口场景 log.test_plan.api_scenario=接口场景
test_plan.type.not_blank=测试计划类型不能为空

View File

@ -94,3 +94,4 @@ log.test_plan.update=修改了資源
log.test_plan.functional_case=功能用例 log.test_plan.functional_case=功能用例
log.test_plan.api_case=接口用例 log.test_plan.api_case=接口用例
log.test_plan.api_scenario=接口場景 log.test_plan.api_scenario=接口場景
test_plan.type.not_blank=測試計劃類型不能為空

View File

@ -51,6 +51,9 @@ public class TestPlanCreateRequest {
@Schema(description = "描述") @Schema(description = "描述")
private String description; private String description;
@Schema(description = "是否开启测试规划", requiredMode = Schema.RequiredMode.REQUIRED)
private boolean testPlanning;
@Schema(description = "是否自定更新功能用例状态", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "是否自定更新功能用例状态", requiredMode = Schema.RequiredMode.REQUIRED)
private boolean automaticStatusUpdate; private boolean automaticStatusUpdate;
@ -61,7 +64,7 @@ public class TestPlanCreateRequest {
@Max(value = 100, message = "{test_plan.pass_threshold.max}") @Max(value = 100, message = "{test_plan.pass_threshold.max}")
@Min(value = 0) @Min(value = 0)
private double passThreshold = 100; private double passThreshold = 100;
@Schema(description = "测试计划类型") @Schema(description = "测试计划类型",allowableValues ={"TEST_PLAN", "GROUP"}, requiredMode = Schema.RequiredMode.REQUIRED )
private String type = TestPlanConstants.TEST_PLAN_TYPE_PLAN; private String type = TestPlanConstants.TEST_PLAN_TYPE_PLAN;
public List<String> getTags() { public List<String> getTags() {

View File

@ -5,7 +5,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.List; import java.util.List;
@ -17,18 +16,13 @@ public class TestPlanTableRequest extends BasePageRequest {
private List<String> moduleIds; private List<String> moduleIds;
@Schema(description = "项目ID") @Schema(description = "项目ID")
@NotBlank(message = "{id must not be blank}") @NotBlank(message = "{test_plan.project_id.not_blank}")
private String projectId; private String projectId;
public TestPlanTableRequest() { @Schema(description = "类型", allowableValues = {"ALL", "TEST_PLAN", "GROUP"}, requiredMode = Schema.RequiredMode.REQUIRED)
this.setCurrent(1); @NotBlank(message = "{test_plan.type.not_blank}")
this.setPageSize(5); private String type;
}
//没有查询条件
public boolean conditionIsEmpty() {
return StringUtils.isEmpty(this.getKeyword()) && MapUtils.isEmpty(this.getFilter()) && MapUtils.isEmpty(this.getCombine());
}
public String getSortString() { public String getSortString() {
if (StringUtils.isEmpty(super.getSortString())) { if (StringUtils.isEmpty(super.getSortString())) {

View File

@ -33,7 +33,9 @@ public class TestPlanResponse {
private String moduleId; private String moduleId;
@Schema(description = "测试计划组内的测试计划") @Schema(description = "测试计划组内的测试计划")
List<TestPlanResponse> children; List<TestPlanResponse> children;
@Schema(description = "组内计划数量")
private Integer childrenCount;
@Schema(description = "测试计划组Id") @Schema(description = "测试计划组Id")
private String testPlanGroupId; private String groupId;
} }

View File

@ -2,6 +2,7 @@ package io.metersphere.plan.mapper;
import io.metersphere.plan.domain.TestPlan; import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.dto.TestPlanQueryConditions; import io.metersphere.plan.dto.TestPlanQueryConditions;
import io.metersphere.plan.dto.request.TestPlanTableRequest;
import io.metersphere.plan.dto.response.TestPlanResponse; import io.metersphere.plan.dto.response.TestPlanResponse;
import io.metersphere.project.dto.ModuleCountDTO; import io.metersphere.project.dto.ModuleCountDTO;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
@ -13,7 +14,7 @@ public interface ExtTestPlanMapper {
List<String> selectByGroupIdList(@Param("list") List<String> parentTestPlanId); List<String> selectByGroupIdList(@Param("list") List<String> parentTestPlanId);
List<TestPlanResponse> selectByConditions(TestPlanQueryConditions testPlanQueryConditions); List<TestPlanResponse> selectByConditions(@Param("request") TestPlanTableRequest request,@Param("groupIds") List<String> groupIds);
List<String> selectIdByConditions(TestPlanQueryConditions testPlanQueryConditions); List<String> selectIdByConditions(TestPlanQueryConditions testPlanQueryConditions);

View File

@ -11,6 +11,7 @@
<result column="create_user" jdbcType="VARCHAR" property="createUser"/> <result column="create_user" jdbcType="VARCHAR" property="createUser"/>
<result column="create_time" jdbcType="BIGINT" property="createTime"/> <result column="create_time" jdbcType="BIGINT" property="createTime"/>
<result column="status" jdbcType="VARCHAR" property="status"/> <result column="status" jdbcType="VARCHAR" property="status"/>
<result column="group_id" jdbcType="VARCHAR" property="groupId"/>
</resultMap> </resultMap>
<update id="updateDefaultGroupId"> <update id="updateDefaultGroupId">
@ -33,10 +34,9 @@
</select> </select>
<select id="selectByConditions" <select id="selectByConditions"
parameterType="io.metersphere.plan.dto.TestPlanQueryConditions"
resultMap="testPlanBaseInfo"> resultMap="testPlanBaseInfo">
SELECT SELECT
t.id,t.num,t.name,t.status, t.id,t.num,t.name,t.status,t.group_id,
createUser.name AS createUser, createUser.name AS createUser,
t.create_time, t.create_time,
t.module_id, t.module_id,
@ -44,9 +44,192 @@
t.tags t.tags
FROM test_plan t FROM test_plan t
INNER JOIN user createUser ON t.create_user = createUser.id INNER JOIN user createUser ON t.create_user = createUser.id
<include refid="test_plan_page_request"/> WHERE t.project_id = #{request.projectId}
<if test="groupIds != null and groupIds.size() > 0">
and t.group_id IN
<foreach collection="groupIds" item="groupId" separator="," open="(" close=")">
#{groupId}
</foreach>
</if>
<include refid="queryWhereCondition"/>
</select> </select>
<sql id="queryWhereCondition">
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and t.module_id in
<foreach collection="request.moduleIds" item="moduleId" separator="," open="(" close=")">
#{moduleId}
</foreach>
</if>
<if test="request.keyword != null and request.keyword != ''">
and (
t.name like concat('%', #{request.keyword},'%')
or t.num like concat('%', #{request.keyword},'%')
or t.tags like concat('%', #{request.keyword}, '%')
)
</if>
<if test="request.type != null and request.type != ''">
<choose>
<when test="request.type == 'ALL'">
and t.group_id = 'NONE'
</when>
<when test="request.type == 'TEST_PLAN'">
and t.group_id = 'NONE'
and t.type = 'TEST_PLAN'
</when>
<when test="request.type == 'GROUP'">
and t.group_id = 'NONE'
and t.type = 'GTOUP'
</when>
</choose>
</if>
<include refid="filters">
<property name="filter" value="request.filter"/>
</include>
<choose>
<when test='request.searchMode == "AND"'>
AND <include refid="queryCombine"/>
</when>
<when test='request.searchMode == "OR"'>
and (
<include refid="queryCombine"/>
)
</when>
</choose>
</sql>
<sql id="filters">
<if test="${filter} != null and ${filter}.size() > 0">
<foreach collection="${filter}.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<!-- 状态 -->
<when test="key=='status'">
and t.status in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
</choose>
</if>
</foreach>
</if>
</sql>
<sql id="queryCombine">
<if test="request.combine != null">
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="searchMode" value="request.searchMode"/>
</include>
</if>
1=1
</sql>
<sql id="combine">
<!-- 名称 -->
<if test='${condition}.name != null'>
t.name
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.name"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- id -->
<if test='${condition}.id != null'>
t.num
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.id"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 所属模块 -->
<if test='${condition}.moduleId != null'>
t.moduleId
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.moduleId"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 创建人 -->
<if test='${condition}.createUser != null'>
t.create_user
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createUser"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 创建时间 -->
<if test='${condition}.createTime != null'>
t.create_time
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createTime"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 标签 -->
<if test='${condition}.tags != null'>
<include refid="queryTag">
<property name="searchMode" value="${searchMode}"/>
<property name="combineTag" value="${condition}.tags"/>
</include>
</if>
</sql>
<sql id="queryType">
<choose>
<when test='${searchMode} == "AND"'>
AND
</when>
<when test='${searchMode} == "OR"'>
OR
</when>
</choose>
</sql>
<sql id="queryTag">
<!-- 不包含 -->
<if test='${combineTag}.value.size() > 0 and ${combineTag}.operator == "not like"'>
(
t.tags is null or t.tags = '[]' or
<foreach collection="${combineTag}.value" item="tag" separator="and" open="(" close=")">
!JSON_CONTAINS(t.tags, JSON_ARRAY(#{tag}))
</foreach>
)
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 包含 -->
<if test='${combineTag}.value.size() > 0 and ${combineTag}.operator == "like"'>
<foreach collection="${combineTag}.value" item="tag" separator="or" open="(" close=")">
JSON_CONTAINS(t.tags, JSON_ARRAY(#{tag}))
</foreach>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!---->
<if test='${combineTag}.operator == "is null"'>
(t.tags is null or t.tags = '[]')
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
</sql>
<select id="countModuleIdByConditions" <select id="countModuleIdByConditions"
parameterType="io.metersphere.plan.dto.TestPlanQueryConditions" parameterType="io.metersphere.plan.dto.TestPlanQueryConditions"
resultType="io.metersphere.project.dto.ModuleCountDTO"> resultType="io.metersphere.project.dto.ModuleCountDTO">

View File

@ -15,17 +15,17 @@ import io.metersphere.sdk.constants.TestPlanConstants;
import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.service.CommonProjectService;
import io.metersphere.system.utils.PageUtils; import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager; import io.metersphere.system.utils.Pager;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
@Service @Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -37,8 +37,6 @@ public class TestPlanManagementService {
@Resource @Resource
private ExtTestPlanModuleMapper extTestPlanModuleMapper; private ExtTestPlanModuleMapper extTestPlanModuleMapper;
@Resource @Resource
private CommonProjectService commonProjectService;
@Resource
private TestPlanModuleService testPlanModuleService; private TestPlanModuleService testPlanModuleService;
public Map<String, Long> moduleCount(TestPlanTableRequest request) { public Map<String, Long> moduleCount(TestPlanTableRequest request) {
@ -49,51 +47,54 @@ public class TestPlanManagementService {
return moduleCountMap; return moduleCountMap;
} }
public Pager<List<TestPlanResponse>> page(TestPlanTableRequest request) {
TestPlanQueryConditions queryConditions = this.generateTestPlanConditions(request);
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "t.update_time desc");
return PageUtils.setPageInfo(page, this.getTableList(queryConditions));
}
/** /**
* 生成查询条件 * 测试计划列表查询
* *
* @param request 前端传来的筛选条件 * @param request
* @return * @return
*/ */
private TestPlanQueryConditions generateTestPlanConditions(TestPlanTableRequest request) { public Pager<List<TestPlanResponse>> page(TestPlanTableRequest request) {
TestPlanQueryConditions conditions = new TestPlanQueryConditions(request.getModuleIds(), request.getProjectId(), request); Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
if (!request.conditionIsEmpty()) { StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "t.update_time desc");
//查询符合匹配的子节点时不需要传入groupId return PageUtils.setPageInfo(page, this.getTableList(request));
conditions.setGroupId(null);
List<String> includeGroupIds = extTestPlanMapper.selectGroupIdByConditions(conditions);
conditions.setIncludeIds(includeGroupIds);
}
return conditions;
} }
private List<TestPlanResponse> getTableList(TestPlanQueryConditions request) { private List<TestPlanResponse> getTableList(TestPlanTableRequest request) {
List<TestPlanResponse> testPlanResponses = extTestPlanMapper.selectByConditions(request); List<TestPlanResponse> testPlanResponses = extTestPlanMapper.selectByConditions(request, null);
testPlanResponses.forEach(item -> { handChildren(testPlanResponses,request.getProjectId());
if (StringUtils.equals(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
TestPlanQueryConditions childrenCondition = new TestPlanQueryConditions();
childrenCondition.setProjectId(request.getProjectId());
childrenCondition.setGroupId(item.getId());
item.setChildren(extTestPlanMapper.selectByConditions(childrenCondition));
}
this.initTestPlanResponse(item);
});
return testPlanResponses; return testPlanResponses;
} }
private void initTestPlanResponse(TestPlanResponse testPlanResponse) { /**
testPlanResponse.setModuleName(testPlanModuleService.getNameById(testPlanResponse.getModuleId())); * 计划组子节点
//todo 定时任务相关信息处理 *
* @param testPlanResponses
*/
private void handChildren(List<TestPlanResponse> testPlanResponses,String projectId) {
List<String> groupIds = testPlanResponses.stream().filter(item -> StringUtils.equals(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)).map(TestPlanResponse::getId).toList();
TestPlanTableRequest request = new TestPlanTableRequest();
request.setProjectId(projectId);
List<TestPlanResponse> childrenList = extTestPlanMapper.selectByConditions(request, groupIds);
Map<String, List<TestPlanResponse>> collect = childrenList.stream().collect(Collectors.groupingBy(TestPlanResponse::getGroupId));
testPlanResponses.forEach(item -> {
if (collect.containsKey(item.getId())) {
//存在子节点
List<TestPlanResponse> list = collect.get(item.getId());
calculateData(list);
item.setChildren(list);
item.setChildrenCount(list.size());
}
calculateData(Arrays.asList(item));
});
}
if (CollectionUtils.isNotEmpty(testPlanResponse.getChildren())) { /**
testPlanResponse.getChildren().forEach(this::initTestPlanResponse); * 计算各种指标
} *
* @param list
*/
private void calculateData(List<TestPlanResponse> list) {
//TODO 查询计划下面关联的用例数量用于各种计算 什么通过率 进度 用例数
} }
public void checkModuleIsOpen(String resourceId, String resourceType, List<String> moduleMenus) { public void checkModuleIsOpen(String resourceId, String resourceType, List<String> moduleMenus) {

View File

@ -94,6 +94,7 @@ public class TestPlanService {
testPlanConfig.setAutomaticStatusUpdate(testPlanCreateRequest.isAutomaticStatusUpdate()); testPlanConfig.setAutomaticStatusUpdate(testPlanCreateRequest.isAutomaticStatusUpdate());
testPlanConfig.setRepeatCase(testPlanCreateRequest.isRepeatCase()); testPlanConfig.setRepeatCase(testPlanCreateRequest.isRepeatCase());
testPlanConfig.setPassThreshold(testPlanCreateRequest.getPassThreshold()); testPlanConfig.setPassThreshold(testPlanCreateRequest.getPassThreshold());
testPlanConfig.setTestPlanning(testPlanCreateRequest.isTestPlanning());
if (testPlanCreateRequest.isGroupOption()) { if (testPlanCreateRequest.isGroupOption()) {
testPlanXPackFactory.getTestPlanGroupService().validateGroup(createTestPlan, testPlanConfig); testPlanXPackFactory.getTestPlanGroupService().validateGroup(createTestPlan, testPlanConfig);

View File

@ -178,6 +178,9 @@ public class TestPlanTests extends BaseTest {
//查询测试计划列表 //查询测试计划列表
TestPlanTableRequest testPlanTableRequest = new TestPlanTableRequest(); TestPlanTableRequest testPlanTableRequest = new TestPlanTableRequest();
testPlanTableRequest.setProjectId(project.getId()); testPlanTableRequest.setProjectId(project.getId());
testPlanTableRequest.setCurrent(1);
testPlanTableRequest.setPageSize(10);
testPlanTableRequest.setType("ALL");
//先测试一下没有开启模块时接口能否使用 //先测试一下没有开启模块时接口能否使用
testPlanTestService.removeProjectModule(project, PROJECT_MODULE, "testPlan"); testPlanTestService.removeProjectModule(project, PROJECT_MODULE, "testPlan");
@ -504,6 +507,7 @@ public class TestPlanTests extends BaseTest {
assert a1Node != null & a2Node != null & a3Node != null & a1a1Node != null & a1b1Node != null; assert a1Node != null & a2Node != null & a3Node != null & a1a1Node != null & a1b1Node != null;
TestPlanCreateRequest request = new TestPlanCreateRequest(); TestPlanCreateRequest request = new TestPlanCreateRequest();
request.setProjectId(project.getId()); request.setProjectId(project.getId());
request.setTestPlanning(false);
for (int i = 0; i < 999; i++) { for (int i = 0; i < 999; i++) {
String moduleId; String moduleId;
@ -650,6 +654,9 @@ public class TestPlanTests extends BaseTest {
public void testPlanPageCountTest() throws Exception { public void testPlanPageCountTest() throws Exception {
TestPlanTableRequest testPlanTableRequest = new TestPlanTableRequest(); TestPlanTableRequest testPlanTableRequest = new TestPlanTableRequest();
testPlanTableRequest.setProjectId(project.getId()); testPlanTableRequest.setProjectId(project.getId());
testPlanTableRequest.setType("ALL");
testPlanTableRequest.setPageSize(10);
testPlanTableRequest.setCurrent(1);
//测试项目没有开启测试计划模块时能否使用 //测试项目没有开启测试计划模块时能否使用
testPlanTestService.removeProjectModule(project, PROJECT_MODULE, "testPlan"); testPlanTestService.removeProjectModule(project, PROJECT_MODULE, "testPlan");
@ -934,6 +941,9 @@ public class TestPlanTests extends BaseTest {
//因为有条数据被移动了测试计划组里所以检查一下moduleCount. //因为有条数据被移动了测试计划组里所以检查一下moduleCount.
TestPlanTableRequest testPlanTableRequest = new TestPlanTableRequest(); TestPlanTableRequest testPlanTableRequest = new TestPlanTableRequest();
testPlanTableRequest.setProjectId(project.getId()); testPlanTableRequest.setProjectId(project.getId());
testPlanTableRequest.setCurrent(1);
testPlanTableRequest.setPageSize(10);
testPlanTableRequest.setType("ALL");
MvcResult moduleCountResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_MODULE_COUNT, testPlanTableRequest); MvcResult moduleCountResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_MODULE_COUNT, testPlanTableRequest);
String moduleCountReturnData = moduleCountResult.getResponse().getContentAsString(StandardCharsets.UTF_8); String moduleCountReturnData = moduleCountResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
Map<String, Object> moduleCountMap = JSON.parseObject(JSON.toJSONString(JSON.parseObject(moduleCountReturnData, ResultHolder.class).getData()), Map.class); Map<String, Object> moduleCountMap = JSON.parseObject(JSON.toJSONString(JSON.parseObject(moduleCountReturnData, ResultHolder.class).getData()), Map.class);