refactor(功能用例): 删除项目清理用例资源&消息通知

This commit is contained in:
WangXu10 2023-11-01 16:17:53 +08:00 committed by Craftsman
parent f8b559545a
commit b4bf910a06
23 changed files with 412 additions and 221 deletions

View File

@ -23,14 +23,14 @@ public class FunctionalCaseTest implements Serializable {
private String caseId; private String caseId;
@Schema(description = "其他类型用例ID", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "其他类型用例ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case_test.test_id.not_blank}", groups = {Created.class}) @NotBlank(message = "{functional_case_test.source_id.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{functional_case_test.test_id.length_range}", groups = {Created.class, Updated.class}) @Size(min = 1, max = 50, message = "{functional_case_test.source_id.length_range}", groups = {Created.class, Updated.class})
private String testId; private String sourceId;
@Schema(description = "用例类型:接口用例/场景用例/性能用例/UI用例", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "用例类型:接口用例/场景用例/性能用例/UI用例", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case_test.test_type.not_blank}", groups = {Created.class}) @NotBlank(message = "{functional_case_test.source_type.not_blank}", groups = {Created.class})
@Size(min = 1, max = 64, message = "{functional_case_test.test_type.length_range}", groups = {Created.class, Updated.class}) @Size(min = 1, max = 64, message = "{functional_case_test.source_type.length_range}", groups = {Created.class, Updated.class})
private String testType; private String sourceType;
@Schema(description = "创建时间") @Schema(description = "创建时间")
private Long createTime; private Long createTime;
@ -43,8 +43,8 @@ public class FunctionalCaseTest implements Serializable {
public enum Column { public enum Column {
id("id", "id", "VARCHAR", false), id("id", "id", "VARCHAR", false),
caseId("case_id", "caseId", "VARCHAR", false), caseId("case_id", "caseId", "VARCHAR", false),
testId("test_id", "testId", "VARCHAR", false), sourceId("source_id", "sourceId", "VARCHAR", false),
testType("test_type", "testType", "VARCHAR", false), sourceType("source_type", "sourceType", "VARCHAR", false),
createTime("create_time", "createTime", "BIGINT", false), createTime("create_time", "createTime", "BIGINT", false),
updateTime("update_time", "updateTime", "BIGINT", false); updateTime("update_time", "updateTime", "BIGINT", false);

View File

@ -244,143 +244,143 @@ public class FunctionalCaseTestExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdIsNull() { public Criteria andSourceIdIsNull() {
addCriterion("test_id is null"); addCriterion("source_id is null");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdIsNotNull() { public Criteria andSourceIdIsNotNull() {
addCriterion("test_id is not null"); addCriterion("source_id is not null");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdEqualTo(String value) { public Criteria andSourceIdEqualTo(String value) {
addCriterion("test_id =", value, "testId"); addCriterion("source_id =", value, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdNotEqualTo(String value) { public Criteria andSourceIdNotEqualTo(String value) {
addCriterion("test_id <>", value, "testId"); addCriterion("source_id <>", value, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdGreaterThan(String value) { public Criteria andSourceIdGreaterThan(String value) {
addCriterion("test_id >", value, "testId"); addCriterion("source_id >", value, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdGreaterThanOrEqualTo(String value) { public Criteria andSourceIdGreaterThanOrEqualTo(String value) {
addCriterion("test_id >=", value, "testId"); addCriterion("source_id >=", value, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdLessThan(String value) { public Criteria andSourceIdLessThan(String value) {
addCriterion("test_id <", value, "testId"); addCriterion("source_id <", value, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdLessThanOrEqualTo(String value) { public Criteria andSourceIdLessThanOrEqualTo(String value) {
addCriterion("test_id <=", value, "testId"); addCriterion("source_id <=", value, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdLike(String value) { public Criteria andSourceIdLike(String value) {
addCriterion("test_id like", value, "testId"); addCriterion("source_id like", value, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdNotLike(String value) { public Criteria andSourceIdNotLike(String value) {
addCriterion("test_id not like", value, "testId"); addCriterion("source_id not like", value, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdIn(List<String> values) { public Criteria andSourceIdIn(List<String> values) {
addCriterion("test_id in", values, "testId"); addCriterion("source_id in", values, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdNotIn(List<String> values) { public Criteria andSourceIdNotIn(List<String> values) {
addCriterion("test_id not in", values, "testId"); addCriterion("source_id not in", values, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdBetween(String value1, String value2) { public Criteria andSourceIdBetween(String value1, String value2) {
addCriterion("test_id between", value1, value2, "testId"); addCriterion("source_id between", value1, value2, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestIdNotBetween(String value1, String value2) { public Criteria andSourceIdNotBetween(String value1, String value2) {
addCriterion("test_id not between", value1, value2, "testId"); addCriterion("source_id not between", value1, value2, "sourceId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeIsNull() { public Criteria andSourceTypeIsNull() {
addCriterion("test_type is null"); addCriterion("source_type is null");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeIsNotNull() { public Criteria andSourceTypeIsNotNull() {
addCriterion("test_type is not null"); addCriterion("source_type is not null");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeEqualTo(String value) { public Criteria andSourceTypeEqualTo(String value) {
addCriterion("test_type =", value, "testType"); addCriterion("source_type =", value, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeNotEqualTo(String value) { public Criteria andSourceTypeNotEqualTo(String value) {
addCriterion("test_type <>", value, "testType"); addCriterion("source_type <>", value, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeGreaterThan(String value) { public Criteria andSourceTypeGreaterThan(String value) {
addCriterion("test_type >", value, "testType"); addCriterion("source_type >", value, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeGreaterThanOrEqualTo(String value) { public Criteria andSourceTypeGreaterThanOrEqualTo(String value) {
addCriterion("test_type >=", value, "testType"); addCriterion("source_type >=", value, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeLessThan(String value) { public Criteria andSourceTypeLessThan(String value) {
addCriterion("test_type <", value, "testType"); addCriterion("source_type <", value, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeLessThanOrEqualTo(String value) { public Criteria andSourceTypeLessThanOrEqualTo(String value) {
addCriterion("test_type <=", value, "testType"); addCriterion("source_type <=", value, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeLike(String value) { public Criteria andSourceTypeLike(String value) {
addCriterion("test_type like", value, "testType"); addCriterion("source_type like", value, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeNotLike(String value) { public Criteria andSourceTypeNotLike(String value) {
addCriterion("test_type not like", value, "testType"); addCriterion("source_type not like", value, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeIn(List<String> values) { public Criteria andSourceTypeIn(List<String> values) {
addCriterion("test_type in", values, "testType"); addCriterion("source_type in", values, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeNotIn(List<String> values) { public Criteria andSourceTypeNotIn(List<String> values) {
addCriterion("test_type not in", values, "testType"); addCriterion("source_type not in", values, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeBetween(String value1, String value2) { public Criteria andSourceTypeBetween(String value1, String value2) {
addCriterion("test_type between", value1, value2, "testType"); addCriterion("source_type between", value1, value2, "sourceType");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTestTypeNotBetween(String value1, String value2) { public Criteria andSourceTypeNotBetween(String value1, String value2) {
addCriterion("test_type not between", value1, value2, "testType"); addCriterion("source_type not between", value1, value2, "sourceType");
return (Criteria) this; return (Criteria) this;
} }

View File

@ -4,8 +4,8 @@
<resultMap id="BaseResultMap" type="io.metersphere.functional.domain.FunctionalCaseTest"> <resultMap id="BaseResultMap" type="io.metersphere.functional.domain.FunctionalCaseTest">
<id column="id" jdbcType="VARCHAR" property="id" /> <id column="id" jdbcType="VARCHAR" property="id" />
<result column="case_id" jdbcType="VARCHAR" property="caseId" /> <result column="case_id" jdbcType="VARCHAR" property="caseId" />
<result column="test_id" jdbcType="VARCHAR" property="testId" /> <result column="source_id" jdbcType="VARCHAR" property="sourceId" />
<result column="test_type" jdbcType="VARCHAR" property="testType" /> <result column="source_type" jdbcType="VARCHAR" property="sourceType" />
<result column="create_time" jdbcType="BIGINT" property="createTime" /> <result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" /> <result column="update_time" jdbcType="BIGINT" property="updateTime" />
</resultMap> </resultMap>
@ -68,7 +68,7 @@
</where> </where>
</sql> </sql>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, case_id, test_id, test_type, create_time, update_time id, case_id, source_id, source_type, create_time, update_time
</sql> </sql>
<select id="selectByExample" parameterType="io.metersphere.functional.domain.FunctionalCaseTestExample" resultMap="BaseResultMap"> <select id="selectByExample" parameterType="io.metersphere.functional.domain.FunctionalCaseTestExample" resultMap="BaseResultMap">
select select
@ -101,11 +101,11 @@
</if> </if>
</delete> </delete>
<insert id="insert" parameterType="io.metersphere.functional.domain.FunctionalCaseTest"> <insert id="insert" parameterType="io.metersphere.functional.domain.FunctionalCaseTest">
insert into functional_case_test (id, case_id, test_id, insert into functional_case_test (id, case_id, source_id,
test_type, create_time, update_time source_type, create_time, update_time
) )
values (#{id,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR}, #{testId,jdbcType=VARCHAR}, values (#{id,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR},
#{testType,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT} #{sourceType,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}
) )
</insert> </insert>
<insert id="insertSelective" parameterType="io.metersphere.functional.domain.FunctionalCaseTest"> <insert id="insertSelective" parameterType="io.metersphere.functional.domain.FunctionalCaseTest">
@ -117,11 +117,11 @@
<if test="caseId != null"> <if test="caseId != null">
case_id, case_id,
</if> </if>
<if test="testId != null"> <if test="sourceId != null">
test_id, source_id,
</if> </if>
<if test="testType != null"> <if test="sourceType != null">
test_type, source_type,
</if> </if>
<if test="createTime != null"> <if test="createTime != null">
create_time, create_time,
@ -137,11 +137,11 @@
<if test="caseId != null"> <if test="caseId != null">
#{caseId,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR},
</if> </if>
<if test="testId != null"> <if test="sourceId != null">
#{testId,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR},
</if> </if>
<if test="testType != null"> <if test="sourceType != null">
#{testType,jdbcType=VARCHAR}, #{sourceType,jdbcType=VARCHAR},
</if> </if>
<if test="createTime != null"> <if test="createTime != null">
#{createTime,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT},
@ -166,11 +166,11 @@
<if test="record.caseId != null"> <if test="record.caseId != null">
case_id = #{record.caseId,jdbcType=VARCHAR}, case_id = #{record.caseId,jdbcType=VARCHAR},
</if> </if>
<if test="record.testId != null"> <if test="record.sourceId != null">
test_id = #{record.testId,jdbcType=VARCHAR}, source_id = #{record.sourceId,jdbcType=VARCHAR},
</if> </if>
<if test="record.testType != null"> <if test="record.sourceType != null">
test_type = #{record.testType,jdbcType=VARCHAR}, source_type = #{record.sourceType,jdbcType=VARCHAR},
</if> </if>
<if test="record.createTime != null"> <if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT}, create_time = #{record.createTime,jdbcType=BIGINT},
@ -187,8 +187,8 @@
update functional_case_test update functional_case_test
set id = #{record.id,jdbcType=VARCHAR}, set id = #{record.id,jdbcType=VARCHAR},
case_id = #{record.caseId,jdbcType=VARCHAR}, case_id = #{record.caseId,jdbcType=VARCHAR},
test_id = #{record.testId,jdbcType=VARCHAR}, source_id = #{record.sourceId,jdbcType=VARCHAR},
test_type = #{record.testType,jdbcType=VARCHAR}, source_type = #{record.sourceType,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT}, create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT} update_time = #{record.updateTime,jdbcType=BIGINT}
<if test="_parameter != null"> <if test="_parameter != null">
@ -201,11 +201,11 @@
<if test="caseId != null"> <if test="caseId != null">
case_id = #{caseId,jdbcType=VARCHAR}, case_id = #{caseId,jdbcType=VARCHAR},
</if> </if>
<if test="testId != null"> <if test="sourceId != null">
test_id = #{testId,jdbcType=VARCHAR}, source_id = #{sourceId,jdbcType=VARCHAR},
</if> </if>
<if test="testType != null"> <if test="sourceType != null">
test_type = #{testType,jdbcType=VARCHAR}, source_type = #{sourceType,jdbcType=VARCHAR},
</if> </if>
<if test="createTime != null"> <if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=BIGINT},
@ -219,19 +219,19 @@
<update id="updateByPrimaryKey" parameterType="io.metersphere.functional.domain.FunctionalCaseTest"> <update id="updateByPrimaryKey" parameterType="io.metersphere.functional.domain.FunctionalCaseTest">
update functional_case_test update functional_case_test
set case_id = #{caseId,jdbcType=VARCHAR}, set case_id = #{caseId,jdbcType=VARCHAR},
test_id = #{testId,jdbcType=VARCHAR}, source_id = #{sourceId,jdbcType=VARCHAR},
test_type = #{testType,jdbcType=VARCHAR}, source_type = #{sourceType,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT} update_time = #{updateTime,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}
</update> </update>
<insert id="batchInsert" parameterType="map"> <insert id="batchInsert" parameterType="map">
insert into functional_case_test insert into functional_case_test
(id, case_id, test_id, test_type, create_time, update_time) (id, case_id, source_id, source_type, create_time, update_time)
values values
<foreach collection="list" item="item" separator=","> <foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.caseId,jdbcType=VARCHAR}, #{item.testId,jdbcType=VARCHAR}, (#{item.id,jdbcType=VARCHAR}, #{item.caseId,jdbcType=VARCHAR}, #{item.sourceId,jdbcType=VARCHAR},
#{item.testType,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.updateTime,jdbcType=BIGINT} #{item.sourceType,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.updateTime,jdbcType=BIGINT}
) )
</foreach> </foreach>
</insert> </insert>
@ -251,11 +251,11 @@
<if test="'case_id'.toString() == column.value"> <if test="'case_id'.toString() == column.value">
#{item.caseId,jdbcType=VARCHAR} #{item.caseId,jdbcType=VARCHAR}
</if> </if>
<if test="'test_id'.toString() == column.value"> <if test="'source_id'.toString() == column.value">
#{item.testId,jdbcType=VARCHAR} #{item.sourceId,jdbcType=VARCHAR}
</if> </if>
<if test="'test_type'.toString() == column.value"> <if test="'source_type'.toString() == column.value">
#{item.testType,jdbcType=VARCHAR} #{item.sourceType,jdbcType=VARCHAR}
</if> </if>
<if test="'create_time'.toString() == column.value"> <if test="'create_time'.toString() == column.value">
#{item.createTime,jdbcType=BIGINT} #{item.createTime,jdbcType=BIGINT}

View File

@ -157,8 +157,8 @@ CREATE INDEX target_id_index ON functional_case_relationship_edge(target_id);
CREATE TABLE IF NOT EXISTS functional_case_test( CREATE TABLE IF NOT EXISTS functional_case_test(
`id` VARCHAR(50) NOT NULL COMMENT 'ID' , `id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
`case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID' , `case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID' ,
`test_id` VARCHAR(50) NOT NULL COMMENT '其他类型用例ID' , `source_id` VARCHAR(50) NOT NULL COMMENT '其他类型用例ID' ,
`test_type` VARCHAR(64) NOT NULL COMMENT '用例类型:接口用例/场景用例/性能用例/UI用例' , `source_type` VARCHAR(64) NOT NULL COMMENT '用例类型:接口用例/场景用例/性能用例/UI用例' ,
`create_time` BIGINT NOT NULL COMMENT '创建时间' , `create_time` BIGINT NOT NULL COMMENT '创建时间' ,
`update_time` BIGINT NOT NULL COMMENT '更新时间' , `update_time` BIGINT NOT NULL COMMENT '更新时间' ,
PRIMARY KEY (id) PRIMARY KEY (id)
@ -167,8 +167,8 @@ CREATE TABLE IF NOT EXISTS functional_case_test(
COLLATE = utf8mb4_general_ci COMMENT = '功能用例和其他用例的中间表'; COLLATE = utf8mb4_general_ci COMMENT = '功能用例和其他用例的中间表';
CREATE UNIQUE INDEX uk_case_id_test_id ON functional_case_test(case_id,test_id); CREATE INDEX idx_case_id ON functional_case_test(case_id);
CREATE INDEX idx_test_id ON functional_case_test(test_id); CREATE INDEX idx_source_id ON functional_case_test(source_id);
CREATE TABLE IF NOT EXISTS functional_minder_extra_node( CREATE TABLE IF NOT EXISTS functional_minder_extra_node(

View File

@ -76,10 +76,10 @@ functional_case_relationship_edge.create_user.not_blank=Creator cannot be empty
functional_case_test.id.not_blank=ID cannot be empty functional_case_test.id.not_blank=ID cannot be empty
functional_case_test.functional_case_id.length_range=The length of the function case ID must be between 1 and 50 functional_case_test.functional_case_id.length_range=The length of the function case ID must be between 1 and 50
functional_case_test.functional_case_id.not_blank=Function case ID cannot be empty functional_case_test.functional_case_id.not_blank=Function case ID cannot be empty
functional_case_test.test_id.length_range=The length of the test ID must be between 1 and 50 functional_case_test.source_id.length_range=The length of the test ID must be between 1 and 50
functional_case_test.test_id.not_blank=Test ID cannot be empty functional_case_test.source_id.not_blank=Test ID cannot be empty
functional_case_test.test_type.length_range=The length of the test type must be between 1 and 64 functional_case_test.source_type.length_range=The length of the test type must be between 1 and 64
functional_case_test.test_type.not_blank=Test type cannot be empty functional_case_test.source_type.not_blank=Test type cannot be empty
#FunctionalCaseCustomField #FunctionalCaseCustomField
functional_case_custom_field.case_id.not_blank=Case ID cannot be empty functional_case_custom_field.case_id.not_blank=Case ID cannot be empty
functional_case_custom_field.field_id.not_blank=Field ID cannot be empty functional_case_custom_field.field_id.not_blank=Field ID cannot be empty

View File

@ -76,10 +76,10 @@ functional_case_relationship_edge.create_user.not_blank=创建人不能为空
functional_case_test.id.not_blank=ID不能为空 functional_case_test.id.not_blank=ID不能为空
functional_case_test.functional_case_id.length_range=功能用例ID长度必须在1-50之间 functional_case_test.functional_case_id.length_range=功能用例ID长度必须在1-50之间
functional_case_test.functional_case_id.not_blank=功能用例ID不能为空 functional_case_test.functional_case_id.not_blank=功能用例ID不能为空
functional_case_test.test_id.length_range=其他类型用例ID长度必须在1-50之间 functional_case_test.source_id.length_range=其他类型用例ID长度必须在1-50之间
functional_case_test.test_id.not_blank=其他类型用例ID不能为空 functional_case_test.source_id.not_blank=其他类型用例ID不能为空
functional_case_test.test_type.length_range=用例类型长度必须在1-64之间 functional_case_test.source_type.length_range=用例类型长度必须在1-64之间
functional_case_test.test_type.not_blank=用例类型不能为空 functional_case_test.source_type.not_blank=用例类型不能为空
#FunctionalCaseCustomField #FunctionalCaseCustomField
functional_case_custom_field.case_id.not_blank=功能用例ID不能为空 functional_case_custom_field.case_id.not_blank=功能用例ID不能为空
functional_case_custom_field.field_id.not_blank=自定义字段ID不能为空 functional_case_custom_field.field_id.not_blank=自定义字段ID不能为空

View File

@ -76,10 +76,10 @@ functional_case_relationship_edge.create_user.not_blank=創建人不能為空
functional_case_test.id.not_blank=ID不能為空 functional_case_test.id.not_blank=ID不能為空
functional_case_test.functional_case_id.length_range=功能用例ID長度必須在1-50之間 functional_case_test.functional_case_id.length_range=功能用例ID長度必須在1-50之間
functional_case_test.functional_case_id.not_blank=功能用例ID不能為空 functional_case_test.functional_case_id.not_blank=功能用例ID不能為空
functional_case_test.test_id.length_range=其他類型用例ID長度必須在1-50之間 functional_case_test.source_id.length_range=其他類型用例ID長度必須在1-50之間
functional_case_test.test_id.not_blank=其他類型用例ID不能為空 functional_case_test.source_id.not_blank=其他類型用例ID不能為空
functional_case_test.test_type.length_range=用例類型長度必須在1-64之間 functional_case_test.source_type.length_range=用例類型長度必須在1-64之間
functional_case_test.test_type.not_blank=用例類型不能為空 functional_case_test.source_type.not_blank=用例類型不能為空
#FunctionalCaseCustomField #FunctionalCaseCustomField
functional_case_custom_field.case_id.not_blank=功能用例ID不能爲空 functional_case_custom_field.case_id.not_blank=功能用例ID不能爲空
functional_case_custom_field.field_id.not_blank=自定義字段ID不能爲空 functional_case_custom_field.field_id.not_blank=自定義字段ID不能爲空

View File

@ -61,7 +61,7 @@ public class FunctionalCaseController {
@Operation(summary = "功能用例-新增用例") @Operation(summary = "功能用例-新增用例")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_ADD) @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_ADD)
@Log(type = OperationLogType.ADD, expression = "#msClass.addFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseLogService.class) @Log(type = OperationLogType.ADD, expression = "#msClass.addFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseLogService.class)
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.CREATE, target = "#targetClass.getMainFunctionalCaseDTO(#request)", targetClass = FunctionalCaseNoticeService.class) @SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.CREATE, target = "#targetClass.getMainFunctionalCaseDTO(#request.name, #request.caseEditType, #request.customsFields)", targetClass = FunctionalCaseNoticeService.class)
public FunctionalCase addFunctionalCase(@Validated @RequestPart("request") FunctionalCaseAddRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> files) { public FunctionalCase addFunctionalCase(@Validated @RequestPart("request") FunctionalCaseAddRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> files) {
String userId = SessionUtils.getUserId(); String userId = SessionUtils.getUserId();
return functionalCaseService.addFunctionalCase(request, files, userId); return functionalCaseService.addFunctionalCase(request, files, userId);
@ -80,6 +80,7 @@ public class FunctionalCaseController {
@Operation(summary = "功能用例-更新用例") @Operation(summary = "功能用例-更新用例")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE) @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseLogService.class) @Log(type = OperationLogType.UPDATE, expression = "#msClass.updateFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseLogService.class)
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainFunctionalCaseDTO(#request.name, #request.caseEditType, #request.customsFields)", targetClass = FunctionalCaseNoticeService.class)
public FunctionalCase updateFunctionalCase(@Validated @RequestPart("request") FunctionalCaseEditRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> files) { public FunctionalCase updateFunctionalCase(@Validated @RequestPart("request") FunctionalCaseEditRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> files) {
String userId = SessionUtils.getUserId(); String userId = SessionUtils.getUserId();
return functionalCaseService.updateFunctionalCase(request, files, userId); return functionalCaseService.updateFunctionalCase(request, files, userId);
@ -115,6 +116,7 @@ public class FunctionalCaseController {
@Operation(summary = "功能用例-删除用例") @Operation(summary = "功能用例-删除用例")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_DELETE) @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_DELETE)
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class) @Log(type = OperationLogType.DELETE, expression = "#msClass.deleteFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class)
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getDeleteFunctionalCaseDTO(#request.id)", targetClass = FunctionalCaseNoticeService.class)
public void deleteFunctionalCase(@Validated @RequestBody FunctionalCaseDeleteRequest request) { public void deleteFunctionalCase(@Validated @RequestBody FunctionalCaseDeleteRequest request) {
String userId = SessionUtils.getUserId(); String userId = SessionUtils.getUserId();
functionalCaseService.deleteFunctionalCase(request, userId); functionalCaseService.deleteFunctionalCase(request, userId);

View File

@ -24,4 +24,6 @@ public class FunctionalCaseVersionDTO implements Serializable {
@Schema(description = "版本id") @Schema(description = "版本id")
private String versionId; private String versionId;
@Schema(description = "项目id")
private String projectId;
} }

View File

@ -18,4 +18,5 @@ public interface ExtFunctionalCaseMapper {
List<FunctionalCaseVersionDTO> getFunctionalCaseByRefId(@Param("refId") String refId); List<FunctionalCaseVersionDTO> getFunctionalCaseByRefId(@Param("refId") String refId);
List<String> getFunctionalCaseIds(@Param("projectId") String projectId);
} }

View File

@ -40,10 +40,20 @@
SELECT SELECT
id, id,
NAME, NAME,
version_id version_id,
project_id
FROM FROM
functional_case functional_case
WHERE WHERE
ref_id = #{refId} ref_id = #{refId}
</select> </select>
<select id="getFunctionalCaseIds" resultType="java.lang.String">
SELECT
id
FROM
functional_case
WHERE
project_id = #{projectId}
</select>
</mapper> </mapper>

View File

@ -22,4 +22,8 @@ public class FunctionalCaseDeleteRequest implements Serializable {
@Schema(description = "删除列表版本/删除全部版本") @Schema(description = "删除列表版本/删除全部版本")
private Boolean deleteAll; private Boolean deleteAll;
@Schema(description = "项目id")
@NotBlank(message = "{functional_case.project_id.not_blank}")
private String projectId;
} }

View File

@ -0,0 +1,38 @@
package io.metersphere.functional.service;
import io.metersphere.functional.mapper.ExtFunctionalCaseMapper;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.service.CleanupProjectResourceService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author wx
*/
@Component
public class CleanupFunctionalCaseResourceService implements CleanupProjectResourceService {
@Resource
private ExtFunctionalCaseMapper extFunctionalCaseMapper;
@Resource
private DeleteFunctionalCaseService deleteFunctionalCaseService;
@Override
public void deleteResources(String projectId) {
List<String> ids = extFunctionalCaseMapper.getFunctionalCaseIds(projectId);
if (CollectionUtils.isNotEmpty(ids)) {
deleteFunctionalCaseService.deleteFunctionalCaseResource(ids, projectId);
}
}
@Override
public void cleanReportResources(String projectId) {
LogUtils.info("清理当前项目[" + projectId + "]相关报告资源");
}
}

View File

@ -0,0 +1,55 @@
package io.metersphere.functional.service;
import io.metersphere.functional.domain.*;
import io.metersphere.functional.mapper.FunctionalCaseBlobMapper;
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.mapper.FunctionalCaseTestMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author wx
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class DeleteFunctionalCaseService {
@Resource
private FunctionalCaseTestMapper functionalCaseTestMapper;
@Resource
private FunctionalCaseAttachmentService functionalCaseAttachmentService;
@Resource
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
@Resource
private FunctionalCaseBlobMapper functionalCaseBlobMapper;
@Resource
private FunctionalCaseMapper functionalCaseMapper;
public void deleteFunctionalCaseResource(List<String> ids, String projectId) {
//TODO 删除各种关联关系 1.测试用例(接口/场景/ui/性能) 2.关联缺陷(是否需要同步) 3.关联需求(是否需要同步) 4.依赖关系 5.关联评审 6.操作记录 7.关联测试计划 8.评论 9.附件 10.自定义字段 11.用例基本信息(主表附属表)12.模块? 13...?
//1.刪除用例与其他用例关联关系
FunctionalCaseTestExample caseTestExample = new FunctionalCaseTestExample();
caseTestExample.createCriteria().andCaseIdIn(ids);
functionalCaseTestMapper.deleteByExample(caseTestExample);
//9.附件
functionalCaseAttachmentService.deleteAttachmentResource(ids, projectId);
//10.自定义字段
FunctionalCaseCustomFieldExample fieldExample = new FunctionalCaseCustomFieldExample();
fieldExample.createCriteria().andCaseIdIn(ids);
functionalCaseCustomFieldMapper.deleteByExample(fieldExample);
//11.用例基本信息
FunctionalCaseBlobExample blobExample = new FunctionalCaseBlobExample();
blobExample.createCriteria().andIdIn(ids);
functionalCaseBlobMapper.deleteByExample(blobExample);
FunctionalCaseExample caseExample = new FunctionalCaseExample();
caseExample.createCriteria().andIdIn(ids).andProjectIdEqualTo(projectId);
functionalCaseMapper.deleteByExample(caseExample);
}
}

View File

@ -7,9 +7,15 @@ import io.metersphere.functional.domain.FunctionalCaseAttachmentExample;
import io.metersphere.functional.dto.FunctionalCaseAttachmentDTO; import io.metersphere.functional.dto.FunctionalCaseAttachmentDTO;
import io.metersphere.functional.dto.FunctionalCaseDetailDTO; import io.metersphere.functional.dto.FunctionalCaseDetailDTO;
import io.metersphere.functional.mapper.FunctionalCaseAttachmentMapper; import io.metersphere.functional.mapper.FunctionalCaseAttachmentMapper;
import io.metersphere.functional.request.FunctionalCaseAddRequest;
import io.metersphere.project.domain.FileMetadata; import io.metersphere.project.domain.FileMetadata;
import io.metersphere.project.mapper.FileMetadataMapper; import io.metersphere.project.mapper.FileMetadataMapper;
import io.metersphere.sdk.constants.StorageType;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.MsFileUtils;
import io.metersphere.system.file.FileRequest;
import io.metersphere.system.file.MinioRepository;
import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
@ -40,6 +46,9 @@ public class FunctionalCaseAttachmentService {
@Resource @Resource
private FileMetadataMapper fileMetadataMapper; private FileMetadataMapper fileMetadataMapper;
@Resource
private MinioRepository minioRepository;
/** /**
* 保存本地上传文件和用例关联关系 * 保存本地上传文件和用例关联关系
* *
@ -55,6 +64,31 @@ public class FunctionalCaseAttachmentService {
} }
/**
* 功能用例上传附件
*
* @param request
* @param files
*/
public void uploadFile(FunctionalCaseAddRequest request, String caseId, List<MultipartFile> files, Boolean isLocal, String userId) {
if (CollectionUtils.isNotEmpty(files)) {
files.forEach(file -> {
String fileId = IDGenerator.nextStr();
FileRequest fileRequest = new FileRequest();
fileRequest.setFileName(file.getName());
fileRequest.setResourceId(MsFileUtils.FUNCTIONAL_CASE_DIR_NAME + "/" + request.getProjectId() + fileId);
fileRequest.setStorage(StorageType.MINIO.name());
try {
minioRepository.saveFile(file, fileRequest);
} catch (Exception e) {
throw new MSException("save file error");
}
saveCaseAttachment(fileId, file, caseId, isLocal, userId);
});
}
}
/** /**
* 保存文件库文件与用例关联关系 * 保存文件库文件与用例关联关系
* *
@ -121,13 +155,46 @@ public class FunctionalCaseAttachmentService {
* *
* @param deleteFileMetaIds * @param deleteFileMetaIds
*/ */
public List<FunctionalCaseAttachment> deleteCaseAttachment(List<String> deleteFileMetaIds, String caseId) { public void deleteCaseAttachment(List<String> deleteFileMetaIds, String caseId, String projectId) {
FunctionalCaseAttachmentExample example = new FunctionalCaseAttachmentExample(); FunctionalCaseAttachmentExample example = new FunctionalCaseAttachmentExample();
example.createCriteria().andFileIdIn(deleteFileMetaIds).andCaseIdEqualTo(caseId).andLocalEqualTo(true); example.createCriteria().andFileIdIn(deleteFileMetaIds).andCaseIdEqualTo(caseId).andLocalEqualTo(true);
List<FunctionalCaseAttachment> delAttachment = functionalCaseAttachmentMapper.selectByExample(example); List<FunctionalCaseAttachment> delAttachment = functionalCaseAttachmentMapper.selectByExample(example);
example.clear(); example.clear();
example.createCriteria().andFileIdIn(deleteFileMetaIds).andCaseIdEqualTo(caseId); example.createCriteria().andFileIdIn(deleteFileMetaIds).andCaseIdEqualTo(caseId);
functionalCaseAttachmentMapper.deleteByExample(example); functionalCaseAttachmentMapper.deleteByExample(example);
return delAttachment; this.deleteMinioFile(delAttachment, projectId);
}
private void deleteMinioFile(List<FunctionalCaseAttachment> files, String projectId) {
if (CollectionUtils.isNotEmpty(files)) {
files.forEach(file -> {
FileRequest fileRequest = new FileRequest();
fileRequest.setFileName(file.getFileName());
fileRequest.setResourceId(MsFileUtils.FUNCTIONAL_CASE_DIR_NAME + "/" + projectId + file.getFileId());
fileRequest.setStorage(StorageType.MINIO.name());
try {
minioRepository.delete(fileRequest);
} catch (Exception e) {
throw new MSException("delete file error");
}
});
}
}
/**
* 清理附件资源
*
* @param ids
*/
public void deleteAttachmentResource(List<String> ids, String projectId) {
FunctionalCaseAttachmentExample example = new FunctionalCaseAttachmentExample();
example.createCriteria().andCaseIdIn(ids).andLocalEqualTo(true);
List<FunctionalCaseAttachment> localAttachment = functionalCaseAttachmentMapper.selectByExample(example);
example.clear();
example.createCriteria().andCaseIdIn(ids);
functionalCaseAttachmentMapper.deleteByExample(example);
deleteMinioFile(localAttachment, projectId);
} }
} }

View File

@ -87,18 +87,21 @@ public class FunctionalCaseLogService {
*/ */
public LogDTO deleteFunctionalCaseLog(FunctionalCaseDeleteRequest request) { public LogDTO deleteFunctionalCaseLog(FunctionalCaseDeleteRequest request) {
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(request.getId()); FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(request.getId());
LogDTO dto = new LogDTO( if (functionalCase != null) {
functionalCase.getProjectId(), LogDTO dto = new LogDTO(
null, functionalCase.getProjectId(),
functionalCase.getId(), null,
null, functionalCase.getId(),
OperationLogType.DELETE.name(), null,
OperationLogModule.FUNCTIONAL_CASE, OperationLogType.DELETE.name(),
functionalCase.getName()); OperationLogModule.FUNCTIONAL_CASE,
functionalCase.getName());
dto.setPath("/functional/case/delete"); dto.setPath("/functional/case/delete");
dto.setMethod(HttpMethodConstants.POST.name()); dto.setMethod(HttpMethodConstants.POST.name());
dto.setOriginalValue(JSON.toJSONBytes(functionalCase)); dto.setOriginalValue(JSON.toJSONBytes(functionalCase));
return dto; return dto;
}
return null;
} }
} }

View File

@ -7,7 +7,6 @@ import io.metersphere.functional.dto.CaseCustomsFieldDTO;
import io.metersphere.functional.dto.FunctionalCaseDTO; import io.metersphere.functional.dto.FunctionalCaseDTO;
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper; import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.request.FunctionalCaseAddRequest;
import io.metersphere.functional.request.FunctionalCaseCommentRequest; import io.metersphere.functional.request.FunctionalCaseCommentRequest;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.system.domain.CustomField; import io.metersphere.system.domain.CustomField;
@ -21,10 +20,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -39,10 +35,10 @@ public class FunctionalCaseNoticeService {
@Resource @Resource
private CustomFieldMapper customFieldMapper; private CustomFieldMapper customFieldMapper;
public FunctionalCaseDTO getFunctionalCaseDTO(FunctionalCaseCommentRequest functionalCaseCommentRequest){ public FunctionalCaseDTO getFunctionalCaseDTO(FunctionalCaseCommentRequest functionalCaseCommentRequest) {
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId()); FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO(); FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
BeanUtils.copyBean(functionalCaseDTO,functionalCase); BeanUtils.copyBean(functionalCaseDTO, functionalCase);
setNotifier(functionalCaseCommentRequest, functionalCaseDTO); setNotifier(functionalCaseCommentRequest, functionalCaseDTO);
List<OptionDTO> customFields = getCustomFields(functionalCaseCommentRequest.getCaseId()); List<OptionDTO> customFields = getCustomFields(functionalCaseCommentRequest.getCaseId());
functionalCaseDTO.setFields(customFields); functionalCaseDTO.setFields(customFields);
@ -50,11 +46,11 @@ public class FunctionalCaseNoticeService {
} }
/** /**
*
* 如果是REPLAY事件需要判断有无@的人如果有@的人且当前被回复的人不是同一人这里只要被回复的人,如果是同一人这里通知人为空走AT事件 * 如果是REPLAY事件需要判断有无@的人如果有@的人且当前被回复的人不是同一人这里只要被回复的人,如果是同一人这里通知人为空走AT事件
* 如果不是REPLAY事件需要判断有无被回复的人如果被回复的人不在被@人里则用页面参数传递的通知人如果在则排除这个人,如果没有被回复的人用页面数据 * 如果不是REPLAY事件需要判断有无被回复的人如果被回复的人不在被@人里则用页面参数传递的通知人如果在则排除这个人,如果没有被回复的人用页面数据
*
* @param functionalCaseCommentRequest 页面参数 * @param functionalCaseCommentRequest 页面参数
* @param functionalCaseDTO 发通知需要解析字段集合 * @param functionalCaseDTO 发通知需要解析字段集合
*/ */
private void setNotifier(FunctionalCaseCommentRequest functionalCaseCommentRequest, FunctionalCaseDTO functionalCaseDTO) { private void setNotifier(FunctionalCaseCommentRequest functionalCaseCommentRequest, FunctionalCaseDTO functionalCaseDTO) {
String notifier = functionalCaseCommentRequest.getNotifier(); String notifier = functionalCaseCommentRequest.getNotifier();
@ -70,7 +66,7 @@ public class FunctionalCaseNoticeService {
} }
} else { } else {
if (StringUtils.isNotBlank(replyUser)) { if (StringUtils.isNotBlank(replyUser)) {
StringBuilder notifierStr = new StringBuilder(); StringBuilder notifierStr = new StringBuilder();
if (StringUtils.isNotBlank(notifier)) { if (StringUtils.isNotBlank(notifier)) {
List<String> notifierList = Arrays.asList(notifier.split(";")); List<String> notifierList = Arrays.asList(notifier.split(";"));
if (notifierList.contains(replyUser)) { if (notifierList.contains(replyUser)) {
@ -79,8 +75,7 @@ public class FunctionalCaseNoticeService {
notifierStr.append(notifierId).append(";"); notifierStr.append(notifierId).append(";");
} }
} }
} } else {
else {
notifierStr = new StringBuilder(notifier); notifierStr = new StringBuilder(notifier);
} }
functionalCaseDTO.setRelatedUsers(notifierStr.toString()); functionalCaseDTO.setRelatedUsers(notifierStr.toString());
@ -94,21 +89,21 @@ public class FunctionalCaseNoticeService {
/** /**
* 根据用例id获取当前用例在使用的自定义的字段及其值 * 根据用例id获取当前用例在使用的自定义的字段及其值
* *
* @param caseId 用例Id * @param caseId 用例Id
* @return 返回 字段以及字段值的组合 * @return 返回 字段以及字段值的组合
*/ */
private List<OptionDTO> getCustomFields(String caseId) { private List<OptionDTO> getCustomFields(String caseId) {
FunctionalCaseCustomFieldExample functionalCaseCustomFieldExample = new FunctionalCaseCustomFieldExample(); FunctionalCaseCustomFieldExample functionalCaseCustomFieldExample = new FunctionalCaseCustomFieldExample();
functionalCaseCustomFieldExample.createCriteria().andCaseIdEqualTo(caseId); functionalCaseCustomFieldExample.createCriteria().andCaseIdEqualTo(caseId);
List<FunctionalCaseCustomField> functionalCaseCustomFields = functionalCaseCustomFieldMapper.selectByExample(functionalCaseCustomFieldExample); List<FunctionalCaseCustomField> functionalCaseCustomFields = functionalCaseCustomFieldMapper.selectByExample(functionalCaseCustomFieldExample);
List<OptionDTO>optionDTOList = new ArrayList<>(); List<OptionDTO> optionDTOList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(functionalCaseCustomFields)) { if (CollectionUtils.isNotEmpty(functionalCaseCustomFields)) {
Map<String, String> fieldValueMap = functionalCaseCustomFields.stream().collect(Collectors.toMap(FunctionalCaseCustomField::getFieldId, FunctionalCaseCustomField::getValue)); Map<String, String> fieldValueMap = functionalCaseCustomFields.stream().collect(Collectors.toMap(FunctionalCaseCustomField::getFieldId, FunctionalCaseCustomField::getValue));
List<String> fieldIds = functionalCaseCustomFields.stream().map(FunctionalCaseCustomField::getFieldId).distinct().toList(); List<String> fieldIds = functionalCaseCustomFields.stream().map(FunctionalCaseCustomField::getFieldId).distinct().toList();
CustomFieldExample customFieldExample = new CustomFieldExample(); CustomFieldExample customFieldExample = new CustomFieldExample();
customFieldExample.createCriteria().andIdIn(fieldIds); customFieldExample.createCriteria().andIdIn(fieldIds);
List<CustomField> customFields = customFieldMapper.selectByExample(customFieldExample); List<CustomField> customFields = customFieldMapper.selectByExample(customFieldExample);
customFields.forEach(t->{ customFields.forEach(t -> {
OptionDTO optionDTO = new OptionDTO(); OptionDTO optionDTO = new OptionDTO();
optionDTO.setId(t.getName()); optionDTO.setId(t.getName());
optionDTO.setName(fieldValueMap.get(t.getId())); optionDTO.setName(fieldValueMap.get(t.getId()));
@ -118,15 +113,15 @@ public class FunctionalCaseNoticeService {
return optionDTOList; return optionDTOList;
} }
public FunctionalCaseDTO getMainFunctionalCaseDTO(FunctionalCaseAddRequest request) { public FunctionalCaseDTO getMainFunctionalCaseDTO(String name, String caseEditType, List<CaseCustomsFieldDTO> customsFields) {
String userId = SessionUtils.getUserId(); String userId = SessionUtils.getUserId();
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO(); FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
functionalCaseDTO.setName(request.getName()); functionalCaseDTO.setName(name);
functionalCaseDTO.setCaseEditType(request.getCaseEditType()); functionalCaseDTO.setCaseEditType(caseEditType);
functionalCaseDTO.setCreateUser(userId); functionalCaseDTO.setCreateUser(userId);
List<OptionDTO>fields = new ArrayList<>(); List<OptionDTO> fields = new ArrayList<>();
if (CollectionUtils.isNotEmpty(request.getCustomsFields())){ if (CollectionUtils.isNotEmpty(customsFields)) {
for (CaseCustomsFieldDTO customsFieldDTO : request.getCustomsFields()) { for (CaseCustomsFieldDTO customsFieldDTO : customsFields) {
OptionDTO optionDTO = new OptionDTO(); OptionDTO optionDTO = new OptionDTO();
CustomField customField = customFieldMapper.selectByPrimaryKey(customsFieldDTO.getFieldId()); CustomField customField = customFieldMapper.selectByPrimaryKey(customsFieldDTO.getFieldId());
if (customField == null) { if (customField == null) {
@ -142,5 +137,19 @@ public class FunctionalCaseNoticeService {
} }
public FunctionalCaseDTO getDeleteFunctionalCaseDTO(String id){
String userId = SessionUtils.getUserId();
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(id);
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
Optional.ofNullable(functionalCase).ifPresent(functional -> {
functionalCaseDTO.setName(functionalCase.getName());
functionalCaseDTO.setCaseEditType(functionalCase.getCaseEditType());
functionalCaseDTO.setCreateUser(userId);
List<OptionDTO> customFields = getCustomFields(id);
functionalCaseDTO.setFields(customFields);
});
return functionalCaseDTO;
}
} }

View File

@ -13,14 +13,14 @@ import io.metersphere.functional.request.FunctionalCaseDeleteRequest;
import io.metersphere.functional.request.FunctionalCaseEditRequest; import io.metersphere.functional.request.FunctionalCaseEditRequest;
import io.metersphere.functional.result.FunctionalCaseResultCode; import io.metersphere.functional.result.FunctionalCaseResultCode;
import io.metersphere.project.service.ProjectTemplateService; import io.metersphere.project.service.ProjectTemplateService;
import io.metersphere.sdk.constants.*; import io.metersphere.sdk.constants.ApplicationNumScope;
import io.metersphere.sdk.constants.FunctionalCaseExecuteResult;
import io.metersphere.sdk.constants.FunctionalCaseReviewStatus;
import io.metersphere.sdk.constants.TemplateScene;
import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.MsFileUtils;
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO; import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
import io.metersphere.system.dto.sdk.TemplateDTO; import io.metersphere.system.dto.sdk.TemplateDTO;
import io.metersphere.system.file.FileRequest;
import io.metersphere.system.file.MinioRepository;
import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.uid.IDGenerator;
import io.metersphere.system.uid.NumGenerator; import io.metersphere.system.uid.NumGenerator;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -32,6 +32,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -45,9 +46,6 @@ public class FunctionalCaseService {
public static final int ORDER_STEP = 5000; public static final int ORDER_STEP = 5000;
@Resource
private MinioRepository minioRepository;
@Resource @Resource
private ExtFunctionalCaseMapper extFunctionalCaseMapper; private ExtFunctionalCaseMapper extFunctionalCaseMapper;
@ -70,7 +68,7 @@ public class FunctionalCaseService {
private FunctionalCaseFollowerMapper functionalCaseFollowerMapper; private FunctionalCaseFollowerMapper functionalCaseFollowerMapper;
@Resource @Resource
private FunctionalCaseCommentService functionalCaseCommentService; private DeleteFunctionalCaseService deleteFunctionalCaseService;
public FunctionalCase addFunctionalCase(FunctionalCaseAddRequest request, List<MultipartFile> files, String userId) { public FunctionalCase addFunctionalCase(FunctionalCaseAddRequest request, List<MultipartFile> files, String userId) {
String caseId = IDGenerator.nextStr(); String caseId = IDGenerator.nextStr();
@ -78,7 +76,7 @@ public class FunctionalCaseService {
FunctionalCase functionalCase = addCase(caseId, request, userId); FunctionalCase functionalCase = addCase(caseId, request, userId);
//上传文件 //上传文件
uploadFile(request, caseId, files, true, userId); functionalCaseAttachmentService.uploadFile(request, caseId, files, true, userId);
//关联附件 //关联附件
functionalCaseAttachmentService.relateFileMeta(request.getRelateFileMetaIds(), caseId, userId); functionalCaseAttachmentService.relateFileMeta(request.getRelateFileMetaIds(), caseId, userId);
@ -133,30 +131,6 @@ public class FunctionalCaseService {
return bigDecimal.intValue(); return bigDecimal.intValue();
} }
/**
* 功能用例上传附件
*
* @param request
* @param files
*/
public void uploadFile(FunctionalCaseAddRequest request, String caseId, List<MultipartFile> files, Boolean isLocal, String userId) {
if (CollectionUtils.isNotEmpty(files)) {
files.forEach(file -> {
String fileId = IDGenerator.nextStr();
FileRequest fileRequest = new FileRequest();
fileRequest.setFileName(file.getName());
fileRequest.setResourceId(MsFileUtils.FUNCTIONAL_CASE_DIR_NAME + "/" + request.getProjectId() + fileId);
fileRequest.setStorage(StorageType.MINIO.name());
try {
minioRepository.saveFile(file, fileRequest);
} catch (Exception e) {
throw new MSException("save file error");
}
functionalCaseAttachmentService.saveCaseAttachment(fileId, file, caseId, isLocal, userId);
});
}
}
/** /**
* 查看用例获取详情 * 查看用例获取详情
@ -243,11 +217,11 @@ public class FunctionalCaseService {
//处理删除文件id //处理删除文件id
if (CollectionUtils.isNotEmpty(request.getDeleteFileMetaIds())) { if (CollectionUtils.isNotEmpty(request.getDeleteFileMetaIds())) {
this.deleteFile(request.getDeleteFileMetaIds(), request); functionalCaseAttachmentService.deleteCaseAttachment(request.getDeleteFileMetaIds(), request.getId(), request.getProjectId());
} }
//上传新文件 //上传新文件
uploadFile(request, request.getId(), files, true, userId); functionalCaseAttachmentService.uploadFile(request, request.getId(), files, true, userId);
//关联新附件 //关联新附件
functionalCaseAttachmentService.relateFileMeta(request.getRelateFileMetaIds(), request.getId(), userId); functionalCaseAttachmentService.relateFileMeta(request.getRelateFileMetaIds(), request.getId(), userId);
@ -269,27 +243,6 @@ public class FunctionalCaseService {
extFunctionalCaseMapper.updateFunctionalCaseModule(refId, moduleId); extFunctionalCaseMapper.updateFunctionalCaseModule(refId, moduleId);
} }
private void deleteFile(List<String> deleteFileMetaIds, FunctionalCaseEditRequest request) {
List<FunctionalCaseAttachment> caseAttachments = functionalCaseAttachmentService.deleteCaseAttachment(deleteFileMetaIds, request.getId());
if (CollectionUtils.isNotEmpty(caseAttachments)) {
//删除本地上传的minio文件
deleteMinioFile(caseAttachments, request.getProjectId());
}
}
private void deleteMinioFile(List<FunctionalCaseAttachment> files, String projectId) {
files.forEach(file -> {
FileRequest fileRequest = new FileRequest();
fileRequest.setFileName(file.getFileName());
fileRequest.setResourceId(MsFileUtils.FUNCTIONAL_CASE_DIR_NAME + "/" + projectId + file.getFileId());
fileRequest.setStorage(StorageType.MINIO.name());
try {
minioRepository.delete(fileRequest);
} catch (Exception e) {
throw new MSException("delete file error");
}
});
}
private void updateCase(FunctionalCaseEditRequest request, String userId, FunctionalCase functionalCase) { private void updateCase(FunctionalCaseEditRequest request, String userId, FunctionalCase functionalCase) {
functionalCase.setUpdateUser(userId); functionalCase.setUpdateUser(userId);
@ -357,7 +310,8 @@ public class FunctionalCaseService {
if (versionDTOList.size() > 1) { if (versionDTOList.size() > 1) {
//存在多个版本 //存在多个版本
List<String> ids = versionDTOList.stream().map(FunctionalCaseVersionDTO::getId).collect(Collectors.toList()); List<String> ids = versionDTOList.stream().map(FunctionalCaseVersionDTO::getId).collect(Collectors.toList());
handleFunctionalCaseByVersions(request, ids, userId); String projectId = versionDTOList.get(0).getProjectId();
handleFunctionalCaseByVersions(request, projectId, ids, userId);
} else { } else {
//只有一个版本 直接放入回收站 //只有一个版本 直接放入回收站
doDelete(request.getId(), userId); doDelete(request.getId(), userId);
@ -373,27 +327,18 @@ public class FunctionalCaseService {
* @param ids * @param ids
* @param userId * @param userId
*/ */
private void handleFunctionalCaseByVersions(FunctionalCaseDeleteRequest request, List<String> ids, String userId) { private void handleFunctionalCaseByVersions(FunctionalCaseDeleteRequest request, String projectId, List<String> ids, String userId) {
if (request.getDeleteAll()) { if (request.getDeleteAll()) {
//删除所有版本 //删除所有版本
ids.forEach(id -> { ids.forEach(id -> {
doDelete(id, userId); doDelete(id, userId);
}); });
} else { } else {
//删除指定版本 //删除指定版本(用例多版本情况下 删除单个版本用例)
deleteFunctionalCaseSingle(request.getId()); deleteFunctionalCaseService.deleteFunctionalCaseResource(Arrays.asList(request.getId()), projectId);
} }
} }
/**
* 用例多版本情况下 删除单个版本用例
*
* @param functionalCaseId
*/
private void deleteFunctionalCaseSingle(String functionalCaseId) {
//TODO 删除各种关联关系 1.测试用例(接口/场景/ui/性能) 2.关联缺陷(是否需要同步) 3.关联需求(是否需要同步) 4.依赖关系 5.关联评审 6.操作记录 7.关联测试计划 8.评论 9.附件 10.自定义字段 11.用例基本信息(主表附属表)
}
private void doDelete(String id, String userId) { private void doDelete(String id, String userId) {
FunctionalCase functionalCase = new FunctionalCase(); FunctionalCase functionalCase = new FunctionalCase();

View File

@ -0,0 +1,30 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.service.CleanupFunctionalCaseResourceService;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
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;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class CleanupFunctionalCaseResourceTest {
@Resource
private CleanupFunctionalCaseResourceService cleanupFunctionalCaseResourceService;
@Test
@Order(1)
@Sql(scripts = {"/dml/init_clean_up_resource_test.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void testCleanupResource() throws Exception {
cleanupFunctionalCaseResourceService.deleteResources("test_project_id");
cleanupFunctionalCaseResourceService.deleteResources("TEST_CLEAN_UP_PROJECT_ID");
}
}

View File

@ -259,6 +259,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
FunctionalCaseDeleteRequest request = new FunctionalCaseDeleteRequest(); FunctionalCaseDeleteRequest request = new FunctionalCaseDeleteRequest();
request.setId("TEST_FUNCTIONAL_CASE_ID"); request.setId("TEST_FUNCTIONAL_CASE_ID");
request.setDeleteAll(false); request.setDeleteAll(false);
request.setProjectId(DEFAULT_PROJECT_ID);
MvcResult mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_DELETE_URL, request); MvcResult mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_DELETE_URL, request);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class); ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
@ -267,7 +268,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
request.setId("TEST_FUNCTIONAL_CASE_ID_1"); request.setId("TEST_FUNCTIONAL_CASE_ID_1");
request.setDeleteAll(false); request.setDeleteAll(false);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_DELETE_URL, request); this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_DELETE_URL, request);
request.setId("TEST_FUNCTIONAL_CASE_ID_1"); request.setId("TEST_FUNCTIONAL_CASE_ID_3");
request.setDeleteAll(true); request.setDeleteAll(true);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_DELETE_URL, request); this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_DELETE_URL, request);
} }

View File

@ -0,0 +1,15 @@
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('CLEAN_UP_FUNCTIONAL_CASE_ID', 1, 'TEST_MOUDLE_ID', 'TEST_CLEAN_UP_PROJECT_ID', '100001', '测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'v1.0.0', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('CLEAN_UP_FUNCTIONAL_CASE_ID_1', 2, 'TEST_MOUDLE_ID', 'TEST_CLEAN_UP_PROJECT_ID', '100001', '测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);

View File

@ -13,6 +13,8 @@ VALUES ('TEST_FUNCTIONAL_CASE_ID_2', 3, 'TEST_MOUDLE_ID', '100001100001', '10000
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time) INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('TEST_FUNCTIONAL_CASE_ID_3', 3, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL); VALUES ('TEST_FUNCTIONAL_CASE_ID_3', 3, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('TEST_FUNCTIONAL_CASE_ID_4', 4, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID', 'STEP', '1111', NULL, NULL, 'TEST'); INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID', 'STEP', '1111', NULL, NULL, 'TEST');

View File

@ -1,5 +1,7 @@
package io.metersphere.project.service; package io.metersphere.project.service;
import io.metersphere.project.domain.ProjectApplicationExample;
import io.metersphere.project.mapper.ProjectApplicationMapper;
import io.metersphere.sdk.util.LogUtils; import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.sechedule.ScheduleService; import io.metersphere.system.sechedule.ScheduleService;
import io.metersphere.system.service.CleanupProjectResourceService; import io.metersphere.system.service.CleanupProjectResourceService;
@ -14,10 +16,15 @@ public class CleanupApplicationResourceService implements CleanupProjectResource
@Resource @Resource
private ScheduleService scheduleService; private ScheduleService scheduleService;
@Resource
private ProjectApplicationMapper projectApplicationMapper;
@Override @Override
public void deleteResources(String projectId) { public void deleteResources(String projectId) {
scheduleService.deleteByProjectId(projectId); scheduleService.deleteByProjectId(projectId);
ProjectApplicationExample example = new ProjectApplicationExample();
example.createCriteria().andProjectIdEqualTo(projectId);
projectApplicationMapper.deleteByExample(example);
} }
@Override @Override