feat(测试计划): 获取已关联接口用例列表

This commit is contained in:
WangXu10 2024-06-04 11:43:52 +08:00 committed by 刘瑞斌
parent d4b3c16681
commit 3ee5bd00a8
16 changed files with 595 additions and 43 deletions

View File

@ -44,7 +44,7 @@ public class TestPlanApiCase implements Serializable {
@Schema(description = "创建人")
private String createUser;
@Schema(description = "自定义排序,间隔5000", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(description = "自定义排序,间隔为2的n次幂", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{test_plan_api_case.pos.not_blank}", groups = {Created.class})
private Long pos;
@ -53,6 +53,9 @@ public class TestPlanApiCase implements Serializable {
@Size(min = 1, max = 50, message = "{test_plan_api_case.test_plan_collection_id.length_range}", groups = {Created.class, Updated.class})
private String testPlanCollectionId;
@Schema(description = "最后执行时间")
private Long lastExecTime;
@Schema(description = "所属环境")
private String environmentId;
@ -69,6 +72,7 @@ public class TestPlanApiCase implements Serializable {
createUser("create_user", "createUser", "VARCHAR", false),
pos("pos", "pos", "BIGINT", false),
testPlanCollectionId("test_plan_collection_id", "testPlanCollectionId", "VARCHAR", false),
lastExecTime("last_exec_time", "lastExecTime", "BIGINT", false),
environmentId("environment_id", "environmentId", "LONGVARCHAR", false);
private static final String BEGINNING_DELIMITER = "`";

View File

@ -783,6 +783,66 @@ public class TestPlanApiCaseExample {
addCriterion("test_plan_collection_id not between", value1, value2, "testPlanCollectionId");
return (Criteria) this;
}
public Criteria andLastExecTimeIsNull() {
addCriterion("last_exec_time is null");
return (Criteria) this;
}
public Criteria andLastExecTimeIsNotNull() {
addCriterion("last_exec_time is not null");
return (Criteria) this;
}
public Criteria andLastExecTimeEqualTo(Long value) {
addCriterion("last_exec_time =", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeNotEqualTo(Long value) {
addCriterion("last_exec_time <>", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeGreaterThan(Long value) {
addCriterion("last_exec_time >", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeGreaterThanOrEqualTo(Long value) {
addCriterion("last_exec_time >=", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeLessThan(Long value) {
addCriterion("last_exec_time <", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeLessThanOrEqualTo(Long value) {
addCriterion("last_exec_time <=", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeIn(List<Long> values) {
addCriterion("last_exec_time in", values, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeNotIn(List<Long> values) {
addCriterion("last_exec_time not in", values, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeBetween(Long value1, Long value2) {
addCriterion("last_exec_time between", value1, value2, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeNotBetween(Long value1, Long value2) {
addCriterion("last_exec_time not between", value1, value2, "lastExecTime");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -57,6 +57,9 @@ public class TestPlanApiScenario implements Serializable {
@Schema(description = "是否为环境组")
private Boolean grouped;
@Schema(description = "最后执行时间")
private Long lastExecTime;
private static final long serialVersionUID = 1L;
public enum Column {
@ -71,7 +74,8 @@ public class TestPlanApiScenario implements Serializable {
createUser("create_user", "createUser", "VARCHAR", false),
pos("pos", "pos", "BIGINT", false),
testPlanCollectionId("test_plan_collection_id", "testPlanCollectionId", "VARCHAR", false),
grouped("grouped", "grouped", "BIT", false);
grouped("grouped", "grouped", "BIT", false),
lastExecTime("last_exec_time", "lastExecTime", "BIGINT", false);
private static final String BEGINNING_DELIMITER = "`";

View File

@ -913,6 +913,66 @@ public class TestPlanApiScenarioExample {
addCriterion("grouped not between", value1, value2, "grouped");
return (Criteria) this;
}
public Criteria andLastExecTimeIsNull() {
addCriterion("last_exec_time is null");
return (Criteria) this;
}
public Criteria andLastExecTimeIsNotNull() {
addCriterion("last_exec_time is not null");
return (Criteria) this;
}
public Criteria andLastExecTimeEqualTo(Long value) {
addCriterion("last_exec_time =", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeNotEqualTo(Long value) {
addCriterion("last_exec_time <>", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeGreaterThan(Long value) {
addCriterion("last_exec_time >", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeGreaterThanOrEqualTo(Long value) {
addCriterion("last_exec_time >=", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeLessThan(Long value) {
addCriterion("last_exec_time <", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeLessThanOrEqualTo(Long value) {
addCriterion("last_exec_time <=", value, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeIn(List<Long> values) {
addCriterion("last_exec_time in", values, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeNotIn(List<Long> values) {
addCriterion("last_exec_time not in", values, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeBetween(Long value1, Long value2) {
addCriterion("last_exec_time between", value1, value2, "lastExecTime");
return (Criteria) this;
}
public Criteria andLastExecTimeNotBetween(Long value1, Long value2) {
addCriterion("last_exec_time not between", value1, value2, "lastExecTime");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -12,6 +12,7 @@
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
<result column="pos" jdbcType="BIGINT" property="pos" />
<result column="test_plan_collection_id" jdbcType="VARCHAR" property="testPlanCollectionId" />
<result column="last_exec_time" jdbcType="BIGINT" property="lastExecTime" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.plan.domain.TestPlanApiCase">
<result column="environment_id" jdbcType="LONGVARCHAR" property="environmentId" />
@ -76,7 +77,7 @@
</sql>
<sql id="Base_Column_List">
id, test_plan_id, api_case_id, last_exec_result, last_exec_report_id, execute_user,
create_time, create_user, pos, test_plan_collection_id
create_time, create_user, pos, test_plan_collection_id, last_exec_time
</sql>
<sql id="Blob_Column_List">
environment_id
@ -133,12 +134,12 @@
insert into test_plan_api_case (id, test_plan_id, api_case_id,
last_exec_result, last_exec_report_id, execute_user,
create_time, create_user, pos,
test_plan_collection_id, environment_id
test_plan_collection_id, last_exec_time, environment_id
)
values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{apiCaseId,jdbcType=VARCHAR},
#{lastExecResult,jdbcType=VARCHAR}, #{lastExecReportId,jdbcType=VARCHAR}, #{executeUser,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{createUser,jdbcType=VARCHAR}, #{pos,jdbcType=BIGINT},
#{testPlanCollectionId,jdbcType=VARCHAR}, #{environmentId,jdbcType=LONGVARCHAR}
#{testPlanCollectionId,jdbcType=VARCHAR}, #{lastExecTime,jdbcType=BIGINT}, #{environmentId,jdbcType=LONGVARCHAR}
)
</insert>
<insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanApiCase">
@ -174,6 +175,9 @@
<if test="testPlanCollectionId != null">
test_plan_collection_id,
</if>
<if test="lastExecTime != null">
last_exec_time,
</if>
<if test="environmentId != null">
environment_id,
</if>
@ -209,6 +213,9 @@
<if test="testPlanCollectionId != null">
#{testPlanCollectionId,jdbcType=VARCHAR},
</if>
<if test="lastExecTime != null">
#{lastExecTime,jdbcType=BIGINT},
</if>
<if test="environmentId != null">
#{environmentId,jdbcType=LONGVARCHAR},
</if>
@ -253,6 +260,9 @@
<if test="record.testPlanCollectionId != null">
test_plan_collection_id = #{record.testPlanCollectionId,jdbcType=VARCHAR},
</if>
<if test="record.lastExecTime != null">
last_exec_time = #{record.lastExecTime,jdbcType=BIGINT},
</if>
<if test="record.environmentId != null">
environment_id = #{record.environmentId,jdbcType=LONGVARCHAR},
</if>
@ -273,6 +283,7 @@
create_user = #{record.createUser,jdbcType=VARCHAR},
pos = #{record.pos,jdbcType=BIGINT},
test_plan_collection_id = #{record.testPlanCollectionId,jdbcType=VARCHAR},
last_exec_time = #{record.lastExecTime,jdbcType=BIGINT},
environment_id = #{record.environmentId,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -289,7 +300,8 @@
create_time = #{record.createTime,jdbcType=BIGINT},
create_user = #{record.createUser,jdbcType=VARCHAR},
pos = #{record.pos,jdbcType=BIGINT},
test_plan_collection_id = #{record.testPlanCollectionId,jdbcType=VARCHAR}
test_plan_collection_id = #{record.testPlanCollectionId,jdbcType=VARCHAR},
last_exec_time = #{record.lastExecTime,jdbcType=BIGINT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -324,6 +336,9 @@
<if test="testPlanCollectionId != null">
test_plan_collection_id = #{testPlanCollectionId,jdbcType=VARCHAR},
</if>
<if test="lastExecTime != null">
last_exec_time = #{lastExecTime,jdbcType=BIGINT},
</if>
<if test="environmentId != null">
environment_id = #{environmentId,jdbcType=LONGVARCHAR},
</if>
@ -341,6 +356,7 @@
create_user = #{createUser,jdbcType=VARCHAR},
pos = #{pos,jdbcType=BIGINT},
test_plan_collection_id = #{testPlanCollectionId,jdbcType=VARCHAR},
last_exec_time = #{lastExecTime,jdbcType=BIGINT},
environment_id = #{environmentId,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
@ -354,20 +370,22 @@
create_time = #{createTime,jdbcType=BIGINT},
create_user = #{createUser,jdbcType=VARCHAR},
pos = #{pos,jdbcType=BIGINT},
test_plan_collection_id = #{testPlanCollectionId,jdbcType=VARCHAR}
test_plan_collection_id = #{testPlanCollectionId,jdbcType=VARCHAR},
last_exec_time = #{lastExecTime,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR}
</update>
<insert id="batchInsert" parameterType="map">
insert into test_plan_api_case
(id, test_plan_id, api_case_id, last_exec_result, last_exec_report_id, execute_user,
create_time, create_user, pos, test_plan_collection_id, environment_id)
create_time, create_user, pos, test_plan_collection_id, last_exec_time, environment_id
)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.testPlanId,jdbcType=VARCHAR}, #{item.apiCaseId,jdbcType=VARCHAR},
#{item.lastExecResult,jdbcType=VARCHAR}, #{item.lastExecReportId,jdbcType=VARCHAR},
#{item.executeUser,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.createUser,jdbcType=VARCHAR},
#{item.pos,jdbcType=BIGINT}, #{item.testPlanCollectionId,jdbcType=VARCHAR}, #{item.environmentId,jdbcType=LONGVARCHAR}
)
#{item.pos,jdbcType=BIGINT}, #{item.testPlanCollectionId,jdbcType=VARCHAR}, #{item.lastExecTime,jdbcType=BIGINT},
#{item.environmentId,jdbcType=LONGVARCHAR})
</foreach>
</insert>
<insert id="batchInsertSelective" parameterType="map">
@ -410,6 +428,9 @@
<if test="'test_plan_collection_id'.toString() == column.value">
#{item.testPlanCollectionId,jdbcType=VARCHAR}
</if>
<if test="'last_exec_time'.toString() == column.value">
#{item.lastExecTime,jdbcType=BIGINT}
</if>
<if test="'environment_id'.toString() == column.value">
#{item.environmentId,jdbcType=LONGVARCHAR}
</if>

View File

@ -2,9 +2,8 @@ package io.metersphere.plan.mapper;
import io.metersphere.plan.domain.TestPlanApiScenario;
import io.metersphere.plan.domain.TestPlanApiScenarioExample;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface TestPlanApiScenarioMapper {
long countByExample(TestPlanApiScenarioExample example);

View File

@ -14,6 +14,7 @@
<result column="pos" jdbcType="BIGINT" property="pos" />
<result column="test_plan_collection_id" jdbcType="VARCHAR" property="testPlanCollectionId" />
<result column="grouped" jdbcType="BIT" property="grouped" />
<result column="last_exec_time" jdbcType="BIGINT" property="lastExecTime" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -75,7 +76,8 @@
</sql>
<sql id="Base_Column_List">
id, test_plan_id, api_scenario_id, environment_id, execute_user, last_exec_result,
last_exec_report_id, create_time, create_user, pos, test_plan_collection_id, grouped
last_exec_report_id, create_time, create_user, pos, test_plan_collection_id, grouped,
last_exec_time
</sql>
<select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanApiScenarioExample" resultMap="BaseResultMap">
select
@ -111,13 +113,13 @@
insert into test_plan_api_scenario (id, test_plan_id, api_scenario_id,
environment_id, execute_user, last_exec_result,
last_exec_report_id, create_time, create_user,
pos, test_plan_collection_id, grouped
)
pos, test_plan_collection_id, grouped,
last_exec_time)
values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{apiScenarioId,jdbcType=VARCHAR},
#{environmentId,jdbcType=VARCHAR}, #{executeUser,jdbcType=VARCHAR}, #{lastExecResult,jdbcType=VARCHAR},
#{lastExecReportId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{createUser,jdbcType=VARCHAR},
#{pos,jdbcType=BIGINT}, #{testPlanCollectionId,jdbcType=VARCHAR}, #{grouped,jdbcType=BIT}
)
#{pos,jdbcType=BIGINT}, #{testPlanCollectionId,jdbcType=VARCHAR}, #{grouped,jdbcType=BIT},
#{lastExecTime,jdbcType=BIGINT})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanApiScenario">
insert into test_plan_api_scenario
@ -158,6 +160,9 @@
<if test="grouped != null">
grouped,
</if>
<if test="lastExecTime != null">
last_exec_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -196,6 +201,9 @@
<if test="grouped != null">
#{grouped,jdbcType=BIT},
</if>
<if test="lastExecTime != null">
#{lastExecTime,jdbcType=BIGINT},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.plan.domain.TestPlanApiScenarioExample" resultType="java.lang.Long">
@ -243,6 +251,9 @@
<if test="record.grouped != null">
grouped = #{record.grouped,jdbcType=BIT},
</if>
<if test="record.lastExecTime != null">
last_exec_time = #{record.lastExecTime,jdbcType=BIGINT},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -261,7 +272,8 @@
create_user = #{record.createUser,jdbcType=VARCHAR},
pos = #{record.pos,jdbcType=BIGINT},
test_plan_collection_id = #{record.testPlanCollectionId,jdbcType=VARCHAR},
grouped = #{record.grouped,jdbcType=BIT}
grouped = #{record.grouped,jdbcType=BIT},
last_exec_time = #{record.lastExecTime,jdbcType=BIGINT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -302,6 +314,9 @@
<if test="grouped != null">
grouped = #{grouped,jdbcType=BIT},
</if>
<if test="lastExecTime != null">
last_exec_time = #{lastExecTime,jdbcType=BIGINT},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -317,21 +332,22 @@
create_user = #{createUser,jdbcType=VARCHAR},
pos = #{pos,jdbcType=BIGINT},
test_plan_collection_id = #{testPlanCollectionId,jdbcType=VARCHAR},
grouped = #{grouped,jdbcType=BIT}
grouped = #{grouped,jdbcType=BIT},
last_exec_time = #{lastExecTime,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR}
</update>
<insert id="batchInsert" parameterType="map">
insert into test_plan_api_scenario
(id, test_plan_id, api_scenario_id, environment_id, execute_user, last_exec_result,
last_exec_report_id, create_time, create_user, pos, test_plan_collection_id, grouped
)
last_exec_report_id, create_time, create_user, pos, test_plan_collection_id, grouped,
last_exec_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.testPlanId,jdbcType=VARCHAR}, #{item.apiScenarioId,jdbcType=VARCHAR},
#{item.environmentId,jdbcType=VARCHAR}, #{item.executeUser,jdbcType=VARCHAR}, #{item.lastExecResult,jdbcType=VARCHAR},
#{item.lastExecReportId,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT},
#{item.createUser,jdbcType=VARCHAR}, #{item.pos,jdbcType=BIGINT}, #{item.testPlanCollectionId,jdbcType=VARCHAR},
#{item.grouped,jdbcType=BIT})
#{item.grouped,jdbcType=BIT}, #{item.lastExecTime,jdbcType=BIGINT})
</foreach>
</insert>
<insert id="batchInsertSelective" parameterType="map">
@ -380,6 +396,9 @@
<if test="'grouped'.toString() == column.value">
#{item.grouped,jdbcType=BIT}
</if>
<if test="'last_exec_time'.toString() == column.value">
#{item.lastExecTime,jdbcType=BIGINT}
</if>
</foreach>
)
</foreach>

View File

@ -31,6 +31,7 @@ ALTER TABLE test_plan_report_bug MODIFY `bug_case_count` BIGINT NOT NULL DEFAUL
-- 修改测试计划关联接口表字段
ALTER TABLE test_plan_api_case DROP COLUMN num;
ALTER TABLE test_plan_api_case ADD COLUMN test_plan_collection_id VARCHAR(50) NOT NULL COMMENT '测试计划集id';
ALTER TABLE test_plan_api_case ADD COLUMN last_exec_time BIGINT COMMENT '最后执行时间';
CREATE INDEX idx_test_plan_collection_id ON test_plan_api_case(test_plan_collection_id);
CREATE INDEX idx_pos ON test_plan_api_case(pos);
@ -39,6 +40,7 @@ ALTER TABLE test_plan_api_scenario DROP COLUMN num;
ALTER TABLE test_plan_api_scenario ADD COLUMN test_plan_collection_id VARCHAR(50) NOT NULL COMMENT '测试计划集id';
ALTER TABLE test_plan_api_scenario ADD COLUMN grouped BIT DEFAULT 0 COMMENT '是否为环境组';
ALTER TABLE test_plan_api_scenario MODIFY COLUMN `environment_id` VARCHAR(50) COMMENT '所属环境或环境组id';
ALTER TABLE test_plan_api_scenario ADD COLUMN last_exec_time BIGINT COMMENT '最后执行时间';
CREATE INDEX idx_test_plan_collection_id ON test_plan_api_scenario(test_plan_collection_id);
CREATE INDEX idx_pos ON test_plan_api_scenario(pos);

View File

@ -1,12 +1,43 @@
package io.metersphere.plan.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.plan.dto.request.TestPlanApiCaseRequest;
import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
import io.metersphere.plan.service.TestPlanApiCaseService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Tag(name = "测试计划接口用例")
@RestController
@RequestMapping("/test-plan/api/case")
public class TestPlanApiCaseController {
@Resource
private TestPlanApiCaseService testPlanApiCaseService;
@PostMapping("/page")
@Operation(summary = "测试计划-已关联接口用例列表分页查询")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
public Pager<List<TestPlanApiCasePageResponse>> page(@Validated @RequestBody TestPlanApiCaseRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString("id")) ? request.getSortString("id") : "create_time desc");
return PageUtils.setPageInfo(page, testPlanApiCaseService.HasRelateApiCaseList(request, false));
}
}

View File

@ -0,0 +1,71 @@
package io.metersphere.plan.dto.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author wx
*/
@Data
public class TestPlanApiCasePageResponse implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
private String id;
@Schema(description = "业务ID")
private Long num;
@Schema(description = "接口用例名称")
private String name;
@Schema(description = "用例等级")
private String priority;
@Schema(description = "请求路径")
private String path;
@Schema(description = "项目id")
private String projectId;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "模块ID")
private String moduleId;
@Schema(description = "环境fk")
private String environmentId;
@Schema(description = "环境名称")
private String environmentName;
@Schema(description = "执行结果")
private String lastExecResult;
@Schema(description = "执行人")
private String executeUser;
@Schema(description = "执行人名称")
private String executeUserName;
@Schema(description = "最后执行时间")
private Long lastExecTime;
@Schema(description = "创建人id")
private String createUser;
@Schema(description = "创建人名称")
private String createUserName;
@Schema(description = "测试集id")
private String testPlanCollectionId;
@Schema(description = "计划集环境")
private String collectEnvironmentId;
}

View File

@ -3,7 +3,9 @@ package io.metersphere.plan.mapper;
import io.metersphere.api.dto.definition.ApiDefinitionDTO;
import io.metersphere.plan.dto.ResourceSelectParam;
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
import io.metersphere.plan.dto.request.TestPlanApiCaseRequest;
import io.metersphere.plan.dto.request.TestPlanApiRequest;
import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
import io.metersphere.project.dto.DropNode;
import io.metersphere.project.dto.NodeSortQueryParam;
import org.apache.ibatis.annotations.Param;
@ -27,4 +29,6 @@ public interface ExtTestPlanApiCaseMapper {
List<TestPlanCaseRunResultCount> selectCaseExecResultCount(String testPlanId);
List<ApiDefinitionDTO> list(@Param("request") TestPlanApiRequest request, @Param("isRepeat") boolean isRepeat);
List<TestPlanApiCasePageResponse> relateApiCaseList(@Param("request") TestPlanApiCaseRequest request, @Param("deleted") boolean deleted);
}

View File

@ -395,4 +395,128 @@
</otherwise>
</choose>
</sql>
<select id="relateApiCaseList" resultType="io.metersphere.plan.dto.response.TestPlanApiCasePageResponse">
SELECT
t.id,
t.test_plan_collection_id,
atc.num,
atc.name,
atc.priority,
atc.project_id,
atc.api_definition_id,
atc.create_user,
t.create_time,
t.environment_id,
a.module_id,
a.path,
a.method,
a.protocol,
t.last_exec_result,
t.execute_user,
t.last_exec_time,
tpc.environment_id as collectEnvironmentId
FROM
api_test_case atc
INNER JOIN api_definition a ON atc.api_definition_id = a.id
inner join test_plan_api_case t on atc.id = t.api_case_id
left join test_plan_collection tpc on tpc.id = t.test_plan_collection_id
WHERE atc.deleted =#{deleted}
and t.test_plan_id = #{request.testPlanId}
<include refid="queryApiCaseWhereCondition"/>
</select>
<sql id="queryApiCaseWhereCondition">
<if test="request.protocol != null and request.protocol!=''">
and a.protocol = #{request.protocol}
</if>
<if test="request.apiDefinitionId != null and request.apiDefinitionId!=''">
and atc.api_definition_id = #{request.apiDefinitionId}
</if>
<if test="request.keyword != null and request.keyword !=''">
and (
atc.name like concat('%', #{request.keyword},'%')
or atc.num like concat('%', #{request.keyword},'%')
or a.path like concat('%', #{request.keyword},'%')
or atc.tags like concat('%', #{request.keyword},'%')
)
</if>
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and a.module_id in
<foreach collection="request.moduleIds" item="nodeId" separator="," open="(" close=")">
#{nodeId}
</foreach>
</if>
<include refid="apiCaseFilters">
<property name="filter" value="request.filter"/>
</include>
<include refid="queryApiCaseVersionCondition">
<property name="versionTable" value="atc"/>
</include>
</sql>
<sql id="apiCaseFilters">
<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 == 'priority'">
and atc.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='status'">
and atc.status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='caseStatus' or key=='case_status'">
and atc.case_status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='lastReportStatus'">
and atc.last_report_status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='createUser'">
and atc.create_user in
<foreach collection="values" item="value" separator="," open="(" close=")">
(#{value})
</foreach>
</when>
<when test="key=='updateUser'">
and atc.update_user in
<foreach collection="values" item="value" separator="," open="(" close=")">
(#{value})
</foreach>
</when>
<when test="key=='deleteUser'">
and atc.delete_user in
<foreach collection="values" item="value" separator="," open="(" close=")">
(#{value})
</foreach>
</when>
</choose>
</if>
</foreach>
</if>
</sql>
<sql id="queryApiCaseVersionCondition">
<if test="request.versionId != null and request.versionId != ''">
and ${versionTable}.version_id = #{request.versionId}
</if>
<if test="request.versionId == null and request.versionId != '' and request.apiDefinitionId == null and request.apiDefinitionId == ''">
AND a.latest = 1
</if>
</sql>
</mapper>

View File

@ -8,13 +8,27 @@ import io.metersphere.plan.domain.TestPlanApiCaseExample;
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
import io.metersphere.plan.dto.request.TestPlanApiCaseRequest;
import io.metersphere.plan.dto.request.TestPlanApiRequest;
import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
import io.metersphere.plan.mapper.ExtTestPlanApiCaseMapper;
import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
import io.metersphere.plan.mapper.TestPlanCollectionMapper;
import io.metersphere.project.domain.Project;
import io.metersphere.project.domain.ProjectExample;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.ModuleConstants;
import io.metersphere.sdk.domain.Environment;
import io.metersphere.sdk.domain.EnvironmentExample;
import io.metersphere.sdk.mapper.EnvironmentMapper;
import io.metersphere.system.service.UserLoginService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -32,6 +46,14 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
private ApiDefinitionService apiDefinitionService;
@Resource
private ApiTestCaseService apiTestCaseService;
@Resource
private ProjectMapper projectMapper;
@Resource
private EnvironmentMapper environmentMapper;
@Resource
private UserLoginService userLoginService;
@Resource
private TestPlanCollectionMapper testPlanCollectionMapper;
@Override
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
@ -96,4 +118,78 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
return apiCaseLists;
}
/**
* 获取已关联的接口用例列表
*
* @param request
* @param deleted
* @return
*/
public List<TestPlanApiCasePageResponse> HasRelateApiCaseList(TestPlanApiCaseRequest request, boolean deleted) {
List<TestPlanApiCasePageResponse> list = extTestPlanApiCaseMapper.relateApiCaseList(request, deleted);
buildApiCaseResponse(list);
return list;
}
private void buildApiCaseResponse(List<TestPlanApiCasePageResponse> apiCaseList) {
if (CollectionUtils.isNotEmpty(apiCaseList)) {
Map<String, String> projectMap = getProject(apiCaseList);
Map<String, String> envMap = getEnvironmentMap(apiCaseList);
Map<String, String> userMap = getUserMap(apiCaseList);
apiCaseList.forEach(apiCase -> {
apiCase.setProjectName(projectMap.get(apiCase.getProjectId()));
apiCase.setEnvironmentName(envMap.get(apiCase.getId()));
apiCase.setCreateUserName(userMap.get(apiCase.getCreateUser()));
});
}
}
private Map<String, String> getUserMap(List<TestPlanApiCasePageResponse> apiCaseList) {
List<String> userIds = new ArrayList<>();
userIds.addAll(apiCaseList.stream().map(TestPlanApiCasePageResponse::getCreateUser).toList());
userIds.addAll(apiCaseList.stream().map(TestPlanApiCasePageResponse::getExecuteUser).toList());
return userLoginService.getUserNameMap(userIds.stream().filter(StringUtils::isNotBlank).distinct().toList());
}
private Map<String, String> getEnvironmentMap(List<TestPlanApiCasePageResponse> apiCaseList) {
Map<String, String> envMap = new HashMap<>();
//默认环境
List<TestPlanApiCasePageResponse> defaultEnv = apiCaseList.stream().filter(item -> StringUtils.equalsIgnoreCase(ModuleConstants.ROOT_NODE_PARENT_ID, item.getCollectEnvironmentId())).toList();
if (CollectionUtils.isNotEmpty(defaultEnv)) {
List<String> defaultEnvIds = defaultEnv.stream().map(TestPlanApiCasePageResponse::getEnvironmentId).distinct().toList();
Map<String, TestPlanApiCasePageResponse> defaultEnvMap = defaultEnv.stream().collect(Collectors.toMap(TestPlanApiCasePageResponse::getEnvironmentId, testPlanApiCasePageResponse -> testPlanApiCasePageResponse));
EnvironmentExample environmentExample = new EnvironmentExample();
environmentExample.createCriteria().andIdIn(defaultEnvIds);
List<Environment> environments = environmentMapper.selectByExample(environmentExample);
environments.forEach(item -> {
TestPlanApiCasePageResponse testPlanApiCasePageResponse = defaultEnvMap.get(item.getId());
envMap.put(testPlanApiCasePageResponse.getId(), item.getName());
});
}
//非默认环境
List<TestPlanApiCasePageResponse> collectEnv = apiCaseList.stream().filter(item -> !StringUtils.equalsIgnoreCase(ModuleConstants.ROOT_NODE_PARENT_ID, item.getCollectEnvironmentId())).toList();
if (CollectionUtils.isNotEmpty(collectEnv)) {
List<String> collectEnvIds = collectEnv.stream().map(TestPlanApiCasePageResponse::getCollectEnvironmentId).distinct().toList();
Map<String, List<TestPlanApiCasePageResponse>> collectEnvMap = collectEnv.stream().collect(Collectors.groupingBy(TestPlanApiCasePageResponse::getCollectEnvironmentId));
EnvironmentExample environmentExample = new EnvironmentExample();
environmentExample.createCriteria().andIdIn(collectEnvIds);
List<Environment> environments = environmentMapper.selectByExample(environmentExample);
environments.forEach(item -> {
List<TestPlanApiCasePageResponse> list = collectEnvMap.get(item.getId());
list.forEach(response -> {
envMap.put(response.getId(), item.getName());
});
});
}
return envMap;
}
private Map<String, String> getProject(List<TestPlanApiCasePageResponse> apiCaseList) {
List<String> projectIds = apiCaseList.stream().map(TestPlanApiCasePageResponse::getProjectId).toList();
ProjectExample projectExample = new ProjectExample();
projectExample.createCriteria().andIdIn(projectIds);
List<Project> projectList = projectMapper.selectByExample(projectExample);
return projectList.stream().collect(Collectors.toMap(Project::getId, Project::getName));
}
}

View File

@ -1,17 +1,44 @@
package io.metersphere.plan.controller;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.TestMethodOrder;
import io.metersphere.plan.dto.request.TestPlanApiCaseRequest;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Sql(scripts = {"/ddl/test_plan_api_case.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public class TestPlanApiCaseControllerTests {
public class TestPlanApiCaseControllerTests extends BaseTest {
public static final String API_CASE_PAGE = "/test-plan/api/case/page";
@Test
@Order(1)
@Sql(scripts = {"/dml/init_test_plan_api_case.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void testApiCasePageList() throws Exception {
TestPlanApiCaseRequest request = new TestPlanApiCaseRequest();
request.setCurrent(1);
request.setPageSize(10);
request.setTestPlanId("wxxx_1");
request.setProjectId("wxx_1234");
request.setProtocol("HTTP");
this.requestPost(API_CASE_PAGE, request);
request.setSort(new HashMap<>() {{
put("createTime", "desc");
}});
MvcResult mvcResult = this.requestPostWithOkAndReturn(API_CASE_PAGE, request);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNotNull(resultHolder);
}
}

View File

@ -1,15 +0,0 @@
CREATE TABLE test_plan_api_case(
`id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
`test_plan_id` VARCHAR(50) NOT NULL COMMENT '测试计划ID' ,
`api_case_id` VARCHAR(50) NOT NULL COMMENT '接口用例ID' ,
`environment_type` VARCHAR(20) COMMENT '环境类型' ,
`environment` LONGTEXT COMMENT '所属环境' ,
`environment_group_id` VARCHAR(50) COMMENT '环境组ID' ,
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
`create_user` VARCHAR(40) NOT NULL COMMENT '创建人' ,
`pos` BIGINT NOT NULL COMMENT '自定义排序间隔5000' ,
PRIMARY KEY (id)
) COMMENT = '测试计划关联接口用例';
INSERT INTO test_plan_api_case value ('test-plan-api-case-id', UUID(), UUID(), null, null, null, CURRENT_TIMESTAMP, 'admin', 1);

View File

@ -0,0 +1,45 @@
INSERT INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `name`, `status`, `type`, `tags`, `create_time`, `create_user`, `update_time`, `update_user`, `planned_start_time`, `planned_end_time`, `actual_start_time`, `actual_end_time`, `description`)
VALUES
('wxxx_1', 5000, 'wxx_1234', 'NONE', '1', 'qwe', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
('wxxx_2', 10000, 'wxx_1234', 'NONE', '1', 'eeew', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`)
VALUES
('wxxx_1', b'0', b'0', 100),
('wxxx_2', b'0', b'0', 100);
INSERT INTO `api_definition`(`id`, `name`, `protocol`, `method`, `path`, `status`, `num`, `tags`, `pos`, `project_id`, `module_id`, `latest`, `version_id`, `ref_id`, `description`, `create_time`, `create_user`, `update_time`, `update_user`, `delete_user`, `delete_time`, `deleted`)
VALUES
('wxxx_api_1', '2222', 'HTTP', 'GET', '/111', 'DEPRECATED', 100003, '[]', 192, 'wxx_1234', 'root', b'1', '100844458962059498', '1086025445195776', '', 1716370415311, 'admin', 1716455838628, 'admin', NULL, NULL, b'0'),
('wxxx_api_2', '3333', 'HTTP', 'GET', '/111', 'DEPRECATED', 100003, '[]', 192, 'wxx_1234', 'root', b'1', '100844458962059498', '1086025445195776', '', 1716370415311, 'admin', 1716455838628, 'admin', NULL, NULL, b'0'),
('wxxx_api_3', '4444', 'HTTP', 'GET', '/111', 'DEPRECATED', 100003, '[]', 192, 'wxx_1234', 'root', b'1', '100844458962059498', '1086025445195776', '', 1716370415311, 'admin', 1716455838628, 'admin', NULL, NULL, b'0');
INSERT INTO `api_test_case`(`id`, `name`, `priority`, `num`, `tags`, `status`, `last_report_status`, `last_report_id`, `pos`, `project_id`, `api_definition_id`, `version_id`, `environment_id`, `create_time`, `create_user`, `update_time`, `update_user`, `delete_time`, `delete_user`, `deleted`)
VALUES
('wxxx_api_case_1', '231', 'P0', 100055001, '[]', 'PROCESSING', 'SUCCESS', '1130899263537153', 64, 'wxx_1234', 'wxxx_api_1', '899658209591296', '899606669983745', 1716199600948, 'admin', 1716199600948, 'admin', NULL, NULL, b'0'),
('wxxx_api_case_2', '232', 'P0', 100055001, '[]', 'PROCESSING', 'SUCCESS', '1130899263537153', 64, 'wxx_1234', 'wxxx_api_1', '899658209591296', '899606669983745', 1716199600948, 'admin', 1716199600948, 'admin', NULL, NULL, b'0'),
('wxxx_api_case_3', '233', 'P0', 100055001, '[]', 'PROCESSING', 'SUCCESS', '1130899263537153', 64, 'wxx_1234', 'wxxx_api_2', '899658209591296', '899606669983745', 1716199600948, 'admin', 1716199600948, 'admin', NULL, NULL, b'0');
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time, module_setting)
VALUES
('wxx_1234', 4, 1, 'wx', 'wx', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,'["bugManagement","caseManagement","apiTest","testPlan"]');
INSERT INTO `test_plan_api_case`(`id`, `test_plan_id`, `api_case_id`, `environment_id`, `last_exec_result`, `last_exec_report_id`, `execute_user`, `create_time`, `create_user`, `pos`, `test_plan_collection_id`, `last_exec_time`)
VALUES
('wxxx_1', 'wxxx_1', 'wxxx_api_case_1', '1', NULL, NULL, 'admin', 1716370415311, 'admin', 2, 'wxxx_1', 1716370415311),
('wxxx_2', 'wxxx_1', 'wxxx_api_case_2', '1', NULL, NULL, 'admin', 1716370415311, 'admin', 2, 'wxxx_2', 1716370415311);
INSERT INTO `test_plan_collection`(`id`, `test_plan_id`, `test_collection_type_id`, `name`, `execute_method`, `grouped`, `environment_id`, `pos`, `create_user`, `create_time`)
VALUES
('wxxx_1', 'wxxx_1', 'wxxx_1', '123', 'wx', b'0', 'NONE', 2, 'admin', 1716370415311),
('wxxx_2', 'wxxx_1', 'wxxx_2', '12223', 'wx', b'0', '123', 2, 'admin', 1716370415311);
INSERT INTO `environment`(`id`, `name`, `project_id`, `create_user`, `update_user`, `create_time`, `update_time`, `mock`, `description`, `pos`)
VALUES ('123', 'Mock环境', 'wxx_1234', 'admin', 'admin', 1716175907000, 1716175907000, b'1', NULL, 64);