refactor(测试计划): 优化测试计划报告
This commit is contained in:
parent
02a237af85
commit
21fbfee0b4
|
@ -1,15 +1,12 @@
|
||||||
package io.metersphere.plan.domain;
|
package io.metersphere.plan.domain;
|
||||||
|
|
||||||
import io.metersphere.validation.groups.Created;
|
import io.metersphere.validation.groups.*;
|
||||||
import io.metersphere.validation.groups.Updated;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.*;
|
||||||
import jakarta.validation.constraints.Size;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class TestPlanReport implements Serializable {
|
public class TestPlanReport implements Serializable {
|
||||||
|
@ -43,12 +40,12 @@ public class TestPlanReport implements Serializable {
|
||||||
@Schema(description = "触发类型")
|
@Schema(description = "触发类型")
|
||||||
private String triggerMode;
|
private String triggerMode;
|
||||||
|
|
||||||
@Schema(description = "执行状态;未执行, 执行中, 已停止, 已完成;", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "执行状态: 未执行, 执行中, 已停止, 已完成;", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
@NotBlank(message = "{test_plan_report.exec_status.not_blank}", groups = {Created.class})
|
@NotBlank(message = "{test_plan_report.exec_status.not_blank}", groups = {Created.class})
|
||||||
@Size(min = 1, max = 50, message = "{test_plan_report.exec_status.length_range}", groups = {Created.class, Updated.class})
|
@Size(min = 1, max = 50, message = "{test_plan_report.exec_status.length_range}", groups = {Created.class, Updated.class})
|
||||||
private String execStatus;
|
private String execStatus;
|
||||||
|
|
||||||
@Schema(description = "结果状态;成功, 失败, 阻塞, 误报")
|
@Schema(description = "结果状态: 成功, 失败, 阻塞, 误报")
|
||||||
private String resultStatus;
|
private String resultStatus;
|
||||||
|
|
||||||
@Schema(description = "通过阈值", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "通过阈值", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ -59,6 +56,19 @@ public class TestPlanReport implements Serializable {
|
||||||
@Schema(description = "通过率")
|
@Schema(description = "通过率")
|
||||||
private Long passRate;
|
private Long passRate;
|
||||||
|
|
||||||
|
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{test_plan_report.project_id.not_blank}", groups = {Created.class})
|
||||||
|
@Size(min = 1, max = 50, message = "{test_plan_report.project_id.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@Schema(description = "是否是集成报告", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "{test_plan_report.integrated.not_blank}", groups = {Created.class})
|
||||||
|
private Boolean integrated;
|
||||||
|
|
||||||
|
@Schema(description = "是否删除", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "{test_plan_report.deleted.not_blank}", groups = {Created.class})
|
||||||
|
private Boolean deleted;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public enum Column {
|
public enum Column {
|
||||||
|
@ -73,7 +83,10 @@ public class TestPlanReport implements Serializable {
|
||||||
execStatus("exec_status", "execStatus", "VARCHAR", false),
|
execStatus("exec_status", "execStatus", "VARCHAR", false),
|
||||||
resultStatus("result_status", "resultStatus", "VARCHAR", false),
|
resultStatus("result_status", "resultStatus", "VARCHAR", false),
|
||||||
passThreshold("pass_threshold", "passThreshold", "VARCHAR", false),
|
passThreshold("pass_threshold", "passThreshold", "VARCHAR", false),
|
||||||
passRate("pass_rate", "passRate", "DECIMAL", false);
|
passRate("pass_rate", "passRate", "DECIMAL", false),
|
||||||
|
projectId("project_id", "projectId", "VARCHAR", false),
|
||||||
|
integrated("integrated", "integrated", "BIT", false),
|
||||||
|
deleted("deleted", "deleted", "BIT", false);
|
||||||
|
|
||||||
private static final String BEGINNING_DELIMITER = "`";
|
private static final String BEGINNING_DELIMITER = "`";
|
||||||
|
|
||||||
|
|
|
@ -903,6 +903,196 @@ public class TestPlanReportExample {
|
||||||
addCriterion("pass_rate not between", value1, value2, "passRate");
|
addCriterion("pass_rate not between", value1, value2, "passRate");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdIsNull() {
|
||||||
|
addCriterion("project_id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdIsNotNull() {
|
||||||
|
addCriterion("project_id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdEqualTo(String value) {
|
||||||
|
addCriterion("project_id =", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdNotEqualTo(String value) {
|
||||||
|
addCriterion("project_id <>", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdGreaterThan(String value) {
|
||||||
|
addCriterion("project_id >", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("project_id >=", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdLessThan(String value) {
|
||||||
|
addCriterion("project_id <", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("project_id <=", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdLike(String value) {
|
||||||
|
addCriterion("project_id like", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdNotLike(String value) {
|
||||||
|
addCriterion("project_id not like", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdIn(List<String> values) {
|
||||||
|
addCriterion("project_id in", values, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdNotIn(List<String> values) {
|
||||||
|
addCriterion("project_id not in", values, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("project_id between", value1, value2, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("project_id not between", value1, value2, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedIsNull() {
|
||||||
|
addCriterion("integrated is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedIsNotNull() {
|
||||||
|
addCriterion("integrated is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedEqualTo(Boolean value) {
|
||||||
|
addCriterion("integrated =", value, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedNotEqualTo(Boolean value) {
|
||||||
|
addCriterion("integrated <>", value, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedGreaterThan(Boolean value) {
|
||||||
|
addCriterion("integrated >", value, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedGreaterThanOrEqualTo(Boolean value) {
|
||||||
|
addCriterion("integrated >=", value, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedLessThan(Boolean value) {
|
||||||
|
addCriterion("integrated <", value, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedLessThanOrEqualTo(Boolean value) {
|
||||||
|
addCriterion("integrated <=", value, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedIn(List<Boolean> values) {
|
||||||
|
addCriterion("integrated in", values, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedNotIn(List<Boolean> values) {
|
||||||
|
addCriterion("integrated not in", values, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedBetween(Boolean value1, Boolean value2) {
|
||||||
|
addCriterion("integrated between", value1, value2, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIntegratedNotBetween(Boolean value1, Boolean value2) {
|
||||||
|
addCriterion("integrated not between", value1, value2, "integrated");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedIsNull() {
|
||||||
|
addCriterion("deleted is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedIsNotNull() {
|
||||||
|
addCriterion("deleted is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedEqualTo(Boolean value) {
|
||||||
|
addCriterion("deleted =", value, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedNotEqualTo(Boolean value) {
|
||||||
|
addCriterion("deleted <>", value, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedGreaterThan(Boolean value) {
|
||||||
|
addCriterion("deleted >", value, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedGreaterThanOrEqualTo(Boolean value) {
|
||||||
|
addCriterion("deleted >=", value, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedLessThan(Boolean value) {
|
||||||
|
addCriterion("deleted <", value, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedLessThanOrEqualTo(Boolean value) {
|
||||||
|
addCriterion("deleted <=", value, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedIn(List<Boolean> values) {
|
||||||
|
addCriterion("deleted in", values, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedNotIn(List<Boolean> values) {
|
||||||
|
addCriterion("deleted not in", values, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedBetween(Boolean value1, Boolean value2) {
|
||||||
|
addCriterion("deleted between", value1, value2, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andDeletedNotBetween(Boolean value1, Boolean value2) {
|
||||||
|
addCriterion("deleted not between", value1, value2, "deleted");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Criteria extends GeneratedCriteria {
|
public static class Criteria extends GeneratedCriteria {
|
||||||
|
|
|
@ -2,9 +2,8 @@ package io.metersphere.plan.mapper;
|
||||||
|
|
||||||
import io.metersphere.plan.domain.TestPlanReport;
|
import io.metersphere.plan.domain.TestPlanReport;
|
||||||
import io.metersphere.plan.domain.TestPlanReportExample;
|
import io.metersphere.plan.domain.TestPlanReportExample;
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
public interface TestPlanReportMapper {
|
public interface TestPlanReportMapper {
|
||||||
long countByExample(TestPlanReportExample example);
|
long countByExample(TestPlanReportExample example);
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
<result column="result_status" jdbcType="VARCHAR" property="resultStatus" />
|
<result column="result_status" jdbcType="VARCHAR" property="resultStatus" />
|
||||||
<result column="pass_threshold" jdbcType="VARCHAR" property="passThreshold" />
|
<result column="pass_threshold" jdbcType="VARCHAR" property="passThreshold" />
|
||||||
<result column="pass_rate" jdbcType="DECIMAL" property="passRate" />
|
<result column="pass_rate" jdbcType="DECIMAL" property="passRate" />
|
||||||
|
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
||||||
|
<result column="integrated" jdbcType="BIT" property="integrated" />
|
||||||
|
<result column="deleted" jdbcType="BIT" property="deleted" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<sql id="Example_Where_Clause">
|
<sql id="Example_Where_Clause">
|
||||||
<where>
|
<where>
|
||||||
|
@ -75,7 +78,7 @@
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, test_plan_id, `name`, create_user, create_time, start_time, end_time, trigger_mode,
|
id, test_plan_id, `name`, create_user, create_time, start_time, end_time, trigger_mode,
|
||||||
exec_status, result_status, pass_threshold, pass_rate
|
exec_status, result_status, pass_threshold, pass_rate, project_id, integrated, deleted
|
||||||
</sql>
|
</sql>
|
||||||
<select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanReportExample" resultMap="BaseResultMap">
|
<select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanReportExample" resultMap="BaseResultMap">
|
||||||
select
|
select
|
||||||
|
@ -111,12 +114,14 @@
|
||||||
insert into test_plan_report (id, test_plan_id, `name`,
|
insert into test_plan_report (id, test_plan_id, `name`,
|
||||||
create_user, create_time, start_time,
|
create_user, create_time, start_time,
|
||||||
end_time, trigger_mode, exec_status,
|
end_time, trigger_mode, exec_status,
|
||||||
result_status, pass_threshold, pass_rate
|
result_status, pass_threshold, pass_rate,
|
||||||
|
project_id, integrated, deleted
|
||||||
)
|
)
|
||||||
values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
||||||
#{createUser,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{startTime,jdbcType=BIGINT},
|
#{createUser,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{startTime,jdbcType=BIGINT},
|
||||||
#{endTime,jdbcType=BIGINT}, #{triggerMode,jdbcType=VARCHAR}, #{execStatus,jdbcType=VARCHAR},
|
#{endTime,jdbcType=BIGINT}, #{triggerMode,jdbcType=VARCHAR}, #{execStatus,jdbcType=VARCHAR},
|
||||||
#{resultStatus,jdbcType=VARCHAR}, #{passThreshold,jdbcType=VARCHAR}, #{passRate,jdbcType=DECIMAL}
|
#{resultStatus,jdbcType=VARCHAR}, #{passThreshold,jdbcType=VARCHAR}, #{passRate,jdbcType=DECIMAL},
|
||||||
|
#{projectId,jdbcType=VARCHAR}, #{integrated,jdbcType=BIT}, #{deleted,jdbcType=BIT}
|
||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanReport">
|
<insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanReport">
|
||||||
|
@ -158,6 +163,15 @@
|
||||||
<if test="passRate != null">
|
<if test="passRate != null">
|
||||||
pass_rate,
|
pass_rate,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="projectId != null">
|
||||||
|
project_id,
|
||||||
|
</if>
|
||||||
|
<if test="integrated != null">
|
||||||
|
integrated,
|
||||||
|
</if>
|
||||||
|
<if test="deleted != null">
|
||||||
|
deleted,
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="id != null">
|
<if test="id != null">
|
||||||
|
@ -196,6 +210,15 @@
|
||||||
<if test="passRate != null">
|
<if test="passRate != null">
|
||||||
#{passRate,jdbcType=DECIMAL},
|
#{passRate,jdbcType=DECIMAL},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="projectId != null">
|
||||||
|
#{projectId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="integrated != null">
|
||||||
|
#{integrated,jdbcType=BIT},
|
||||||
|
</if>
|
||||||
|
<if test="deleted != null">
|
||||||
|
#{deleted,jdbcType=BIT},
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
<select id="countByExample" parameterType="io.metersphere.plan.domain.TestPlanReportExample" resultType="java.lang.Long">
|
<select id="countByExample" parameterType="io.metersphere.plan.domain.TestPlanReportExample" resultType="java.lang.Long">
|
||||||
|
@ -243,6 +266,15 @@
|
||||||
<if test="record.passRate != null">
|
<if test="record.passRate != null">
|
||||||
pass_rate = #{record.passRate,jdbcType=DECIMAL},
|
pass_rate = #{record.passRate,jdbcType=DECIMAL},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="record.projectId != null">
|
||||||
|
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.integrated != null">
|
||||||
|
integrated = #{record.integrated,jdbcType=BIT},
|
||||||
|
</if>
|
||||||
|
<if test="record.deleted != null">
|
||||||
|
deleted = #{record.deleted,jdbcType=BIT},
|
||||||
|
</if>
|
||||||
</set>
|
</set>
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
@ -261,7 +293,10 @@
|
||||||
exec_status = #{record.execStatus,jdbcType=VARCHAR},
|
exec_status = #{record.execStatus,jdbcType=VARCHAR},
|
||||||
result_status = #{record.resultStatus,jdbcType=VARCHAR},
|
result_status = #{record.resultStatus,jdbcType=VARCHAR},
|
||||||
pass_threshold = #{record.passThreshold,jdbcType=VARCHAR},
|
pass_threshold = #{record.passThreshold,jdbcType=VARCHAR},
|
||||||
pass_rate = #{record.passRate,jdbcType=DECIMAL}
|
pass_rate = #{record.passRate,jdbcType=DECIMAL},
|
||||||
|
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||||
|
integrated = #{record.integrated,jdbcType=BIT},
|
||||||
|
deleted = #{record.deleted,jdbcType=BIT}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
|
@ -302,6 +337,15 @@
|
||||||
<if test="passRate != null">
|
<if test="passRate != null">
|
||||||
pass_rate = #{passRate,jdbcType=DECIMAL},
|
pass_rate = #{passRate,jdbcType=DECIMAL},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="projectId != null">
|
||||||
|
project_id = #{projectId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="integrated != null">
|
||||||
|
integrated = #{integrated,jdbcType=BIT},
|
||||||
|
</if>
|
||||||
|
<if test="deleted != null">
|
||||||
|
deleted = #{deleted,jdbcType=BIT},
|
||||||
|
</if>
|
||||||
</set>
|
</set>
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
|
@ -317,20 +361,25 @@
|
||||||
exec_status = #{execStatus,jdbcType=VARCHAR},
|
exec_status = #{execStatus,jdbcType=VARCHAR},
|
||||||
result_status = #{resultStatus,jdbcType=VARCHAR},
|
result_status = #{resultStatus,jdbcType=VARCHAR},
|
||||||
pass_threshold = #{passThreshold,jdbcType=VARCHAR},
|
pass_threshold = #{passThreshold,jdbcType=VARCHAR},
|
||||||
pass_rate = #{passRate,jdbcType=DECIMAL}
|
pass_rate = #{passRate,jdbcType=DECIMAL},
|
||||||
|
project_id = #{projectId,jdbcType=VARCHAR},
|
||||||
|
integrated = #{integrated,jdbcType=BIT},
|
||||||
|
deleted = #{deleted,jdbcType=BIT}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
<insert id="batchInsert" parameterType="map">
|
<insert id="batchInsert" parameterType="map">
|
||||||
insert into test_plan_report
|
insert into test_plan_report
|
||||||
(id, test_plan_id, `name`, create_user, create_time, start_time, end_time, trigger_mode,
|
(id, test_plan_id, `name`, create_user, create_time, start_time, end_time, trigger_mode,
|
||||||
exec_status, result_status, pass_threshold, pass_rate)
|
exec_status, result_status, pass_threshold, pass_rate, project_id, integrated,
|
||||||
|
deleted)
|
||||||
values
|
values
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{item.id,jdbcType=VARCHAR}, #{item.testPlanId,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR},
|
(#{item.id,jdbcType=VARCHAR}, #{item.testPlanId,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR},
|
||||||
#{item.createUser,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.startTime,jdbcType=BIGINT},
|
#{item.createUser,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.startTime,jdbcType=BIGINT},
|
||||||
#{item.endTime,jdbcType=BIGINT}, #{item.triggerMode,jdbcType=VARCHAR}, #{item.execStatus,jdbcType=VARCHAR},
|
#{item.endTime,jdbcType=BIGINT}, #{item.triggerMode,jdbcType=VARCHAR}, #{item.execStatus,jdbcType=VARCHAR},
|
||||||
#{item.resultStatus,jdbcType=VARCHAR}, #{item.passThreshold,jdbcType=VARCHAR},
|
#{item.resultStatus,jdbcType=VARCHAR}, #{item.passThreshold,jdbcType=VARCHAR},
|
||||||
#{item.passRate,jdbcType=DECIMAL})
|
#{item.passRate,jdbcType=DECIMAL}, #{item.projectId,jdbcType=VARCHAR}, #{item.integrated,jdbcType=BIT},
|
||||||
|
#{item.deleted,jdbcType=BIT})
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="batchInsertSelective" parameterType="map">
|
<insert id="batchInsertSelective" parameterType="map">
|
||||||
|
@ -379,6 +428,15 @@
|
||||||
<if test="'pass_rate'.toString() == column.value">
|
<if test="'pass_rate'.toString() == column.value">
|
||||||
#{item.passRate,jdbcType=DECIMAL}
|
#{item.passRate,jdbcType=DECIMAL}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="'project_id'.toString() == column.value">
|
||||||
|
#{item.projectId,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="'integrated'.toString() == column.value">
|
||||||
|
#{item.integrated,jdbcType=BIT}
|
||||||
|
</if>
|
||||||
|
<if test="'deleted'.toString() == column.value">
|
||||||
|
#{item.deleted,jdbcType=BIT}
|
||||||
|
</if>
|
||||||
</foreach>
|
</foreach>
|
||||||
)
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
|
|
|
@ -77,6 +77,9 @@ CREATE TABLE IF NOT EXISTS test_plan_report(
|
||||||
`result_status` VARCHAR(50) DEFAULT '-' COMMENT '结果状态: 成功, 失败, 阻塞, 误报' ,
|
`result_status` VARCHAR(50) DEFAULT '-' COMMENT '结果状态: 成功, 失败, 阻塞, 误报' ,
|
||||||
`pass_threshold` VARCHAR(100) NOT NULL COMMENT '通过阈值' ,
|
`pass_threshold` VARCHAR(100) NOT NULL COMMENT '通过阈值' ,
|
||||||
`pass_rate` DECIMAL COMMENT '通过率' ,
|
`pass_rate` DECIMAL COMMENT '通过率' ,
|
||||||
|
`project_id` VARCHAR(50) NOT NULL COMMENT '项目id' ,
|
||||||
|
`integrated` BIT NOT NULL DEFAULT 0 COMMENT '是否是集成报告' ,
|
||||||
|
`deleted` BIT NOT NULL DEFAULT 0 COMMENT '是否删除' ,
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试计划报告';
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试计划报告';
|
||||||
|
|
||||||
|
@ -87,6 +90,9 @@ CREATE INDEX idx_create_time ON test_plan_report(create_time);
|
||||||
CREATE INDEX idx_exec_status ON test_plan_report(exec_status);
|
CREATE INDEX idx_exec_status ON test_plan_report(exec_status);
|
||||||
CREATE INDEX idx_result_status ON test_plan_report(result_status);
|
CREATE INDEX idx_result_status ON test_plan_report(result_status);
|
||||||
CREATE INDEX idx_pass_rate ON test_plan_report(pass_rate);
|
CREATE INDEX idx_pass_rate ON test_plan_report(pass_rate);
|
||||||
|
CREATE INDEX idx_project_id ON test_plan_report(project_id);
|
||||||
|
CREATE INDEX idx_integrated ON test_plan_report(integrated);
|
||||||
|
CREATE INDEX idx_deleted ON test_plan_report(deleted);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS test_plan_report_summary(
|
CREATE TABLE IF NOT EXISTS test_plan_report_summary(
|
||||||
`id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
|
`id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
|
||||||
|
|
|
@ -48,14 +48,14 @@ public class ApiReportLogService {
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLog(String id) {
|
public LogDTO updateLog(String id) {
|
||||||
ApiReport apiReport = apiReportMapper.selectByPrimaryKey(id);
|
ApiReport apiReport = apiReportMapper.selectByPrimaryKey(id);
|
||||||
Project project = projectMapper.selectByPrimaryKey(apiReport.getProjectId());
|
Project project = projectMapper.selectByPrimaryKey(apiReport.getProjectId());
|
||||||
LogDTO dto = new LogDTO(
|
LogDTO dto = new LogDTO(
|
||||||
apiReport.getProjectId(),
|
apiReport.getProjectId(),
|
||||||
project.getOrganizationId(),
|
project.getOrganizationId(),
|
||||||
apiReport.getId(),
|
apiReport.getId(),
|
||||||
apiReport.getUpdateUser(),
|
null,
|
||||||
OperationLogType.UPDATE.name(),
|
OperationLogType.UPDATE.name(),
|
||||||
OperationLogModule.API_REPORT,
|
OperationLogModule.API_REPORT,
|
||||||
apiReport.getName());
|
apiReport.getName());
|
||||||
|
@ -63,7 +63,7 @@ public class ApiReportLogService {
|
||||||
dto.setPath("/api/report/case/rename/" + apiReport.getId() + "/" + apiReport.getName());
|
dto.setPath("/api/report/case/rename/" + apiReport.getId() + "/" + apiReport.getName());
|
||||||
dto.setMethod(HttpMethodConstants.GET.name());
|
dto.setMethod(HttpMethodConstants.GET.name());
|
||||||
dto.setOriginalValue(JSON.toJSONBytes(apiReport));
|
dto.setOriginalValue(JSON.toJSONBytes(apiReport));
|
||||||
operationLogService.add(dto);
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void batchDeleteLog(List<String> ids, String userId, String projectId) {
|
public void batchDeleteLog(List<String> ids, String userId, String projectId) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class OperationLogModule {
|
||||||
public static final String API_TEST_MANAGEMENT_RECYCLE = "API_TEST_MANAGEMENT_RECYCLE";
|
public static final String API_TEST_MANAGEMENT_RECYCLE = "API_TEST_MANAGEMENT_RECYCLE";
|
||||||
|
|
||||||
public static final String API_REPORT = "API_TEST_REPORT_CASE";
|
public static final String API_REPORT = "API_TEST_REPORT_CASE";
|
||||||
public static final String API_TEST_REPORT_SCENARIO = "API_TEST_REPORT_SCENARIO";
|
public static final String API_TEST_REPORT_SCENARIO = "API_TEST_REPORT_SCENARIO";
|
||||||
public static final String AUTH_TITLE = "AUTH_TITLE";
|
public static final String AUTH_TITLE = "AUTH_TITLE";
|
||||||
public static final String PROJECT_ENVIRONMENT_SETTING = "PROJECT_ENVIRONMENT_SETTING";
|
public static final String PROJECT_ENVIRONMENT_SETTING = "PROJECT_ENVIRONMENT_SETTING";
|
||||||
public static final String PROJECT_PROJECT_MANAGER = "PROJECT_PROJECT_MANAGER";
|
public static final String PROJECT_PROJECT_MANAGER = "PROJECT_PROJECT_MANAGER";
|
||||||
|
@ -170,4 +170,6 @@ public class OperationLogModule {
|
||||||
public static final String SETTING_ORGANIZATION_TASK_CENTER = "SETTING_ORGANIZATION_TASK_CENTER";
|
public static final String SETTING_ORGANIZATION_TASK_CENTER = "SETTING_ORGANIZATION_TASK_CENTER";
|
||||||
//项目任务中心:PROJECT_MANAGEMENT_TASK_CENTER
|
//项目任务中心:PROJECT_MANAGEMENT_TASK_CENTER
|
||||||
public static final String PROJECT_MANAGEMENT_TASK_CENTER = "PROJECT_MANAGEMENT_TASK_CENTER";
|
public static final String PROJECT_MANAGEMENT_TASK_CENTER = "PROJECT_MANAGEMENT_TASK_CENTER";
|
||||||
|
|
||||||
|
public static final String TEST_PLAN_REPORT = "TEST_PLAN_REPORT";
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,26 +4,28 @@ import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
|
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportDeleteRequest;
|
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportEditRequest;
|
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
|
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
|
||||||
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
|
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
|
||||||
import io.metersphere.plan.service.TestPlanManagementService;
|
import io.metersphere.plan.service.TestPlanManagementService;
|
||||||
|
import io.metersphere.plan.service.TestPlanReportLogService;
|
||||||
|
import io.metersphere.plan.service.TestPlanReportNoticeService;
|
||||||
import io.metersphere.plan.service.TestPlanReportService;
|
import io.metersphere.plan.service.TestPlanReportService;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
|
import io.metersphere.system.log.annotation.Log;
|
||||||
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
|
import io.metersphere.system.notice.annotation.SendNotice;
|
||||||
|
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
import io.metersphere.system.security.CheckOwner;
|
import io.metersphere.system.security.CheckOwner;
|
||||||
import io.metersphere.system.utils.PageUtils;
|
import io.metersphere.system.utils.PageUtils;
|
||||||
import io.metersphere.system.utils.Pager;
|
import io.metersphere.system.utils.Pager;
|
||||||
|
import io.metersphere.system.utils.SessionUtils;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -33,43 +35,46 @@ import java.util.List;
|
||||||
@Tag(name = "测试计划-报告")
|
@Tag(name = "测试计划-报告")
|
||||||
public class TestPlanReportController {
|
public class TestPlanReportController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanManagementService testPlanManagementService;
|
private TestPlanManagementService testPlanManagementService;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanReportService testPlanReportService;
|
private TestPlanReportService testPlanReportService;
|
||||||
|
|
||||||
@PostMapping("/page")
|
@PostMapping("/page")
|
||||||
@Operation(summary = "测试计划-报告-表格分页查询")
|
@Operation(summary = "测试计划-报告-表格分页查询")
|
||||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
|
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||||
public Pager<List<TestPlanReportPageResponse>> page(@Validated @RequestBody TestPlanReportPageRequest request) {
|
public Pager<List<TestPlanReportPageResponse>> page(@Validated @RequestBody TestPlanReportPageRequest request) {
|
||||||
testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
|
testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
|
||||||
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
|
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
|
||||||
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "tpr.create_time desc");
|
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "tpr.create_time desc");
|
||||||
return PageUtils.setPageInfo(page, testPlanReportService.page(request));
|
return PageUtils.setPageInfo(page, testPlanReportService.page(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/rename")
|
@PostMapping("/rename/{id}")
|
||||||
@Operation(summary = "测试计划-报告-重命名")
|
@Operation(summary = "测试计划-报告-重命名")
|
||||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_UPDATE)
|
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_UPDATE)
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
@CheckOwner(resourceId = "#request.getId()", resourceType = "test_plan_report")
|
||||||
public void rename(@Validated @RequestBody TestPlanReportEditRequest request) {
|
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#id)", msClass = TestPlanReportLogService.class)
|
||||||
testPlanReportService.rename(request);
|
public void rename(@PathVariable String id, @RequestBody Object name) {
|
||||||
}
|
testPlanReportService.rename(id, name.toString());
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/delete")
|
@GetMapping("/delete/{id}")
|
||||||
@Operation(summary = "测试计划-报告-删除")
|
@Operation(summary = "测试计划-报告-删除")
|
||||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_DELETE)
|
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_DELETE)
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
@CheckOwner(resourceId = "#id", resourceType = "test_plan_report")
|
||||||
public void delete(@Validated @RequestBody TestPlanReportDeleteRequest request) {
|
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = TestPlanReportLogService.class)
|
||||||
testPlanReportService.delete(request);
|
@SendNotice(taskType = NoticeConstants.TaskType.TEST_PLAN_REPORT_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getDto(#id)", targetClass = TestPlanReportNoticeService.class)
|
||||||
}
|
public void delete(@PathVariable String id) {
|
||||||
|
testPlanReportService.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/batch-delete")
|
@PostMapping("/batch-delete")
|
||||||
@Operation(summary = "测试计划-报告-批量删除")
|
@Operation(summary = "测试计划-报告-批量删除")
|
||||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_DELETE)
|
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_DELETE)
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||||
public void batchDelete(@Validated @RequestBody TestPlanReportBatchRequest request) {
|
public void batchDelete(@Validated @RequestBody TestPlanReportBatchRequest request) {
|
||||||
testPlanReportService.batchDelete(request);
|
testPlanReportService.batchDelete(request, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,7 @@ import lombok.EqualsAndHashCode;
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class TestPlanReportBatchRequest extends TableBatchRequest {
|
public class TestPlanReportBatchRequest extends TableBatchRequest {
|
||||||
|
|
||||||
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
@NotBlank(message = "{test_plan.project_id.not_blank}")
|
@NotBlank(message = "{test_plan.project_id.not_blank}")
|
||||||
private String projectId;
|
private String projectId;
|
||||||
|
|
||||||
@Schema(description = "类型", allowableValues = {"ALL: 全部", "TEST_PLAN: 独立", "GROUP: 聚合"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
@NotBlank(message = "{test_plan.type.not_blank}")
|
|
||||||
private String type;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,7 @@ import lombok.EqualsAndHashCode;
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class TestPlanReportPageRequest extends BasePageRequest {
|
public class TestPlanReportPageRequest extends BasePageRequest {
|
||||||
|
|
||||||
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
@NotBlank(message = "{test_plan.project_id.not_blank}")
|
@NotBlank(message = "{test_plan.project_id.not_blank}")
|
||||||
private String projectId;
|
private String projectId;
|
||||||
|
|
||||||
@Schema(description = "类型", allowableValues = {"ALL: 全部", "TEST_PLAN: 独立", "GROUP: 聚合"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
@NotBlank(message = "{test_plan.type.not_blank}")
|
|
||||||
private String type;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,27 +8,29 @@ import lombok.EqualsAndHashCode;
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class TestPlanReportPageResponse {
|
public class TestPlanReportPageResponse {
|
||||||
|
|
||||||
@Schema(description = "报告ID")
|
@Schema(description = "报告ID")
|
||||||
private String id;
|
private String id;
|
||||||
@Schema(description = "报告名称")
|
@Schema(description = "报告名称")
|
||||||
private String name;
|
private String name;
|
||||||
@Schema(description = "计划名称")
|
@Schema(description = "计划名称")
|
||||||
private String planName;
|
private String planName;
|
||||||
@Schema(description = "计划通过阈值")
|
@Schema(description = "计划通过阈值")
|
||||||
private String planPassThreshold;
|
private String planPassThreshold;
|
||||||
@Schema(description = "触发方式")
|
@Schema(description = "触发方式")
|
||||||
private String triggerMode;
|
private String triggerMode;
|
||||||
@Schema(description = "执行状态")
|
@Schema(description = "执行状态")
|
||||||
private String executeStatus;
|
private String execStatus;
|
||||||
@Schema(description = "执行结果")
|
@Schema(description = "执行结果")
|
||||||
private String resultStatus;
|
private String resultStatus;
|
||||||
@Schema(description = "通过率")
|
@Schema(description = "通过率")
|
||||||
private Double passRate;
|
private Double passRate;
|
||||||
@Schema(description = "创建人")
|
@Schema(description = "创建人")
|
||||||
private String createUser;
|
private String createUser;
|
||||||
@Schema(description = "创建人名称")
|
@Schema(description = "创建人名称")
|
||||||
private String createUserName;
|
private String createUserName;
|
||||||
@Schema(description = "创建时间")
|
@Schema(description = "创建时间")
|
||||||
private Long createTime;
|
private Long createTime;
|
||||||
|
@Schema(description = "是否是集合报告")
|
||||||
|
private boolean integrated;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,33 @@
|
||||||
package io.metersphere.plan.mapper;
|
package io.metersphere.plan.mapper;
|
||||||
|
|
||||||
|
import io.metersphere.plan.domain.TestPlanReport;
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
|
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
|
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
|
||||||
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
|
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
|
||||||
|
import io.metersphere.system.dto.sdk.ApiReportMessageDTO;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface ExtTestPlanReportMapper {
|
public interface ExtTestPlanReportMapper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页获取计划列表
|
* 分页获取计划列表
|
||||||
* @param request 分页请求参数
|
*
|
||||||
* @return 计划列表
|
* @param request 分页请求参数
|
||||||
*/
|
* @return 计划列表
|
||||||
List<TestPlanReportPageResponse> list(@Param("request") TestPlanReportPageRequest request, @Param("sort") String sort);
|
*/
|
||||||
|
List<TestPlanReportPageResponse> list(@Param("request") TestPlanReportPageRequest request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据页面参数获取批量操作的报告ID
|
* 根据页面参数获取批量操作的报告ID
|
||||||
* @param request 请求参数
|
*
|
||||||
* @return 报告ID集合
|
* @param request 请求参数
|
||||||
*/
|
* @return 报告ID集合
|
||||||
List<String> getReportBatchIdsByParam(@Param("request")TestPlanReportBatchRequest request);
|
*/
|
||||||
|
List<String> getReportBatchIdsByParam(@Param("request") TestPlanReportBatchRequest request);
|
||||||
|
|
||||||
|
List<TestPlanReport> selectReportByIds(@Param("ids") List<String> ids);
|
||||||
|
|
||||||
|
List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> subList);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,11 @@
|
||||||
<mapper namespace="io.metersphere.plan.mapper.ExtTestPlanReportMapper">
|
<mapper namespace="io.metersphere.plan.mapper.ExtTestPlanReportMapper">
|
||||||
<select id="list" resultType="io.metersphere.plan.dto.response.TestPlanReportPageResponse">
|
<select id="list" resultType="io.metersphere.plan.dto.response.TestPlanReportPageResponse">
|
||||||
select tpr.id as id, tpr.name as name, tp.name as planName, tpr.pass_threshold planPassThreshold,
|
select tpr.id as id, tpr.name as name, tp.name as planName, tpr.pass_threshold planPassThreshold,
|
||||||
tpr.trigger_mode as triggerMode, tpr.exec_status as executeStatus, tpr.result_status as resultStatus,
|
tpr.trigger_mode as triggerMode, tpr.exec_status , tpr.result_status as resultStatus,
|
||||||
tpr.pass_rate passRate, tpr.create_user createUser, tpr.create_time createTime
|
tpr.pass_rate passRate, tpr.create_user createUser, tpr.create_time createTime, tpr.integrated
|
||||||
from test_plan_report tpr
|
from test_plan_report tpr
|
||||||
join test_plan tp on tpr.test_plan_id = tp.id
|
join test_plan tp on tpr.test_plan_id = tp.id
|
||||||
<include refid="queryWhereCondition"/>
|
<include refid="queryWhereCondition"/>
|
||||||
<if test="sort != null and sort != ''">
|
|
||||||
order by ${sort}
|
|
||||||
</if>
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="getReportBatchIdsByParam" resultType="java.lang.String">
|
<select id="getReportBatchIdsByParam" resultType="java.lang.String">
|
||||||
|
@ -18,14 +15,24 @@
|
||||||
join test_plan tp on tpr.test_plan_id = tp.id
|
join test_plan tp on tpr.test_plan_id = tp.id
|
||||||
<include refid="queryWhereCondition"/>
|
<include refid="queryWhereCondition"/>
|
||||||
</select>
|
</select>
|
||||||
|
<select id="selectReportByIds" resultType="io.metersphere.plan.domain.TestPlanReport">
|
||||||
|
select * from test_plan_report where id in
|
||||||
|
<foreach collection="ids" item="id" open="(" close=")" separator=",">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
<select id="getNoticeList" resultType="io.metersphere.system.dto.sdk.ApiReportMessageDTO">
|
||||||
|
select id, name from test_plan_report where id in
|
||||||
|
<foreach collection="ids" item="id" open="(" close=")" separator=",">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
<sql id="queryWhereCondition">
|
<sql id="queryWhereCondition">
|
||||||
<where>
|
<where>
|
||||||
|
tpr.deleted = 0
|
||||||
<if test="request.projectId != null and request.projectId != ''">
|
<if test="request.projectId != null and request.projectId != ''">
|
||||||
and tp.project_id = #{request.projectId}
|
and tpr.project_id = #{request.projectId}
|
||||||
</if>
|
|
||||||
<if test="request.type != null and request.type != '' and request.type != 'ALL'">
|
|
||||||
and tp.type = #{request.type}
|
|
||||||
</if>
|
</if>
|
||||||
<if test="request.keyword != null and request.keyword != ''">
|
<if test="request.keyword != null and request.keyword != ''">
|
||||||
and tpr.name like concat('%', #{request.keyword},'%')
|
and tpr.name like concat('%', #{request.keyword},'%')
|
||||||
|
@ -44,13 +51,23 @@
|
||||||
<foreach collection="request.filter.entrySet()" index="key" item="values">
|
<foreach collection="request.filter.entrySet()" index="key" item="values">
|
||||||
<if test="values != null and values.size() > 0">
|
<if test="values != null and values.size() > 0">
|
||||||
<choose>
|
<choose>
|
||||||
|
<when test="key=='integrated'">
|
||||||
|
and tpr.integrated in
|
||||||
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
|
<choose>
|
||||||
|
<when test="value == 'true'">1</when>
|
||||||
|
<when test="value == 'false'">0</when>
|
||||||
|
<otherwise>0</otherwise>
|
||||||
|
</choose>
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
<!-- 触发方式 -->
|
<!-- 触发方式 -->
|
||||||
<when test="key == 'triggerMode'">
|
<when test="key == 'triggerMode'">
|
||||||
and tpr.trigger_mode in
|
and tpr.trigger_mode in
|
||||||
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
|
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
|
||||||
</when>
|
</when>
|
||||||
<!-- 执行状态 -->
|
<!-- 执行状态 -->
|
||||||
<when test="key == 'executeStatus'">
|
<when test="key == 'execStatus'">
|
||||||
and tpr.exec_status in
|
and tpr.exec_status in
|
||||||
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
|
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
|
||||||
</when>
|
</when>
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
package io.metersphere.plan.service;
|
||||||
|
|
||||||
|
import io.metersphere.plan.domain.TestPlanReport;
|
||||||
|
import io.metersphere.plan.mapper.ExtTestPlanReportMapper;
|
||||||
|
import io.metersphere.plan.mapper.TestPlanReportMapper;
|
||||||
|
import io.metersphere.project.domain.Project;
|
||||||
|
import io.metersphere.project.mapper.ProjectMapper;
|
||||||
|
import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.system.log.aspect.OperationLogAspect;
|
||||||
|
import io.metersphere.system.log.constants.OperationLogModule;
|
||||||
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
|
import io.metersphere.system.log.dto.LogDTO;
|
||||||
|
import io.metersphere.system.log.service.OperationLogService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TestPlanReportLogService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ProjectMapper projectMapper;
|
||||||
|
@Resource
|
||||||
|
private OperationLogService operationLogService;
|
||||||
|
@Resource
|
||||||
|
private ExtTestPlanReportMapper extTestPlanReportMapper;
|
||||||
|
@Resource
|
||||||
|
private TestPlanReportMapper testPlanReportMapper;
|
||||||
|
|
||||||
|
|
||||||
|
public LogDTO deleteLog(String id) {
|
||||||
|
TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id);
|
||||||
|
Project project = projectMapper.selectByPrimaryKey(report.getProjectId());
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
report.getProjectId(),
|
||||||
|
project.getOrganizationId(),
|
||||||
|
report.getId(),
|
||||||
|
null,
|
||||||
|
OperationLogType.DELETE.name(),
|
||||||
|
OperationLogModule.TEST_PLAN_REPORT,
|
||||||
|
report.getName());
|
||||||
|
|
||||||
|
dto.setPath(OperationLogAspect.getPath());
|
||||||
|
dto.setMethod(HttpMethodConstants.GET.name());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(report));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogDTO updateLog(String id) {
|
||||||
|
TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id);
|
||||||
|
Project project = projectMapper.selectByPrimaryKey(report.getProjectId());
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
report.getProjectId(),
|
||||||
|
project.getOrganizationId(),
|
||||||
|
report.getId(),
|
||||||
|
null,
|
||||||
|
OperationLogType.UPDATE.name(),
|
||||||
|
OperationLogModule.TEST_PLAN_REPORT,
|
||||||
|
report.getName());
|
||||||
|
|
||||||
|
dto.setPath(OperationLogAspect.getPath());
|
||||||
|
dto.setMethod(HttpMethodConstants.GET.name());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(report));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void batchDeleteLog(List<String> ids, String userId, String projectId) {
|
||||||
|
Project project = projectMapper.selectByPrimaryKey(projectId);
|
||||||
|
List<TestPlanReport> reports = extTestPlanReportMapper.selectReportByIds(ids);
|
||||||
|
List<LogDTO> logs = new ArrayList<>();
|
||||||
|
reports.forEach(report -> {
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
projectId,
|
||||||
|
project.getOrganizationId(),
|
||||||
|
report.getId(),
|
||||||
|
userId,
|
||||||
|
OperationLogType.DELETE.name(),
|
||||||
|
OperationLogModule.TEST_PLAN_REPORT,
|
||||||
|
report.getName());
|
||||||
|
|
||||||
|
dto.setPath(OperationLogAspect.getPath());
|
||||||
|
dto.setMethod(HttpMethodConstants.POST.name());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(report));
|
||||||
|
logs.add(dto);
|
||||||
|
});
|
||||||
|
operationLogService.batchAdd(logs);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package io.metersphere.plan.service;
|
||||||
|
|
||||||
|
import io.metersphere.plan.domain.TestPlanReport;
|
||||||
|
import io.metersphere.plan.mapper.ExtTestPlanReportMapper;
|
||||||
|
import io.metersphere.plan.mapper.TestPlanReportMapper;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.sdk.util.SubListUtils;
|
||||||
|
import io.metersphere.system.domain.User;
|
||||||
|
import io.metersphere.system.dto.sdk.ApiReportMessageDTO;
|
||||||
|
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
|
import io.metersphere.system.service.CommonNoticeSendService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TestPlanReportNoticeService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TestPlanReportMapper testPlanReportMapper;
|
||||||
|
@Resource
|
||||||
|
private CommonNoticeSendService commonNoticeSendService;
|
||||||
|
@Resource
|
||||||
|
private ExtTestPlanReportMapper extTestPlanReportMapper;
|
||||||
|
|
||||||
|
public ApiReportMessageDTO getDto(String id) {
|
||||||
|
TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(id);
|
||||||
|
ApiReportMessageDTO reportMessageDTO = new ApiReportMessageDTO();
|
||||||
|
reportMessageDTO.setId(report.getId());
|
||||||
|
reportMessageDTO.setName(report.getName());
|
||||||
|
return reportMessageDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void batchSendNotice(List<String> ids, User user, String projectId, String event) {
|
||||||
|
if (CollectionUtils.isNotEmpty(ids)) {
|
||||||
|
SubListUtils.dealForSubList(ids, 100, (subList) -> {
|
||||||
|
List<ApiReportMessageDTO> noticeLists = extTestPlanReportMapper.getNoticeList(subList);
|
||||||
|
List<Map> resources = new ArrayList<>(JSON.parseArray(JSON.toJSONString(noticeLists), Map.class));
|
||||||
|
commonNoticeSendService.sendNotice(NoticeConstants.TaskType.TEST_PLAN_REPORT_TASK, event, resources, user, projectId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,18 @@
|
||||||
package io.metersphere.plan.service;
|
package io.metersphere.plan.service;
|
||||||
|
|
||||||
import io.metersphere.plan.domain.*;
|
import io.metersphere.plan.domain.TestPlanReport;
|
||||||
|
import io.metersphere.plan.domain.TestPlanReportExample;
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
|
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportDeleteRequest;
|
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportEditRequest;
|
|
||||||
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
|
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
|
||||||
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
|
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
|
||||||
import io.metersphere.plan.mapper.*;
|
import io.metersphere.plan.mapper.ExtTestPlanReportMapper;
|
||||||
|
import io.metersphere.plan.mapper.TestPlanReportMapper;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
|
import io.metersphere.sdk.util.SubListUtils;
|
||||||
import io.metersphere.sdk.util.Translator;
|
import io.metersphere.sdk.util.Translator;
|
||||||
|
import io.metersphere.system.domain.User;
|
||||||
|
import io.metersphere.system.mapper.UserMapper;
|
||||||
|
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
import io.metersphere.system.service.UserService;
|
import io.metersphere.system.service.UserService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
@ -21,115 +25,105 @@ import java.util.Map;
|
||||||
@Service
|
@Service
|
||||||
public class TestPlanReportService {
|
public class TestPlanReportService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanReportMapper testPlanReportMapper;
|
private TestPlanReportMapper testPlanReportMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ExtTestPlanReportMapper extTestPlanReportMapper;
|
private ExtTestPlanReportMapper extTestPlanReportMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanReportSummaryMapper testPlanReportSummaryMapper;
|
private TestPlanReportLogService testPlanReportLogService;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanReportFunctionCaseMapper testPlanReportFunctionCaseMapper;
|
private TestPlanReportNoticeService testPlanReportNoticeService;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanReportBugMapper testPlanReportBugMapper;
|
private UserMapper userMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询报告列表
|
* 分页查询报告列表
|
||||||
* @param request 分页请求参数
|
*
|
||||||
* @return 报告列表
|
* @param request 分页请求参数
|
||||||
*/
|
* @return 报告列表
|
||||||
public List<TestPlanReportPageResponse> page(TestPlanReportPageRequest request) {
|
*/
|
||||||
List<TestPlanReportPageResponse> reportList = extTestPlanReportMapper.list(request, request.getSortString());
|
public List<TestPlanReportPageResponse> page(TestPlanReportPageRequest request) {
|
||||||
if (CollectionUtils.isEmpty(reportList)) {
|
List<TestPlanReportPageResponse> reportList = extTestPlanReportMapper.list(request);
|
||||||
return new ArrayList<>();
|
if (CollectionUtils.isEmpty(reportList)) {
|
||||||
}
|
return new ArrayList<>();
|
||||||
List<String> distinctUserIds = reportList.stream().map(TestPlanReportPageResponse::getCreateUser).distinct().toList();
|
}
|
||||||
Map<String, String> userMap = userService.getUserMapByIds(distinctUserIds);
|
List<String> distinctUserIds = reportList.stream().map(TestPlanReportPageResponse::getCreateUser).distinct().toList();
|
||||||
reportList.forEach(report -> report.setCreateUserName(userMap.get(report.getCreateUser())));
|
Map<String, String> userMap = userService.getUserMapByIds(distinctUserIds);
|
||||||
return reportList;
|
reportList.forEach(report -> report.setCreateUserName(userMap.get(report.getCreateUser())));
|
||||||
}
|
return reportList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报告重命名
|
* 报告重命名
|
||||||
* @param request 请求参数
|
*/
|
||||||
*/
|
public void rename(String id, String name) {
|
||||||
public void rename(TestPlanReportEditRequest request) {
|
TestPlanReport report = checkReport(id);
|
||||||
checkReport(request.getId());
|
report.setName(name);
|
||||||
TestPlanReport report = new TestPlanReport();
|
testPlanReportMapper.updateByPrimaryKeySelective(report);
|
||||||
report.setId(request.getId());
|
}
|
||||||
report.setName(request.getName());
|
|
||||||
testPlanReportMapper.updateByPrimaryKeySelective(report);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除单个报告
|
* 删除单个报告
|
||||||
* @param request 请求参数
|
*/
|
||||||
*/
|
public void delete(String id) {
|
||||||
public void delete(TestPlanReportDeleteRequest request) {
|
TestPlanReport report = checkReport(id);
|
||||||
checkReport(request.getId());
|
report.setDeleted(true);
|
||||||
testPlanReportMapper.deleteByPrimaryKey(request.getId());
|
testPlanReportMapper.updateByPrimaryKeySelective(report);
|
||||||
// 删除报告内容的关联资源表
|
}
|
||||||
cleanReportAssociateResource(List.of(request.getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量参数报告
|
* 批量参数报告
|
||||||
* @param request 请求参数
|
*
|
||||||
*/
|
* @param request 请求参数
|
||||||
public void batchDelete(TestPlanReportBatchRequest request) {
|
*/
|
||||||
List<String> batchIds = getBatchIds(request);
|
public void batchDelete(TestPlanReportBatchRequest request, String userId) {
|
||||||
if (CollectionUtils.isNotEmpty(batchIds)) {
|
List<String> batchIds = getBatchIds(request);
|
||||||
TestPlanReportExample example = new TestPlanReportExample();
|
User user = userMapper.selectByPrimaryKey(userId);
|
||||||
example.createCriteria().andIdIn(batchIds);
|
if (CollectionUtils.isNotEmpty(batchIds)) {
|
||||||
testPlanReportMapper.deleteByExample(example);
|
SubListUtils.dealForSubList(batchIds, 500, subList -> {
|
||||||
// 删除报告内容的关联资源表
|
TestPlanReportExample example = new TestPlanReportExample();
|
||||||
cleanReportAssociateResource(batchIds);
|
example.createCriteria().andIdIn(subList);
|
||||||
}
|
TestPlanReport testPlanReport = new TestPlanReport();
|
||||||
}
|
testPlanReport.setDeleted(true);
|
||||||
|
testPlanReportMapper.updateByExampleSelective(testPlanReport, example);
|
||||||
|
|
||||||
/**
|
testPlanReportLogService.batchDeleteLog(subList, userId, request.getProjectId());
|
||||||
* 清理报告关联的资源
|
testPlanReportNoticeService.batchSendNotice(subList, user, request.getProjectId(), NoticeConstants.Event.DELETE);
|
||||||
* @param reportIds 报告ID集合
|
});
|
||||||
*/
|
}
|
||||||
public void cleanReportAssociateResource(List<String> reportIds) {
|
}
|
||||||
// TODO: 删除报告关联的统计, 用例, 缺陷
|
|
||||||
TestPlanReportSummaryExample summaryExample = new TestPlanReportSummaryExample();
|
|
||||||
summaryExample.createCriteria().andTestPlanReportIdIn(reportIds);
|
|
||||||
testPlanReportSummaryMapper.deleteByExample(summaryExample);
|
|
||||||
TestPlanReportFunctionCaseExample functionCaseExample = new TestPlanReportFunctionCaseExample();
|
|
||||||
functionCaseExample.createCriteria().andTestPlanReportIdIn(reportIds);
|
|
||||||
testPlanReportFunctionCaseMapper.deleteByExample(functionCaseExample);
|
|
||||||
TestPlanReportBugExample bugExample = new TestPlanReportBugExample();
|
|
||||||
bugExample.createCriteria().andTestPlanReportIdIn(reportIds);
|
|
||||||
testPlanReportBugMapper.deleteByExample(bugExample);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过请求参数获取批量操作的ID集合
|
|
||||||
* @param request 请求参数
|
|
||||||
* @return ID集合
|
|
||||||
*/
|
|
||||||
private List<String> getBatchIds(TestPlanReportBatchRequest request) {
|
|
||||||
if (request.isSelectAll()) {
|
|
||||||
List<String> batchIds = extTestPlanReportMapper.getReportBatchIdsByParam(request);
|
|
||||||
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
|
|
||||||
batchIds.removeIf(id -> request.getExcludeIds().contains(id));
|
|
||||||
}
|
|
||||||
return batchIds;
|
|
||||||
} else {
|
|
||||||
return request.getSelectIds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验报告是否存在
|
* 通过请求参数获取批量操作的ID集合
|
||||||
* @param id 报告ID
|
*
|
||||||
*/
|
* @param request 请求参数
|
||||||
private void checkReport(String id) {
|
* @return ID集合
|
||||||
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(id);
|
*/
|
||||||
if (testPlanReport == null) {
|
private List<String> getBatchIds(TestPlanReportBatchRequest request) {
|
||||||
throw new MSException(Translator.get("test_plan_report_not_exist"));
|
if (request.isSelectAll()) {
|
||||||
}
|
List<String> batchIds = extTestPlanReportMapper.getReportBatchIdsByParam(request);
|
||||||
}
|
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
|
||||||
|
batchIds.removeIf(id -> request.getExcludeIds().contains(id));
|
||||||
|
}
|
||||||
|
return batchIds;
|
||||||
|
} else {
|
||||||
|
return request.getSelectIds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验报告是否存在
|
||||||
|
*
|
||||||
|
* @param id 报告ID
|
||||||
|
*/
|
||||||
|
private TestPlanReport checkReport(String id) {
|
||||||
|
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(id);
|
||||||
|
if (testPlanReport == null) {
|
||||||
|
throw new MSException(Translator.get("test_plan_report_not_exist"));
|
||||||
|
}
|
||||||
|
return testPlanReport;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,144 +28,137 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
@AutoConfigureMockMvc
|
@AutoConfigureMockMvc
|
||||||
public class TestPlanReportControllerTests extends BaseTest {
|
public class TestPlanReportControllerTests extends BaseTest {
|
||||||
|
|
||||||
private static final String LIST_PLAN_REPORT = "/test-plan/report/page";
|
private static final String LIST_PLAN_REPORT = "/test-plan/report/page";
|
||||||
private static final String RENAME_PLAN_REPORT = "/test-plan/report/rename";
|
private static final String RENAME_PLAN_REPORT = "/test-plan/report/rename";
|
||||||
private static final String DELETE_PLAN_REPORT = "/test-plan/report/delete";
|
private static final String DELETE_PLAN_REPORT = "/test-plan/report/delete";
|
||||||
private static final String BATCH_DELETE_PLAN_REPORT = "/test-plan/report/batch-delete";
|
private static final String BATCH_DELETE_PLAN_REPORT = "/test-plan/report/batch-delete";
|
||||||
private static final String GEN_AND_SHARE = "/test-plan/report/share/gen";
|
private static final String GEN_AND_SHARE = "/test-plan/report/share/gen";
|
||||||
private static final String GET_SHARE_INFO = "/test-plan/report/share/get";
|
private static final String GET_SHARE_INFO = "/test-plan/report/share/get";
|
||||||
private static final String GET_SHARE_TIME = "/test-plan/report/share/get-share-time";
|
private static final String GET_SHARE_TIME = "/test-plan/report/share/get-share-time";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(1)
|
@Order(1)
|
||||||
@Sql(scripts = {"/dml/init_test_plan_report.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
@Sql(scripts = {"/dml/init_test_plan_report.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
||||||
void tesPagePlanReportSuccess() throws Exception {
|
void tesPagePlanReportSuccess() throws Exception {
|
||||||
TestPlanReportPageRequest request = new TestPlanReportPageRequest();
|
TestPlanReportPageRequest request = new TestPlanReportPageRequest();
|
||||||
request.setProjectId("100001100001");
|
request.setProjectId("100001100001");
|
||||||
request.setType("ALL");
|
request.setCurrent(1);
|
||||||
request.setCurrent(1);
|
request.setPageSize(10);
|
||||||
request.setPageSize(10);
|
request.setKeyword("1");
|
||||||
request.setKeyword("1");
|
MvcResult mvcResult = this.requestPostWithOkAndReturn(LIST_PLAN_REPORT, request);
|
||||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(LIST_PLAN_REPORT, 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);
|
// 返回请求正常
|
||||||
// 返回请求正常
|
Assertions.assertNotNull(resultHolder);
|
||||||
Assertions.assertNotNull(resultHolder);
|
Pager<?> pageData = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class);
|
||||||
Pager<?> pageData = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class);
|
// 返回值不为空
|
||||||
// 返回值不为空
|
Assertions.assertNotNull(pageData);
|
||||||
Assertions.assertNotNull(pageData);
|
// 返回值的页码和当前页码相同
|
||||||
// 返回值的页码和当前页码相同
|
Assertions.assertEquals(pageData.getCurrent(), request.getCurrent());
|
||||||
Assertions.assertEquals(pageData.getCurrent(), request.getCurrent());
|
// 返回的数据量不超过规定要返回的数据量相同
|
||||||
// 返回的数据量不超过规定要返回的数据量相同
|
Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(pageData.getList())).size() <= request.getPageSize());
|
||||||
Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(pageData.getList())).size() <= request.getPageSize());
|
// 返回值中取出第一条数据, 并判断是否包含关键字default
|
||||||
// 返回值中取出第一条数据, 并判断是否包含关键字default
|
TestPlanReportPageResponse report = JSON.parseArray(JSON.toJSONString(pageData.getList()), TestPlanReportPageResponse.class).get(0);
|
||||||
TestPlanReportPageResponse report = JSON.parseArray(JSON.toJSONString(pageData.getList()), TestPlanReportPageResponse.class).get(0);
|
Assertions.assertTrue(StringUtils.contains(report.getName(), request.getKeyword()));
|
||||||
Assertions.assertTrue(StringUtils.contains(report.getName(), request.getKeyword()));
|
// 覆盖排序, 及数据为空
|
||||||
// 覆盖排序, 及数据为空
|
request.setSort(Map.of("tpr.create_time", "asc"));
|
||||||
request.setSort(Map.of("tpr.create_time", "asc"));
|
request.setKeyword("oasis");
|
||||||
request.setKeyword("oasis");
|
this.requestPost(LIST_PLAN_REPORT, request);
|
||||||
this.requestPost(LIST_PLAN_REPORT, request);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(2)
|
@Order(2)
|
||||||
void testPagePlanReportError() throws Exception {
|
void testPagePlanReportError() throws Exception {
|
||||||
// 必填参数有误
|
// 必填参数有误
|
||||||
TestPlanReportPageRequest request = new TestPlanReportPageRequest();
|
TestPlanReportPageRequest request = new TestPlanReportPageRequest();
|
||||||
request.setCurrent(1);
|
request.setCurrent(1);
|
||||||
request.setPageSize(10);
|
request.setPageSize(10);
|
||||||
this.requestPost(LIST_PLAN_REPORT, request, status().isBadRequest());
|
this.requestPost(LIST_PLAN_REPORT, request, status().isBadRequest());
|
||||||
// 页码有误
|
// 页码有误
|
||||||
request.setProjectId("100001100001");
|
request.setProjectId("100001100001");
|
||||||
request.setType("ALL");
|
request.setCurrent(0);
|
||||||
request.setCurrent(0);
|
request.setPageSize(10);
|
||||||
request.setPageSize(10);
|
this.requestPost(LIST_PLAN_REPORT, request, status().isBadRequest());
|
||||||
this.requestPost(LIST_PLAN_REPORT, request, status().isBadRequest());
|
// 页数有误
|
||||||
// 页数有误
|
request.setCurrent(1);
|
||||||
request.setCurrent(1);
|
request.setPageSize(1);
|
||||||
request.setPageSize(1);
|
this.requestPost(LIST_PLAN_REPORT, request, status().isBadRequest());
|
||||||
this.requestPost(LIST_PLAN_REPORT, request, status().isBadRequest());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(3)
|
@Order(3)
|
||||||
void testRenamePlanReportSuccess() throws Exception {
|
void testRenamePlanReportSuccess() throws Exception {
|
||||||
TestPlanReportEditRequest request = new TestPlanReportEditRequest();
|
this.requestPostWithOk(RENAME_PLAN_REPORT + "/test-plan-report-id-1", "oasis");
|
||||||
request.setId("test-plan-report-id-1");
|
}
|
||||||
request.setName("oasis");
|
|
||||||
request.setProjectId("100001100001");
|
|
||||||
this.requestPostWithOk(RENAME_PLAN_REPORT, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(4)
|
@Order(4)
|
||||||
void testRenamePlanReportError() throws Exception {
|
void testRenamePlanReportError() throws Exception {
|
||||||
TestPlanReportEditRequest request = new TestPlanReportEditRequest();
|
TestPlanReportEditRequest request = new TestPlanReportEditRequest();
|
||||||
request.setId("test-plan-report-id-x");
|
request.setId("test-plan-report-id-x");
|
||||||
request.setName("oasis");
|
request.setName("oasis");
|
||||||
request.setProjectId("100001100001");
|
request.setProjectId("100001100001");
|
||||||
this.requestPost(RENAME_PLAN_REPORT, request, status().is5xxServerError());
|
this.requestPost(RENAME_PLAN_REPORT, request, status().is5xxServerError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(5)
|
@Order(5)
|
||||||
void testSharePlanReport() throws Exception {
|
void testSharePlanReport() throws Exception {
|
||||||
TestPlanReportShareRequest shareRequest = new TestPlanReportShareRequest();
|
TestPlanReportShareRequest shareRequest = new TestPlanReportShareRequest();
|
||||||
shareRequest.setReportId("test-plan-report-id-1");
|
shareRequest.setReportId("test-plan-report-id-1");
|
||||||
shareRequest.setProjectId("100001100001");
|
shareRequest.setProjectId("100001100001");
|
||||||
shareRequest.setShareType(ShareInfoType.TEST_PLAN_SHARE_REPORT.name());
|
shareRequest.setShareType(ShareInfoType.TEST_PLAN_SHARE_REPORT.name());
|
||||||
this.requestPost(GEN_AND_SHARE, shareRequest);
|
this.requestPost(GEN_AND_SHARE, shareRequest);
|
||||||
shareRequest.setLang(Locale.SIMPLIFIED_CHINESE.getLanguage());
|
shareRequest.setLang(Locale.SIMPLIFIED_CHINESE.getLanguage());
|
||||||
MvcResult mvcResult = this.requestPost(GEN_AND_SHARE, shareRequest).andReturn();
|
MvcResult mvcResult = this.requestPost(GEN_AND_SHARE, shareRequest).andReturn();
|
||||||
String sortData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
String sortData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||||
ResultHolder sortHolder = JSON.parseObject(sortData, ResultHolder.class);
|
ResultHolder sortHolder = JSON.parseObject(sortData, ResultHolder.class);
|
||||||
TestPlanShareInfo shareInfo = JSON.parseObject(JSON.toJSONString(sortHolder.getData()), TestPlanShareInfo.class);
|
TestPlanShareInfo shareInfo = JSON.parseObject(JSON.toJSONString(sortHolder.getData()), TestPlanShareInfo.class);
|
||||||
Assertions.assertNotNull(shareInfo);
|
Assertions.assertNotNull(shareInfo);
|
||||||
this.requestGet(GET_SHARE_INFO + "/" + shareInfo.getId());
|
this.requestGet(GET_SHARE_INFO + "/" + shareInfo.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(6)
|
@Order(6)
|
||||||
void testGetShareInfo() throws Exception {
|
void testGetShareInfo() throws Exception {
|
||||||
// 报告被删除
|
// 报告被删除
|
||||||
this.requestGet(GET_SHARE_INFO + "/share-1");
|
this.requestGet(GET_SHARE_INFO + "/share-1");
|
||||||
// 分享链接未找到
|
// 分享链接未找到
|
||||||
this.requestGet(GET_SHARE_INFO + "/share-2", status().is5xxServerError());
|
this.requestGet(GET_SHARE_INFO + "/share-2", status().is5xxServerError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(7)
|
@Order(7)
|
||||||
void testGetShareTime() throws Exception {
|
void testGetShareTime() throws Exception {
|
||||||
this.requestGet(GET_SHARE_TIME + "/100001100001");
|
this.requestGet(GET_SHARE_TIME + "/100001100001");
|
||||||
this.requestGet(GET_SHARE_TIME + "/100001100002");
|
this.requestGet(GET_SHARE_TIME + "/100001100002");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(8)
|
@Order(8)
|
||||||
void testDeletePlanReport() throws Exception {
|
void testDeletePlanReport() throws Exception {
|
||||||
TestPlanReportDeleteRequest request = new TestPlanReportDeleteRequest();
|
TestPlanReportDeleteRequest request = new TestPlanReportDeleteRequest();
|
||||||
request.setId("test-plan-report-id-1");
|
request.setId("test-plan-report-id-1");
|
||||||
request.setProjectId("100001100001");
|
request.setProjectId("100001100001");
|
||||||
this.requestPostWithOk(DELETE_PLAN_REPORT, request);
|
this.requestGet(DELETE_PLAN_REPORT + "/test-plan-report-id-1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(9)
|
@Order(9)
|
||||||
void testBatchDeletePlanReport() throws Exception {
|
void testBatchDeletePlanReport() throws Exception {
|
||||||
TestPlanReportBatchRequest request = new TestPlanReportBatchRequest();
|
TestPlanReportBatchRequest request = new TestPlanReportBatchRequest();
|
||||||
request.setProjectId("100001100001");
|
request.setProjectId("100001100001");
|
||||||
request.setType("ALL");
|
// 勾选部分, 并删除
|
||||||
// 勾选部分, 并删除
|
request.setSelectAll(false);
|
||||||
request.setSelectAll(false);
|
request.setSelectIds(List.of("test-plan-report-id-2"));
|
||||||
request.setSelectIds(List.of("test-plan-report-id-2"));
|
this.requestPostWithOk(BATCH_DELETE_PLAN_REPORT, request);
|
||||||
this.requestPostWithOk(BATCH_DELETE_PLAN_REPORT, request);
|
// 全选并排除所有, 为空
|
||||||
// 全选并排除所有, 为空
|
request.setSelectAll(true);
|
||||||
request.setSelectAll(true);
|
request.setExcludeIds(List.of("test-plan-report-id-3", "test-plan-report-id-4"));
|
||||||
request.setExcludeIds(List.of("test-plan-report-id-3", "test-plan-report-id-4"));
|
this.requestPostWithOk(BATCH_DELETE_PLAN_REPORT, request);
|
||||||
this.requestPostWithOk(BATCH_DELETE_PLAN_REPORT, request);
|
// 全选不排除
|
||||||
// 全选不排除
|
request.setExcludeIds(null);
|
||||||
request.setExcludeIds(null);
|
this.requestPostWithOk(BATCH_DELETE_PLAN_REPORT, request);
|
||||||
this.requestPostWithOk(BATCH_DELETE_PLAN_REPORT, request);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,14 @@ INSERT INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `nam
|
||||||
VALUES ('test-plan-id-for992', 100003, '100001100001', 'NONE', '1', '测试一下计划-992', 'PREPARED', 'TEST_PLAN', NULL, CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '11');
|
VALUES ('test-plan-id-for992', 100003, '100001100001', 'NONE', '1', '测试一下计划-992', 'PREPARED', 'TEST_PLAN', NULL, CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '11');
|
||||||
|
|
||||||
-- 计划报告测试数据
|
-- 计划报告测试数据
|
||||||
INSERT INTO `test_plan_report`(`id`, `test_plan_id`, `name`, `create_user`, `create_time`, `start_time`, `end_time`, `trigger_mode`, `exec_status`, `result_status`, `pass_threshold`, `pass_rate`) VALUES
|
INSERT INTO `test_plan_report`(`id`, `test_plan_id`, `name`, `create_user`, `create_time`, `start_time`, `end_time`, `trigger_mode`, `exec_status`, `result_status`, `pass_threshold`, `pass_rate`, `project_id`, `integrated`, `deleted`) VALUES
|
||||||
('test-plan-report-id-1', 'test-plan-id-for991', '测试一下计划报告1', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'MANUAL', 'PENDING', '-', '99.99', 100.00),
|
('test-plan-report-id-1', 'test-plan-id-for991', '测试一下计划报告1', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'MANUAL', 'PENDING', 'SUCCESS', '99.99', 100.00, '100001100001', 0, 0),
|
||||||
('test-plan-report-id-2', 'test-plan-id-for991', '测试一下计划报告1', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'MANUAL', 'PENDING', '-', '99.99', 100.00),
|
('test-plan-report-id-2', 'test-plan-id-for991', '测试一下计划报告1', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'MANUAL', 'PENDING', '-', '99.99', 100.00, '100001100001', 0, 0),
|
||||||
('test-plan-report-id-3', 'test-plan-id-for992', '测试一下计划报告3', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'MANUAL', 'PENDING', '-', '99.99', 100.00),
|
('test-plan-report-id-3', 'test-plan-id-for992', '测试一下计划报告3', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'MANUAL', 'PENDING', '-', '99.99', 100.00, '100001100001',1, 0),
|
||||||
('test-plan-report-id-4', 'test-plan-id-for992', '测试一下计划报告4', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'MANUAL', 'PENDING', '-', '99.99', 100.00);
|
('test-plan-report-id-4', 'test-plan-id-for992', '测试一下计划报告4', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'MANUAL', 'PENDING', '-', '99.99', 100.00, '100001100001', 1, 0);
|
||||||
|
|
||||||
-- 计划报告分享信息
|
-- 计划报告分享信息
|
||||||
INSERT INTO project_application (`project_id`, `type`, `type_value`) VALUES
|
INSERT INTO project_application (`project_id`, `type`, `type_value`) VALUES
|
||||||
('100001100001', 'TEST_PLAN_SHARE_REPORT', '1D');
|
('100001100001', 'TEST_PLAN_SHARE_REPORT', '1D');
|
||||||
INSERT INTO `share_info`(`id`, `create_time`, `create_user`, `update_time`, `share_type`, `custom_data`, `lang`, `project_id`) VALUES
|
INSERT INTO `share_info`(`id`, `create_time`, `create_user`, `update_time`, `share_type`, `custom_data`, `lang`, `project_id`) VALUES
|
||||||
('share-1', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'TEST_PLAN_SHARE_REPORT', 0x31303531363635363936353436383137, 'zh_CN', '100001100001');
|
('share-1', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'TEST_PLAN_SHARE_REPORT', 0x31303531363635363936353436383137, 'zh_CN', '100001100001');
|
|
@ -1,8 +1,8 @@
|
||||||
// 报告列表
|
// 报告列表
|
||||||
export const PlanReportListUrl = '/api/report/scenario/page';
|
export const PlanReportListUrl = '/test-plan/report/page';
|
||||||
// 报告重命名
|
// 报告重命名
|
||||||
export const PlanReportRenameUrl = '/api/report/scenario/rename';
|
export const PlanReportRenameUrl = '/test-plan/report/rename';
|
||||||
// 删除报告
|
// 删除报告
|
||||||
export const PlanDeleteUrl = '/api/report/scenario/delete';
|
export const PlanDeleteUrl = '/test-plan/report/delete';
|
||||||
// 批量删除报告
|
// 批量删除报告
|
||||||
export const PlanBatchDeleteUrl = '/api/report/scenario/batch/delete';
|
export const PlanBatchDeleteUrl = '/test-plan/report/batch-delete';
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
// 模板展示字段icon
|
// 模板展示字段icon
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
export enum ReportEnum {
|
export enum ReportEnum {
|
||||||
API_SCENARIO_REPORT = 'API_SCENARIO_REPORT',
|
API_SCENARIO_REPORT = 'API_SCENARIO_REPORT',
|
||||||
API_REPORT = 'API_REPORT',
|
API_REPORT = 'API_REPORT',
|
||||||
|
@ -86,23 +89,35 @@ export const ReportStatus = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PlanReportStatus = {
|
export const PlanReportStatus: Record<string, any> = {
|
||||||
[ReportStatusEnum.EXEC_STATUS]: {
|
[ReportStatusEnum.EXEC_STATUS]: {
|
||||||
STOPPED: {
|
STOPPED: {
|
||||||
|
key: 'STOPPED',
|
||||||
icon: 'icon-icon_block_filled',
|
icon: 'icon-icon_block_filled',
|
||||||
|
statusText: t('report.stopped'),
|
||||||
label: 'report.stop',
|
label: 'report.stop',
|
||||||
color: '!var(--color-text-input-border)',
|
color: '!var(--color-text-input-border)',
|
||||||
},
|
},
|
||||||
RUNNING: {
|
RUNNING: {
|
||||||
|
key: 'RUNNING',
|
||||||
icon: 'icon-icon_testing',
|
icon: 'icon-icon_testing',
|
||||||
|
statusText: t('report.status.running'),
|
||||||
label: 'report.inExecution',
|
label: 'report.inExecution',
|
||||||
color: '!text-[rgb(var(--link-6))]',
|
color: '!text-[rgb(var(--link-6))]',
|
||||||
},
|
},
|
||||||
PENDING: {
|
PENDING: {
|
||||||
|
key: 'PENDING',
|
||||||
icon: 'icon-icon_wait',
|
icon: 'icon-icon_wait',
|
||||||
|
statusText: t('report.status.pending'),
|
||||||
label: 'report.queuing',
|
label: 'report.queuing',
|
||||||
color: '!text-[rgb(var(--link-6))]',
|
color: '!text-[rgb(var(--link-6))]',
|
||||||
},
|
},
|
||||||
|
COMPLETED: {
|
||||||
|
key: 'COMPLETED',
|
||||||
|
icon: 'icon-icon_succeed_colorful',
|
||||||
|
statusText: t('report.completed'),
|
||||||
|
label: 'report.successful',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[ReportStatusEnum.REPORT_STATUS]: {
|
[ReportStatusEnum.REPORT_STATUS]: {
|
||||||
SUCCESS: {
|
SUCCESS: {
|
||||||
|
@ -113,10 +128,6 @@ export const PlanReportStatus = {
|
||||||
icon: 'icon-icon_close_colorful',
|
icon: 'icon-icon_close_colorful',
|
||||||
label: 'report.failure',
|
label: 'report.failure',
|
||||||
},
|
},
|
||||||
FAKE_ERROR: {
|
|
||||||
icon: 'icon-icon_warning_colorful',
|
|
||||||
label: 'report.falseAlarm',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export default {};
|
export default {};
|
||||||
|
|
|
@ -7,6 +7,7 @@ export enum FilterSlotNameEnum {
|
||||||
CASE_MANAGEMENT_BUG_STATE = 'CASE_MANAGEMENT_BUG_STATE', // 缺陷状态
|
CASE_MANAGEMENT_BUG_STATE = 'CASE_MANAGEMENT_BUG_STATE', // 缺陷状态
|
||||||
API_TEST_API_REQUEST_METHODS = 'API_TEST_API_REQUEST_METHODS', // 接口测试请求方式
|
API_TEST_API_REQUEST_METHODS = 'API_TEST_API_REQUEST_METHODS', // 接口测试请求方式
|
||||||
API_TEST_API_REQUEST_API_STATUS = 'API_TEST_API_REQUEST_API_STATUS', // 接口测试接口状态
|
API_TEST_API_REQUEST_API_STATUS = 'API_TEST_API_REQUEST_API_STATUS', // 接口测试接口状态
|
||||||
|
TEST_PLAN_REPORT_EXEC_STATUS = 'TEST_PLAN_REPORT_EXEC_STATUS',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum FilterRemoteMethodsEnum {
|
export enum FilterRemoteMethodsEnum {
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
<template>
|
|
||||||
<MsColorLine :color-data="colorData" :height="props.height" :radius="props.radius">
|
|
||||||
<!-- TODO 这个页面还得根据实际业务调整-->
|
|
||||||
<template #popoverContent>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td class="pr-[8px] text-[var(--color-text-4)]">{{ t('caseManagement.caseReview.progress') }}</td>
|
|
||||||
<td class="font-medium text-[var(--color-text-1)]">
|
|
||||||
{{ progress }}
|
|
||||||
<span> ({{ `${props.detail.passCount + props.detail.unPassCount}/${props.detail.caseCount}` }}) </span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="popover-label-td">
|
|
||||||
<div class="mb-[2px] mr-[4px] h-[6px] w-[6px] rounded-full bg-[rgb(var(--success-6))]"></div>
|
|
||||||
<div>{{ t('caseManagement.caseReview.pass') }}</div>
|
|
||||||
</td>
|
|
||||||
<td class="popover-value-td">
|
|
||||||
{{ props.detail.passCount }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="popover-label-td">
|
|
||||||
<div class="mb-[2px] mr-[4px] h-[6px] w-[6px] rounded-full bg-[rgb(var(--danger-6))]"></div>
|
|
||||||
<div>{{ t('caseManagement.caseReview.fail') }}</div>
|
|
||||||
</td>
|
|
||||||
<td class="popover-value-td">
|
|
||||||
{{ props.detail.unPassCount }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="popover-label-td">
|
|
||||||
<div class="mb-[2px] mr-[4px] h-[6px] w-[6px] rounded-full bg-[rgb(var(--warning-6))]"></div>
|
|
||||||
<div>{{ t('caseManagement.caseReview.reReview') }}</div>
|
|
||||||
</td>
|
|
||||||
<td class="popover-value-td">
|
|
||||||
{{ props.detail.reReviewedCount }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="popover-label-td">
|
|
||||||
<div class="mb-[2px] mr-[4px] h-[6px] w-[6px] rounded-full bg-[rgb(var(--link-6))]"></div>
|
|
||||||
<div>{{ t('caseManagement.caseReview.reviewing') }}</div>
|
|
||||||
</td>
|
|
||||||
<td class="popover-value-td">
|
|
||||||
{{ props.detail.underReviewedCount }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</template>
|
|
||||||
</MsColorLine>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import MsColorLine from '@/components/pure/ms-color-line/index.vue';
|
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
detail: {
|
|
||||||
passCount: number;
|
|
||||||
unPassCount: number;
|
|
||||||
reReviewedCount: number;
|
|
||||||
underReviewedCount: number;
|
|
||||||
caseCount: number;
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
height: string;
|
|
||||||
radius?: string;
|
|
||||||
}>();
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const colorData = computed(() => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
percentage: 100,
|
|
||||||
color: 'var(--color-text-n8)',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
// TODO 实际业务调整
|
|
||||||
// return [
|
|
||||||
// {
|
|
||||||
// percentage: (props.detail.passCount / props.detail.caseCount) * 100,
|
|
||||||
// color: 'rgb(var(--success-6))',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// percentage: (props.detail.unPassCount / props.detail.caseCount) * 100,
|
|
||||||
// color: 'rgb(var(--danger-6))',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// percentage: (props.detail.reReviewedCount / props.detail.caseCount) * 100,
|
|
||||||
// color: 'rgb(var(--warning-6))',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// percentage: (props.detail.underReviewedCount / props.detail.caseCount) * 100,
|
|
||||||
// color: 'rgb(var(--link-6))',
|
|
||||||
// },
|
|
||||||
// ];
|
|
||||||
});
|
|
||||||
const progress = computed(() => {
|
|
||||||
const result = ((props.detail.passCount + props.detail.unPassCount) / props.detail.caseCount) * 100;
|
|
||||||
return `${Number.isNaN(result) ? 0 : result.toFixed(2)}%`;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.popover-label-td {
|
|
||||||
@apply flex items-center;
|
|
||||||
|
|
||||||
padding: 8px 8px 0 0;
|
|
||||||
color: var(--color-text-4);
|
|
||||||
}
|
|
||||||
.popover-value-td {
|
|
||||||
@apply font-medium;
|
|
||||||
|
|
||||||
padding-top: 8px;
|
|
||||||
color: var(--color-text-1);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -32,69 +32,7 @@
|
||||||
>{{ characterLimit(record.name) }}</div
|
>{{ characterLimit(record.name) }}</div
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<!-- 报告类型 -->
|
|
||||||
<template #integrated="{ record }">
|
|
||||||
<MsTag theme="light" :type="record.integrated ? 'primary' : undefined">
|
|
||||||
{{ record.integrated ? t('report.collection') : t('report.independent') }}
|
|
||||||
</MsTag>
|
|
||||||
</template>
|
|
||||||
<template #integratedFilter="{ columnConfig }">
|
|
||||||
<TableFilter
|
|
||||||
v-model:visible="reportTypeVisible"
|
|
||||||
v-model:status-filters="integratedFiltersMap[showType]"
|
|
||||||
:title="(columnConfig.title as string)"
|
|
||||||
:list="reportTypeList"
|
|
||||||
@search="initData()"
|
|
||||||
>
|
|
||||||
<template #item="{ item }">
|
|
||||||
<MsTag theme="light" :type="item.value === 'INTEGRATED' ? 'primary' : undefined">
|
|
||||||
{{ item.value === 'INTEGRATED' ? t('report.collection') : t('report.independent') }}
|
|
||||||
</MsTag>
|
|
||||||
</template>
|
|
||||||
</TableFilter>
|
|
||||||
</template>
|
|
||||||
<!-- 报告触发方式筛选 -->
|
|
||||||
<template #triggerModeFilter="{ columnConfig }">
|
|
||||||
<a-trigger
|
|
||||||
v-model:popup-visible="triggerModeFilterVisible"
|
|
||||||
trigger="click"
|
|
||||||
@popup-visible-change="handleFilterHidden"
|
|
||||||
>
|
|
||||||
<a-button
|
|
||||||
type="text"
|
|
||||||
class="arco-btn-text--secondary p-[8px_4px]"
|
|
||||||
@click.stop="triggerModeFilterVisible = true"
|
|
||||||
>
|
|
||||||
<div class="font-medium">
|
|
||||||
{{ t(columnConfig.title as string) }}
|
|
||||||
</div>
|
|
||||||
<icon-down :class="triggerModeFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
|
||||||
</a-button>
|
|
||||||
<template #content>
|
|
||||||
<div class="arco-table-filters-content">
|
|
||||||
<div class="ml-[6px] flex items-center justify-start px-[6px] py-[2px]">
|
|
||||||
<a-checkbox-group
|
|
||||||
v-model:model-value="triggerModeListFiltersMaps[showType]"
|
|
||||||
direction="vertical"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<a-checkbox v-for="(key, value) of TriggerModeLabel" :key="key" :value="value">
|
|
||||||
<div class="font-medium">{{ t(key) }}</div>
|
|
||||||
</a-checkbox>
|
|
||||||
</a-checkbox-group>
|
|
||||||
</div>
|
|
||||||
<div class="filter-button">
|
|
||||||
<a-button size="mini" class="mr-[8px]" @click="resetTriggerModeFilter">
|
|
||||||
{{ t('common.reset') }}
|
|
||||||
</a-button>
|
|
||||||
<a-button type="primary" size="mini" @click="handleFilterHidden(false)">
|
|
||||||
{{ t('system.orgTemplate.confirm') }}
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-trigger>
|
|
||||||
</template>
|
|
||||||
<!-- 通过率 -->
|
<!-- 通过率 -->
|
||||||
<template #passRateColumn>
|
<template #passRateColumn>
|
||||||
<div class="flex items-center text-[var(--color-text-3)]">
|
<div class="flex items-center text-[var(--color-text-3)]">
|
||||||
|
@ -108,95 +46,22 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #passRate="{ record }">
|
<template #passRate="{ record }">
|
||||||
<div class="mr-[8px] w-[100px]">
|
|
||||||
<passRateLine :detail="record" height="5px" />
|
|
||||||
</div>
|
|
||||||
<div class="text-[var(--color-text-1)]">
|
<div class="text-[var(--color-text-1)]">
|
||||||
{{ `${record.passRate | 0}%` }}
|
{{ `${record.passRate | 0}%` }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 报告结果筛选 -->
|
|
||||||
<template #statusFilter="{ columnConfig }">
|
|
||||||
<a-trigger
|
|
||||||
v-model:popup-visible="statusFilterVisible"
|
|
||||||
trigger="click"
|
|
||||||
@popup-visible-change="handleFilterHidden"
|
|
||||||
>
|
|
||||||
<a-button type="text" class="arco-btn-text--secondary p-[8px_4px]" @click.stop="statusFilterVisible = true">
|
|
||||||
<div class="font-medium">
|
|
||||||
{{ t(columnConfig.title as string) }}
|
|
||||||
</div>
|
|
||||||
<icon-down :class="statusFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
|
||||||
</a-button>
|
|
||||||
<template #content>
|
|
||||||
<div class="arco-table-filters-content">
|
|
||||||
<div class="flex items-center justify-center px-[6px] py-[2px]">
|
|
||||||
<a-checkbox-group
|
|
||||||
v-model:model-value="statusListFiltersMap[showType]"
|
|
||||||
direction="vertical"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<a-checkbox v-for="key of statusFilters" :key="key" :value="key">
|
|
||||||
<ExecutionStatus :module-type="ReportStatusEnum.REPORT_STATUS" :status="key" />
|
|
||||||
</a-checkbox>
|
|
||||||
</a-checkbox-group>
|
|
||||||
</div>
|
|
||||||
<div class="filter-button">
|
|
||||||
<a-button size="mini" class="mr-[8px]" @click="resetStatusFilter">
|
|
||||||
{{ t('common.reset') }}
|
|
||||||
</a-button>
|
|
||||||
<a-button type="primary" size="mini" @click="handleFilterHidden(false)">
|
|
||||||
{{ t('system.orgTemplate.confirm') }}
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-trigger>
|
|
||||||
</template>
|
|
||||||
<!-- 执行状态筛选 -->
|
<!-- 执行状态筛选 -->
|
||||||
<template #execStatusFilter="{ columnConfig }">
|
<template #resultStatus="{ record }">
|
||||||
<a-trigger
|
<ExecutionStatus :module-type="ReportStatusEnum.REPORT_STATUS" :status="record.resultStatus" />
|
||||||
v-model:popup-visible="execStatusFilterVisible"
|
|
||||||
trigger="click"
|
|
||||||
@popup-visible-change="handleExecStatusFilterHidden"
|
|
||||||
>
|
|
||||||
<a-button
|
|
||||||
type="text"
|
|
||||||
class="arco-btn-text--secondary p-[8px_4px]"
|
|
||||||
@click.stop="execStatusFilterVisible = true"
|
|
||||||
>
|
|
||||||
<div class="font-medium">
|
|
||||||
{{ t(columnConfig.title as string) }}
|
|
||||||
</div>
|
|
||||||
<icon-down :class="execStatusFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
|
||||||
</a-button>
|
|
||||||
<template #content>
|
|
||||||
<div class="arco-table-filters-content">
|
|
||||||
<div class="flex items-center justify-center px-[6px] py-[2px]">
|
|
||||||
<a-checkbox-group
|
|
||||||
v-model:model-value="statusListFiltersMap[showType]"
|
|
||||||
direction="vertical"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<a-checkbox v-for="key of execStatusFilters" :key="key" :value="key">
|
|
||||||
<ExecutionStatus :module-type="ReportStatusEnum.EXEC_STATUS" :status="key" />
|
|
||||||
</a-checkbox>
|
|
||||||
</a-checkbox-group>
|
|
||||||
</div>
|
|
||||||
<div class="filter-button">
|
|
||||||
<a-button size="mini" class="mr-[8px]" @click="resetExecStatusFilter">
|
|
||||||
{{ t('common.reset') }}
|
|
||||||
</a-button>
|
|
||||||
<a-button type="primary" size="mini" @click="handleExecStatusFilterHidden(false)">
|
|
||||||
{{ t('system.orgTemplate.confirm') }}
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-trigger>
|
|
||||||
</template>
|
</template>
|
||||||
<template #status="{ record }">
|
<template #execStatus="{ record }">
|
||||||
<ExecutionStatus :module-type="ReportStatusEnum.REPORT_STATUS" :status="record.status" />
|
<ExecutionStatus :module-type="ReportStatusEnum.EXEC_STATUS" :status="record.execStatus" />
|
||||||
|
</template>
|
||||||
|
<template #[FilterSlotNameEnum.TEST_PLAN_REPORT_EXEC_STATUS]="{ filterContent }">
|
||||||
|
<ExecutionStatus :module-type="ReportStatusEnum.EXEC_STATUS" :status="filterContent.value" />
|
||||||
|
</template>
|
||||||
|
<template #[FilterSlotNameEnum.TEST_PLAN_STATUS_FILTER]="{ filterContent }">
|
||||||
|
<ExecutionStatus :module-type="ReportStatusEnum.REPORT_STATUS" :status="filterContent.value" />
|
||||||
</template>
|
</template>
|
||||||
<template #triggerMode="{ record }">
|
<template #triggerMode="{ record }">
|
||||||
<span>{{ t(TriggerModeLabel[record.triggerMode as keyof typeof TriggerModeLabel]) }}</span>
|
<span>{{ t(TriggerModeLabel[record.triggerMode as keyof typeof TriggerModeLabel]) }}</span>
|
||||||
|
@ -225,9 +90,6 @@
|
||||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
import type { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
|
import type { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
|
||||||
import TableFilter from '@/views/case-management/caseManagementFeature/components/tableFilter.vue';
|
|
||||||
import passRateLine from '@/views/test-plan/report/component/passRateLine.vue';
|
|
||||||
import ExecutionStatus from '@/views/test-plan/report/component/reportStatus.vue';
|
import ExecutionStatus from '@/views/test-plan/report/component/reportStatus.vue';
|
||||||
|
|
||||||
import { reportBathDelete, reportDelete, reportList, reportRename } from '@/api/modules/test-plan/report';
|
import { reportBathDelete, reportDelete, reportList, reportRename } from '@/api/modules/test-plan/report';
|
||||||
|
@ -241,6 +103,7 @@
|
||||||
import { BatchApiParams } from '@/models/common';
|
import { BatchApiParams } from '@/models/common';
|
||||||
import { PlanReportStatus, ReportStatusEnum, TriggerModeLabel } from '@/enums/reportEnum';
|
import { PlanReportStatus, ReportStatusEnum, TriggerModeLabel } from '@/enums/reportEnum';
|
||||||
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||||
|
|
||||||
const { openModal } = useModal();
|
const { openModal } = useModal();
|
||||||
|
|
||||||
|
@ -248,16 +111,47 @@
|
||||||
const tableStore = useTableStore();
|
const tableStore = useTableStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const keyword = ref<string>('');
|
const keyword = ref<string>('');
|
||||||
const statusFilterVisible = ref(false);
|
|
||||||
const execStatusFilterVisible = ref(false);
|
|
||||||
|
|
||||||
const triggerModeFilterVisible = ref(false);
|
|
||||||
|
|
||||||
const triggerModeListFilters = ref<string[]>([]);
|
|
||||||
|
|
||||||
type ReportShowType = 'All' | 'INDEPENDENT' | 'INTEGRATED';
|
type ReportShowType = 'All' | 'INDEPENDENT' | 'INTEGRATED';
|
||||||
const showType = ref<ReportShowType>('All');
|
const showType = ref<ReportShowType>('All');
|
||||||
|
|
||||||
|
const executeResultOptions = computed(() => {
|
||||||
|
return Object.keys(PlanReportStatus[ReportStatusEnum.EXEC_STATUS]).map((key) => {
|
||||||
|
return {
|
||||||
|
value: key,
|
||||||
|
label: PlanReportStatus[ReportStatusEnum.EXEC_STATUS][key].statusText,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const statusResultOptions = computed(() => {
|
||||||
|
return Object.keys(PlanReportStatus[ReportStatusEnum.REPORT_STATUS]).map((key) => {
|
||||||
|
return {
|
||||||
|
value: key,
|
||||||
|
label: PlanReportStatus[ReportStatusEnum.REPORT_STATUS][key].statusText,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const triggerModeOptions = computed(() => {
|
||||||
|
return Object.keys(TriggerModeLabel).map((key) => {
|
||||||
|
return {
|
||||||
|
value: key,
|
||||||
|
label: t(TriggerModeLabel[key as keyof typeof TriggerModeLabel]),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const integratedFilters = computed(() => {
|
||||||
|
if (showType.value === 'All') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (showType.value === 'INTEGRATED') {
|
||||||
|
return [true];
|
||||||
|
}
|
||||||
|
return [false];
|
||||||
|
});
|
||||||
|
|
||||||
const columns: MsTableColumn = [
|
const columns: MsTableColumn = [
|
||||||
{
|
{
|
||||||
title: 'report.name',
|
title: 'report.name',
|
||||||
|
@ -286,22 +180,13 @@
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
columnSelectorDisabled: true,
|
columnSelectorDisabled: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: 'report.type',
|
|
||||||
slotName: 'integrated',
|
|
||||||
dataIndex: 'integrated',
|
|
||||||
titleSlotName: 'integratedFilter',
|
|
||||||
width: 150,
|
|
||||||
showDrag: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'report.execStatus',
|
title: 'report.execStatus',
|
||||||
dataIndex: 'execStatus',
|
dataIndex: 'execStatus',
|
||||||
slotName: 'execStatus',
|
slotName: 'execStatus',
|
||||||
titleSlotName: 'execStatusFilter',
|
filterConfig: {
|
||||||
sortable: {
|
options: executeResultOptions.value,
|
||||||
sortDirections: ['ascend', 'descend'],
|
filterSlotName: FilterSlotNameEnum.TEST_PLAN_REPORT_EXEC_STATUS,
|
||||||
sorter: true,
|
|
||||||
},
|
},
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
width: 200,
|
width: 200,
|
||||||
|
@ -310,13 +195,17 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
title: 'report.result',
|
title: 'report.result',
|
||||||
dataIndex: 'status',
|
dataIndex: 'resultStatus',
|
||||||
slotName: 'status',
|
slotName: 'resultStatus',
|
||||||
titleSlotName: 'statusFilter',
|
titleSlotName: 'statusFilter',
|
||||||
sortable: {
|
sortable: {
|
||||||
sortDirections: ['ascend', 'descend'],
|
sortDirections: ['ascend', 'descend'],
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
|
filterConfig: {
|
||||||
|
options: statusResultOptions.value,
|
||||||
|
filterSlotName: FilterSlotNameEnum.TEST_PLAN_STATUS_FILTER,
|
||||||
|
},
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
width: 200,
|
width: 200,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
|
@ -333,13 +222,11 @@
|
||||||
dataIndex: 'triggerMode',
|
dataIndex: 'triggerMode',
|
||||||
slotName: 'triggerMode',
|
slotName: 'triggerMode',
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
sorter: true,
|
|
||||||
},
|
|
||||||
width: 150,
|
width: 150,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
titleSlotName: 'triggerModeFilter',
|
filterConfig: {
|
||||||
|
options: triggerModeOptions.value,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'report.operator',
|
title: 'report.operator',
|
||||||
|
@ -400,72 +287,12 @@
|
||||||
}),
|
}),
|
||||||
rename
|
rename
|
||||||
);
|
);
|
||||||
// 全部过滤条件
|
|
||||||
const allListFilters = ref<string[]>([]);
|
|
||||||
const independentListFilters = ref<string[]>([]);
|
|
||||||
const integratedListFilters = ref<string[]>([]);
|
|
||||||
|
|
||||||
const statusListFiltersMap = ref<Record<string, string[]>>({
|
|
||||||
All: allListFilters.value,
|
|
||||||
INDEPENDENT: independentListFilters.value,
|
|
||||||
INTEGRATED: integratedListFilters.value,
|
|
||||||
});
|
|
||||||
|
|
||||||
const allTriggerModeFilters = ref<string[]>([]);
|
|
||||||
const independentTriggerModeFilters = ref<string[]>([]);
|
|
||||||
const integratedTriggerModeFilters = ref<string[]>([]);
|
|
||||||
const triggerModeListFiltersMaps = ref<Record<string, string[]>>({
|
|
||||||
All: allTriggerModeFilters.value,
|
|
||||||
INDEPENDENT: independentTriggerModeFilters.value,
|
|
||||||
INTEGRATED: integratedTriggerModeFilters.value,
|
|
||||||
});
|
|
||||||
// 全部过滤条件
|
|
||||||
const allIntegratedFilters = ref<string[]>([]);
|
|
||||||
const independentIntegratedFilters = ref<string[]>([]);
|
|
||||||
const integratedIntegratedFilters = ref<string[]>([]);
|
|
||||||
|
|
||||||
const reportTypeVisible = ref<boolean>(false);
|
|
||||||
|
|
||||||
const integratedFiltersMap = ref<Record<string, string[]>>({
|
|
||||||
All: allIntegratedFilters.value,
|
|
||||||
INDEPENDENT: independentIntegratedFilters.value,
|
|
||||||
INTEGRATED: integratedIntegratedFilters.value,
|
|
||||||
});
|
|
||||||
|
|
||||||
const reportTypeList = ref([
|
|
||||||
{
|
|
||||||
value: 'INDEPENDENT',
|
|
||||||
label: t('report.independent'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'INTEGRATED',
|
|
||||||
label: t('report.collection'),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const integratedFilters = computed(() => {
|
|
||||||
if (showType.value === 'All') {
|
|
||||||
if (integratedFiltersMap.value[showType.value].length === 1) {
|
|
||||||
return integratedFiltersMap.value[showType.value].includes('INDEPENDENT') ? [false] : [true];
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (showType.value === 'INTEGRATED') {
|
|
||||||
return [true];
|
|
||||||
}
|
|
||||||
return [false];
|
|
||||||
});
|
|
||||||
|
|
||||||
function initData() {
|
function initData() {
|
||||||
setLoadListParams({
|
setLoadListParams({
|
||||||
keyword: keyword.value,
|
keyword: keyword.value,
|
||||||
projectId: appStore.currentProjectId,
|
projectId: appStore.currentProjectId,
|
||||||
|
filter: { ...propsRes.value.filter, integrated: integratedFilters.value },
|
||||||
filter: {
|
|
||||||
status: statusListFiltersMap.value[showType.value],
|
|
||||||
integrated: integratedFilters.value,
|
|
||||||
triggerMode: triggerModeListFiltersMaps.value[showType.value],
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
loadList();
|
loadList();
|
||||||
}
|
}
|
||||||
|
@ -493,11 +320,7 @@
|
||||||
...params,
|
...params,
|
||||||
selectIds: params?.selectedIds || [],
|
selectIds: params?.selectedIds || [],
|
||||||
condition: {
|
condition: {
|
||||||
filter: {
|
filter: { ...propsRes.value.filter, integrated: integratedFilters.value },
|
||||||
status: statusListFiltersMap.value[showType.value],
|
|
||||||
integrated: integratedFilters.value,
|
|
||||||
triggerMode: triggerModeListFilters.value,
|
|
||||||
},
|
|
||||||
keyword: keyword.value,
|
keyword: keyword.value,
|
||||||
},
|
},
|
||||||
projectId: appStore.currentProjectId,
|
projectId: appStore.currentProjectId,
|
||||||
|
@ -561,51 +384,13 @@
|
||||||
initData();
|
initData();
|
||||||
});
|
});
|
||||||
|
|
||||||
const statusFilters = computed(() => {
|
|
||||||
return Object.keys(PlanReportStatus[ReportStatusEnum.REPORT_STATUS]) || [];
|
|
||||||
});
|
|
||||||
|
|
||||||
const execStatusFilters = computed(() => {
|
|
||||||
return Object.keys(PlanReportStatus[ReportStatusEnum.EXEC_STATUS]) || [];
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleFilterHidden(val: boolean) {
|
|
||||||
if (!val) {
|
|
||||||
triggerModeFilterVisible.value = false;
|
|
||||||
statusFilterVisible.value = false;
|
|
||||||
initData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleExecStatusFilterHidden(val: boolean) {
|
|
||||||
if (!val) {
|
|
||||||
triggerModeFilterVisible.value = false;
|
|
||||||
execStatusFilterVisible.value = false;
|
|
||||||
initData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetTriggerModeFilter() {
|
|
||||||
triggerModeFilterVisible.value = false;
|
|
||||||
triggerModeListFilters.value = [];
|
|
||||||
initData();
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetStatusFilter() {
|
|
||||||
statusFilterVisible.value = false;
|
|
||||||
statusListFiltersMap.value[showType.value] = [];
|
|
||||||
initData();
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetExecStatusFilter() {
|
|
||||||
execStatusFilterVisible.value = false;
|
|
||||||
statusListFiltersMap.value[showType.value] = [];
|
|
||||||
initData();
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeShowType(val: string | number | boolean) {
|
function changeShowType(val: string | number | boolean) {
|
||||||
showType.value = val as ReportShowType;
|
showType.value = val as ReportShowType;
|
||||||
resetSelector();
|
resetSelector();
|
||||||
|
console.log(propsRes.value);
|
||||||
|
propsRes.value.filter = {
|
||||||
|
integrated: integratedFilters.value,
|
||||||
|
};
|
||||||
initData();
|
initData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,8 @@
|
||||||
icon: 'icon-icon_close_colorful',
|
icon: 'icon-icon_close_colorful',
|
||||||
label: 'report.failure',
|
label: 'report.failure',
|
||||||
},
|
},
|
||||||
FAKE_ERROR: {
|
|
||||||
icon: 'icon-icon_warning_colorful',
|
|
||||||
label: 'report.fake.error',
|
|
||||||
},
|
|
||||||
DEFAULT: {
|
DEFAULT: {
|
||||||
icon: 'icon-icon_block_filled',
|
label: '-',
|
||||||
label: 'report.status.pending',
|
|
||||||
color: '!text-[var(--color-text-input-border)]',
|
color: '!text-[var(--color-text-input-border)]',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -58,9 +53,9 @@
|
||||||
label: 'report.status.pending',
|
label: 'report.status.pending',
|
||||||
color: '!text-[var(--color-text-input-border)]',
|
color: '!text-[var(--color-text-input-border)]',
|
||||||
},
|
},
|
||||||
DEFAULT: {
|
COMPLETED: {
|
||||||
icon: 'icon-icon_wait',
|
icon: 'icon-icon_wait',
|
||||||
label: 'report.status.pending',
|
label: 'report.completed',
|
||||||
color: '!text-[var(--color-text-input-border)]',
|
color: '!text-[var(--color-text-input-border)]',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,4 +31,5 @@ export default {
|
||||||
'report.execStatus': 'Execution status',
|
'report.execStatus': 'Execution status',
|
||||||
'report.plan.name': 'Plan Name',
|
'report.plan.name': 'Plan Name',
|
||||||
'report.passRate': 'Pass rate',
|
'report.passRate': 'Pass rate',
|
||||||
|
'report.completed': 'Completed',
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,5 +31,6 @@ export default {
|
||||||
'report.execStatus': '执行状态',
|
'report.execStatus': '执行状态',
|
||||||
'report.plan.name': '计划名称',
|
'report.plan.name': '计划名称',
|
||||||
'report.passRate': '通过率',
|
'report.passRate': '通过率',
|
||||||
'report.passRateTip': 'TODO待补充文案',
|
'report.passRateTip': '测试计划报告通过率',
|
||||||
|
'report.completed': '已完成',
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue