feat(接口调试): 处理接口中上传的文件
This commit is contained in:
parent
93518ad555
commit
8674c0a49f
|
@ -0,0 +1,118 @@
|
|||
package io.metersphere.api.domain;
|
||||
|
||||
import io.metersphere.validation.groups.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ApiFileResource implements Serializable {
|
||||
@Schema(description = "资源ID(接口用例等)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{api_file_resource.resource_id.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{api_file_resource.resource_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String resourceId;
|
||||
|
||||
@Schema(description = "文件ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{api_file_resource.file_id.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{api_file_resource.file_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "文件名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{api_file_resource.file_name.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{api_file_resource.file_name.length_range}", groups = {Created.class, Updated.class})
|
||||
private String fileName;
|
||||
|
||||
@Schema(description = "资源类型(API_DEBUG,API,API_CASE,API_SCENARIO)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{api_file_resource.resource_type.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{api_file_resource.resource_type.length_range}", groups = {Created.class, Updated.class})
|
||||
private String resourceType;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private Long createTime;
|
||||
|
||||
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{api_file_resource.project_id.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{api_file_resource.project_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String projectId;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public enum Column {
|
||||
resourceId("resource_id", "resourceId", "VARCHAR", false),
|
||||
fileId("file_id", "fileId", "VARCHAR", false),
|
||||
fileName("file_name", "fileName", "VARCHAR", false),
|
||||
resourceType("resource_type", "resourceType", "VARCHAR", false),
|
||||
createTime("create_time", "createTime", "BIGINT", false),
|
||||
projectId("project_id", "projectId", "VARCHAR", false);
|
||||
|
||||
private static final String BEGINNING_DELIMITER = "`";
|
||||
|
||||
private static final String ENDING_DELIMITER = "`";
|
||||
|
||||
private final String column;
|
||||
|
||||
private final boolean isColumnNameDelimited;
|
||||
|
||||
private final String javaProperty;
|
||||
|
||||
private final String jdbcType;
|
||||
|
||||
public String value() {
|
||||
return this.column;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.column;
|
||||
}
|
||||
|
||||
public String getJavaProperty() {
|
||||
return this.javaProperty;
|
||||
}
|
||||
|
||||
public String getJdbcType() {
|
||||
return this.jdbcType;
|
||||
}
|
||||
|
||||
Column(String column, String javaProperty, String jdbcType, boolean isColumnNameDelimited) {
|
||||
this.column = column;
|
||||
this.javaProperty = javaProperty;
|
||||
this.jdbcType = jdbcType;
|
||||
this.isColumnNameDelimited = isColumnNameDelimited;
|
||||
}
|
||||
|
||||
public String desc() {
|
||||
return this.getEscapedColumnName() + " DESC";
|
||||
}
|
||||
|
||||
public String asc() {
|
||||
return this.getEscapedColumnName() + " ASC";
|
||||
}
|
||||
|
||||
public static Column[] excludes(Column ... excludes) {
|
||||
ArrayList<Column> columns = new ArrayList<>(Arrays.asList(Column.values()));
|
||||
if (excludes != null && excludes.length > 0) {
|
||||
columns.removeAll(new ArrayList<>(Arrays.asList(excludes)));
|
||||
}
|
||||
return columns.toArray(new Column[]{});
|
||||
}
|
||||
|
||||
public static Column[] all() {
|
||||
return Column.values();
|
||||
}
|
||||
|
||||
public String getEscapedColumnName() {
|
||||
if (this.isColumnNameDelimited) {
|
||||
return new StringBuilder().append(BEGINNING_DELIMITER).append(this.column).append(ENDING_DELIMITER).toString();
|
||||
} else {
|
||||
return this.column;
|
||||
}
|
||||
}
|
||||
|
||||
public String getAliasedEscapedColumnName() {
|
||||
return this.getEscapedColumnName();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,610 @@
|
|||
package io.metersphere.api.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ApiFileResourceExample {
|
||||
protected String orderByClause;
|
||||
|
||||
protected boolean distinct;
|
||||
|
||||
protected List<Criteria> oredCriteria;
|
||||
|
||||
public ApiFileResourceExample() {
|
||||
oredCriteria = new ArrayList<Criteria>();
|
||||
}
|
||||
|
||||
public void setOrderByClause(String orderByClause) {
|
||||
this.orderByClause = orderByClause;
|
||||
}
|
||||
|
||||
public String getOrderByClause() {
|
||||
return orderByClause;
|
||||
}
|
||||
|
||||
public void setDistinct(boolean distinct) {
|
||||
this.distinct = distinct;
|
||||
}
|
||||
|
||||
public boolean isDistinct() {
|
||||
return distinct;
|
||||
}
|
||||
|
||||
public List<Criteria> getOredCriteria() {
|
||||
return oredCriteria;
|
||||
}
|
||||
|
||||
public void or(Criteria criteria) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
|
||||
public Criteria or() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
oredCriteria.add(criteria);
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public Criteria createCriteria() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
if (oredCriteria.size() == 0) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected Criteria createCriteriaInternal() {
|
||||
Criteria criteria = new Criteria();
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
oredCriteria.clear();
|
||||
orderByClause = null;
|
||||
distinct = false;
|
||||
}
|
||||
|
||||
protected abstract static class GeneratedCriteria {
|
||||
protected List<Criterion> criteria;
|
||||
|
||||
protected GeneratedCriteria() {
|
||||
super();
|
||||
criteria = new ArrayList<Criterion>();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return criteria.size() > 0;
|
||||
}
|
||||
|
||||
public List<Criterion> getAllCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public List<Criterion> getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition) {
|
||||
if (condition == null) {
|
||||
throw new RuntimeException("Value for condition cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value, String property) {
|
||||
if (value == null) {
|
||||
throw new RuntimeException("Value for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value1, Object value2, String property) {
|
||||
if (value1 == null || value2 == null) {
|
||||
throw new RuntimeException("Between values for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value1, value2));
|
||||
}
|
||||
|
||||
public Criteria andResourceIdIsNull() {
|
||||
addCriterion("resource_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdIsNotNull() {
|
||||
addCriterion("resource_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdEqualTo(String value) {
|
||||
addCriterion("resource_id =", value, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdNotEqualTo(String value) {
|
||||
addCriterion("resource_id <>", value, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdGreaterThan(String value) {
|
||||
addCriterion("resource_id >", value, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("resource_id >=", value, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdLessThan(String value) {
|
||||
addCriterion("resource_id <", value, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("resource_id <=", value, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdLike(String value) {
|
||||
addCriterion("resource_id like", value, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdNotLike(String value) {
|
||||
addCriterion("resource_id not like", value, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdIn(List<String> values) {
|
||||
addCriterion("resource_id in", values, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdNotIn(List<String> values) {
|
||||
addCriterion("resource_id not in", values, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdBetween(String value1, String value2) {
|
||||
addCriterion("resource_id between", value1, value2, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceIdNotBetween(String value1, String value2) {
|
||||
addCriterion("resource_id not between", value1, value2, "resourceId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdIsNull() {
|
||||
addCriterion("file_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdIsNotNull() {
|
||||
addCriterion("file_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdEqualTo(String value) {
|
||||
addCriterion("file_id =", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdNotEqualTo(String value) {
|
||||
addCriterion("file_id <>", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdGreaterThan(String value) {
|
||||
addCriterion("file_id >", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("file_id >=", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdLessThan(String value) {
|
||||
addCriterion("file_id <", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("file_id <=", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdLike(String value) {
|
||||
addCriterion("file_id like", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdNotLike(String value) {
|
||||
addCriterion("file_id not like", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdIn(List<String> values) {
|
||||
addCriterion("file_id in", values, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdNotIn(List<String> values) {
|
||||
addCriterion("file_id not in", values, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdBetween(String value1, String value2) {
|
||||
addCriterion("file_id between", value1, value2, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdNotBetween(String value1, String value2) {
|
||||
addCriterion("file_id not between", value1, value2, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameIsNull() {
|
||||
addCriterion("file_name is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameIsNotNull() {
|
||||
addCriterion("file_name is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameEqualTo(String value) {
|
||||
addCriterion("file_name =", value, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameNotEqualTo(String value) {
|
||||
addCriterion("file_name <>", value, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameGreaterThan(String value) {
|
||||
addCriterion("file_name >", value, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("file_name >=", value, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameLessThan(String value) {
|
||||
addCriterion("file_name <", value, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameLessThanOrEqualTo(String value) {
|
||||
addCriterion("file_name <=", value, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameLike(String value) {
|
||||
addCriterion("file_name like", value, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameNotLike(String value) {
|
||||
addCriterion("file_name not like", value, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameIn(List<String> values) {
|
||||
addCriterion("file_name in", values, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameNotIn(List<String> values) {
|
||||
addCriterion("file_name not in", values, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameBetween(String value1, String value2) {
|
||||
addCriterion("file_name between", value1, value2, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileNameNotBetween(String value1, String value2) {
|
||||
addCriterion("file_name not between", value1, value2, "fileName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeIsNull() {
|
||||
addCriterion("resource_type is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeIsNotNull() {
|
||||
addCriterion("resource_type is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeEqualTo(String value) {
|
||||
addCriterion("resource_type =", value, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeNotEqualTo(String value) {
|
||||
addCriterion("resource_type <>", value, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeGreaterThan(String value) {
|
||||
addCriterion("resource_type >", value, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("resource_type >=", value, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeLessThan(String value) {
|
||||
addCriterion("resource_type <", value, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeLessThanOrEqualTo(String value) {
|
||||
addCriterion("resource_type <=", value, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeLike(String value) {
|
||||
addCriterion("resource_type like", value, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeNotLike(String value) {
|
||||
addCriterion("resource_type not like", value, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeIn(List<String> values) {
|
||||
addCriterion("resource_type in", values, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeNotIn(List<String> values) {
|
||||
addCriterion("resource_type not in", values, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeBetween(String value1, String value2) {
|
||||
addCriterion("resource_type between", value1, value2, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andResourceTypeNotBetween(String value1, String value2) {
|
||||
addCriterion("resource_type not between", value1, value2, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIsNull() {
|
||||
addCriterion("create_time is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIsNotNull() {
|
||||
addCriterion("create_time is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeEqualTo(Long value) {
|
||||
addCriterion("create_time =", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeNotEqualTo(Long value) {
|
||||
addCriterion("create_time <>", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeGreaterThan(Long value) {
|
||||
addCriterion("create_time >", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("create_time >=", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeLessThan(Long value) {
|
||||
addCriterion("create_time <", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeLessThanOrEqualTo(Long value) {
|
||||
addCriterion("create_time <=", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIn(List<Long> values) {
|
||||
addCriterion("create_time in", values, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeNotIn(List<Long> values) {
|
||||
addCriterion("create_time not in", values, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeBetween(Long value1, Long value2) {
|
||||
addCriterion("create_time between", value1, value2, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeNotBetween(Long value1, Long value2) {
|
||||
addCriterion("create_time not between", value1, value2, "createTime");
|
||||
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 static class Criteria extends GeneratedCriteria {
|
||||
|
||||
protected Criteria() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criterion {
|
||||
private String condition;
|
||||
|
||||
private Object value;
|
||||
|
||||
private Object secondValue;
|
||||
|
||||
private boolean noValue;
|
||||
|
||||
private boolean singleValue;
|
||||
|
||||
private boolean betweenValue;
|
||||
|
||||
private boolean listValue;
|
||||
|
||||
private String typeHandler;
|
||||
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object getSecondValue() {
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
public boolean isNoValue() {
|
||||
return noValue;
|
||||
}
|
||||
|
||||
public boolean isSingleValue() {
|
||||
return singleValue;
|
||||
}
|
||||
|
||||
public boolean isBetweenValue() {
|
||||
return betweenValue;
|
||||
}
|
||||
|
||||
public boolean isListValue() {
|
||||
return listValue;
|
||||
}
|
||||
|
||||
public String getTypeHandler() {
|
||||
return typeHandler;
|
||||
}
|
||||
|
||||
protected Criterion(String condition) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.typeHandler = null;
|
||||
this.noValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.typeHandler = typeHandler;
|
||||
if (value instanceof List<?>) {
|
||||
this.listValue = true;
|
||||
} else {
|
||||
this.singleValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value) {
|
||||
this(condition, value, null);
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.secondValue = secondValue;
|
||||
this.typeHandler = typeHandler;
|
||||
this.betweenValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue) {
|
||||
this(condition, value, secondValue, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.metersphere.api.mapper;
|
||||
|
||||
import io.metersphere.api.domain.ApiFileResource;
|
||||
import io.metersphere.api.domain.ApiFileResourceExample;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface ApiFileResourceMapper {
|
||||
long countByExample(ApiFileResourceExample example);
|
||||
|
||||
int deleteByExample(ApiFileResourceExample example);
|
||||
|
||||
int deleteByPrimaryKey(@Param("resourceId") String resourceId, @Param("fileId") String fileId);
|
||||
|
||||
int insert(ApiFileResource record);
|
||||
|
||||
int insertSelective(ApiFileResource record);
|
||||
|
||||
List<ApiFileResource> selectByExample(ApiFileResourceExample example);
|
||||
|
||||
ApiFileResource selectByPrimaryKey(@Param("resourceId") String resourceId, @Param("fileId") String fileId);
|
||||
|
||||
int updateByExampleSelective(@Param("record") ApiFileResource record, @Param("example") ApiFileResourceExample example);
|
||||
|
||||
int updateByExample(@Param("record") ApiFileResource record, @Param("example") ApiFileResourceExample example);
|
||||
|
||||
int updateByPrimaryKeySelective(ApiFileResource record);
|
||||
|
||||
int updateByPrimaryKey(ApiFileResource record);
|
||||
|
||||
int batchInsert(@Param("list") List<ApiFileResource> list);
|
||||
|
||||
int batchInsertSelective(@Param("list") List<ApiFileResource> list, @Param("selective") ApiFileResource.Column ... selective);
|
||||
}
|
|
@ -0,0 +1,270 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.metersphere.api.mapper.ApiFileResourceMapper">
|
||||
<resultMap id="BaseResultMap" type="io.metersphere.api.domain.ApiFileResource">
|
||||
<id column="resource_id" jdbcType="VARCHAR" property="resourceId" />
|
||||
<id column="file_id" jdbcType="VARCHAR" property="fileId" />
|
||||
<result column="file_name" jdbcType="VARCHAR" property="fileName" />
|
||||
<result column="resource_type" jdbcType="VARCHAR" property="resourceType" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Update_By_Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="example.oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
resource_id, file_id, file_name, resource_type, create_time, project_id
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.api.domain.ApiFileResourceExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
from api_file_resource
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByPrimaryKey" parameterType="map" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
from api_file_resource
|
||||
where resource_id = #{resourceId,jdbcType=VARCHAR}
|
||||
and file_id = #{fileId,jdbcType=VARCHAR}
|
||||
</select>
|
||||
<delete id="deleteByPrimaryKey" parameterType="map">
|
||||
delete from api_file_resource
|
||||
where resource_id = #{resourceId,jdbcType=VARCHAR}
|
||||
and file_id = #{fileId,jdbcType=VARCHAR}
|
||||
</delete>
|
||||
<delete id="deleteByExample" parameterType="io.metersphere.api.domain.ApiFileResourceExample">
|
||||
delete from api_file_resource
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.api.domain.ApiFileResource">
|
||||
insert into api_file_resource (resource_id, file_id, file_name,
|
||||
resource_type, create_time, project_id
|
||||
)
|
||||
values (#{resourceId,jdbcType=VARCHAR}, #{fileId,jdbcType=VARCHAR}, #{fileName,jdbcType=VARCHAR},
|
||||
#{resourceType,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{projectId,jdbcType=VARCHAR}
|
||||
)
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.api.domain.ApiFileResource">
|
||||
insert into api_file_resource
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="resourceId != null">
|
||||
resource_id,
|
||||
</if>
|
||||
<if test="fileId != null">
|
||||
file_id,
|
||||
</if>
|
||||
<if test="fileName != null">
|
||||
file_name,
|
||||
</if>
|
||||
<if test="resourceType != null">
|
||||
resource_type,
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time,
|
||||
</if>
|
||||
<if test="projectId != null">
|
||||
project_id,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="resourceId != null">
|
||||
#{resourceId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="fileId != null">
|
||||
#{fileId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="fileName != null">
|
||||
#{fileName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="resourceType != null">
|
||||
#{resourceType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
#{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="projectId != null">
|
||||
#{projectId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.api.domain.ApiFileResourceExample" resultType="java.lang.Long">
|
||||
select count(*) from api_file_resource
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</select>
|
||||
<update id="updateByExampleSelective" parameterType="map">
|
||||
update api_file_resource
|
||||
<set>
|
||||
<if test="record.resourceId != null">
|
||||
resource_id = #{record.resourceId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.fileId != null">
|
||||
file_id = #{record.fileId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.fileName != null">
|
||||
file_name = #{record.fileName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.resourceType != null">
|
||||
resource_type = #{record.resourceType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.createTime != null">
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="record.projectId != null">
|
||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update api_file_resource
|
||||
set resource_id = #{record.resourceId,jdbcType=VARCHAR},
|
||||
file_id = #{record.fileId,jdbcType=VARCHAR},
|
||||
file_name = #{record.fileName,jdbcType=VARCHAR},
|
||||
resource_type = #{record.resourceType,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
project_id = #{record.projectId,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.api.domain.ApiFileResource">
|
||||
update api_file_resource
|
||||
<set>
|
||||
<if test="fileName != null">
|
||||
file_name = #{fileName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="resourceType != null">
|
||||
resource_type = #{resourceType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="projectId != null">
|
||||
project_id = #{projectId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where resource_id = #{resourceId,jdbcType=VARCHAR}
|
||||
and file_id = #{fileId,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="io.metersphere.api.domain.ApiFileResource">
|
||||
update api_file_resource
|
||||
set file_name = #{fileName,jdbcType=VARCHAR},
|
||||
resource_type = #{resourceType,jdbcType=VARCHAR},
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
project_id = #{projectId,jdbcType=VARCHAR}
|
||||
where resource_id = #{resourceId,jdbcType=VARCHAR}
|
||||
and file_id = #{fileId,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<insert id="batchInsert" parameterType="map">
|
||||
insert into api_file_resource
|
||||
(resource_id, file_id, file_name, resource_type, create_time, project_id)
|
||||
values
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(#{item.resourceId,jdbcType=VARCHAR}, #{item.fileId,jdbcType=VARCHAR}, #{item.fileName,jdbcType=VARCHAR},
|
||||
#{item.resourceType,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.projectId,jdbcType=VARCHAR}
|
||||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
<insert id="batchInsertSelective" parameterType="map">
|
||||
insert into api_file_resource (
|
||||
<foreach collection="selective" item="column" separator=",">
|
||||
${column.escapedColumnName}
|
||||
</foreach>
|
||||
)
|
||||
values
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(
|
||||
<foreach collection="selective" item="column" separator=",">
|
||||
<if test="'resource_id'.toString() == column.value">
|
||||
#{item.resourceId,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="'file_id'.toString() == column.value">
|
||||
#{item.fileId,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="'file_name'.toString() == column.value">
|
||||
#{item.fileName,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="'resource_type'.toString() == column.value">
|
||||
#{item.resourceType,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="'create_time'.toString() == column.value">
|
||||
#{item.createTime,jdbcType=BIGINT}
|
||||
</if>
|
||||
<if test="'project_id'.toString() == column.value">
|
||||
#{item.projectId,jdbcType=VARCHAR}
|
||||
</if>
|
||||
</foreach>
|
||||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
</mapper>
|
|
@ -508,5 +508,16 @@ CREATE INDEX idx_api_scenario_id ON api_scenario_environment(api_scenario_id);
|
|||
CREATE INDEX idx_project_id ON api_scenario_environment(project_id);
|
||||
CREATE INDEX idx_environment_id ON api_scenario_environment(environment_id);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS api_file_resource(
|
||||
`resource_id` VARCHAR(50) NOT NULL COMMENT '资源ID(接口用例等)' ,
|
||||
`file_id` VARCHAR(50) NOT NULL COMMENT '文件ID' ,
|
||||
`file_name` VARCHAR(50) NOT NULL COMMENT '文件名称' ,
|
||||
`resource_type` VARCHAR(50) NOT NULL COMMENT '资源类型(API_DEBUG,API,API_CASE,API_SCENARIO)' ,
|
||||
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
|
||||
`project_id` VARCHAR(50) NOT NULL COMMENT '项目ID' ,
|
||||
PRIMARY KEY (resource_id,file_id)
|
||||
) COMMENT = '接口和所需文件资源的关联表';
|
||||
|
||||
-- set innodb lock wait timeout to default
|
||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
|
@ -41,6 +41,11 @@ public class DefaultRepositoryDir {
|
|||
private static final String PROJECT_ENV_SSL_DIR = PROJECT_DIR + "/environment/%s";
|
||||
private static final String PROJECT_FUNCTIONAL_CASE_DIR = PROJECT_DIR + "/functional-case/%s";
|
||||
private static final String PROJECT_FILE_MANAGEMENT_DIR = PROJECT_DIR + "/file-management";
|
||||
/**
|
||||
* 接口调试相关文件的存储目录
|
||||
* project/{projectId}/apiCase/{apiDebugId}
|
||||
*/
|
||||
private static final String PROJECT_API_DEBUG_DIR = PROJECT_DIR + "/api-debug/%s";
|
||||
private static final String PROJECT_BUG_DIR = PROJECT_DIR + "/bug/%s";
|
||||
|
||||
/*------ end: 项目下资源目录 --------*/
|
||||
|
@ -73,4 +78,8 @@ public class DefaultRepositoryDir {
|
|||
public static String getBugDir(String projectId, String bugId) {
|
||||
return String.format(PROJECT_BUG_DIR, projectId, bugId);
|
||||
}
|
||||
|
||||
public static String getApiDebugDir(String projectId, String apiDebugId) {
|
||||
return String.format(PROJECT_API_DEBUG_DIR, projectId, apiDebugId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,4 +15,9 @@ public class FormDataKV extends KeyValueParam {
|
|||
private Integer maxLength;
|
||||
private String contentType;
|
||||
private Boolean encode = false;
|
||||
/**
|
||||
* 记录文件的ID,防止重名
|
||||
* 生成脚本时,通过 fileId + value(文件名) 获取文件路径
|
||||
*/
|
||||
private String fileId;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package io.metersphere.api.constants;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-11-16 16:57
|
||||
*/
|
||||
public enum ApiResourceType {
|
||||
API_DEBUG, API, API_CASE, API_SCENARIO
|
||||
}
|
|
@ -17,6 +17,7 @@ import jakarta.annotation.Resource;
|
|||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -50,16 +51,18 @@ public class ApiDebugController {
|
|||
@Operation(summary = "创建接口调试")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_ADD)
|
||||
@Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = ApiDebugLogService.class)
|
||||
public ApiDebug add(@Validated @RequestBody ApiDebugAddRequest request) {
|
||||
return apiDebugService.add(request, SessionUtils.getUserId());
|
||||
public ApiDebug add(@Validated @RequestPart("request") ApiDebugAddRequest request,
|
||||
@RequestPart(value = "files", required = false) List<MultipartFile> files) {
|
||||
return apiDebugService.add(request, files, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@Operation(summary = "更新接口调试")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_UPDATE)
|
||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = ApiDebugLogService.class)
|
||||
public ApiDebug update(@Validated @RequestBody ApiDebugUpdateRequest request) {
|
||||
return apiDebugService.update(request, SessionUtils.getUserId());
|
||||
public ApiDebug update(@Validated @RequestPart("request") ApiDebugUpdateRequest request,
|
||||
@RequestPart(value = "files", required = false) List<MultipartFile> files) {
|
||||
return apiDebugService.update(request, files, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{id}")
|
||||
|
|
|
@ -6,6 +6,7 @@ import jakarta.validation.constraints.Size;
|
|||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
|
@ -45,4 +46,13 @@ public class ApiDebugAddRequest implements Serializable {
|
|||
@Schema(description = "请求内容")
|
||||
@NotBlank
|
||||
private String request;
|
||||
|
||||
/**
|
||||
* 文件ID列表
|
||||
* 需要和上传的文件顺序保持一致
|
||||
* 为了解决文件名称重复的问题,需要把文件和ID一一对应
|
||||
* 创建时先按ID创建目录,再把文件放入目录
|
||||
*/
|
||||
@Schema(description = "接口所需的所有文件资源ID,与上传的文件顺序保持一致")
|
||||
private List<String> fileIds;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
|||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ApiDebugDTO extends ApiDebug {
|
||||
@Schema(description = "请求内容")
|
||||
|
@ -12,4 +14,7 @@ public class ApiDebugDTO extends ApiDebug {
|
|||
|
||||
@Schema(description = "响应内容")
|
||||
private String response;
|
||||
|
||||
@Schema(description = "接口所关联的文件ID列表,修改时需要作为参数传入")
|
||||
private List<String> fileIds;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import jakarta.validation.constraints.Size;
|
|||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
|
@ -42,4 +43,15 @@ public class ApiDebugUpdateRequest implements Serializable {
|
|||
@Schema(description = "请求内容")
|
||||
@NotBlank
|
||||
private String request;
|
||||
|
||||
@Schema(description = "接口所需的所有文件资源ID")
|
||||
private List<String> fileIds;
|
||||
|
||||
/**
|
||||
* 新上传的文件ID
|
||||
* 为了解决文件名称重复的问题,需要把文件和ID一一对应
|
||||
* 创建时先按ID创建目录,再把文件放入目录
|
||||
*/
|
||||
@Schema(description = "新上传的文件ID,与上传的文件顺序保持一致")
|
||||
private List<String> addFileIds;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package io.metersphere.api.dto.debug;
|
||||
|
||||
import io.metersphere.api.constants.ApiResourceType;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-11-06 10:22
|
||||
*/
|
||||
@Data
|
||||
public class ApiFileResourceUpdateRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
private String projectId;
|
||||
/**
|
||||
* 资源类型
|
||||
*/
|
||||
private ApiResourceType apiResourceType;
|
||||
/**
|
||||
* 关联的资源ID
|
||||
*/
|
||||
private String resourceId;
|
||||
/**
|
||||
* 文件存储的目录
|
||||
*/
|
||||
private String folder;
|
||||
/**
|
||||
* 接口所需的所有文件资源ID
|
||||
*/
|
||||
private List<String> fileIds;
|
||||
|
||||
/**
|
||||
* 新上传的文件ID
|
||||
* 更新时记录新上传的文件ID,与上传的文件顺序保持一致
|
||||
*/
|
||||
private List<String> addFileIds;
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
package io.metersphere.api.service;
|
||||
|
||||
import io.metersphere.api.constants.ApiResourceType;
|
||||
import io.metersphere.api.domain.ApiFileResource;
|
||||
import io.metersphere.api.domain.ApiFileResourceExample;
|
||||
import io.metersphere.api.dto.debug.ApiFileResourceUpdateRequest;
|
||||
import io.metersphere.api.mapper.ApiFileResourceMapper;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.file.FileCenter;
|
||||
import io.metersphere.system.file.FileRequest;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-11-16 16:49
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ApiFileResourceService {
|
||||
@Resource
|
||||
private ApiFileResourceMapper apiFileResourceMapper;
|
||||
|
||||
/**
|
||||
* 上传接口相关的资源文件
|
||||
* @param folder
|
||||
* @param files
|
||||
*/
|
||||
public void uploadFileResource(String folder, List<String> addFileIds, List<MultipartFile> files) {
|
||||
if (CollectionUtils.isEmpty(files) || CollectionUtils.isEmpty(addFileIds)) {
|
||||
return;
|
||||
}
|
||||
int size = addFileIds.size() > files.size() ? addFileIds.size() : files.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
String fileId = addFileIds.get(i);
|
||||
MultipartFile file = files.get(i);
|
||||
FileRequest fileRequest = new FileRequest();
|
||||
fileRequest.setFileName(file.getOriginalFilename());
|
||||
// 按ID建文件夹,避免文件名重复
|
||||
fileRequest.setFolder(folder + "/" + fileId);
|
||||
try {
|
||||
FileCenter.getDefaultRepository()
|
||||
.saveFile(file, fileRequest);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(e);
|
||||
throw new MSException(Translator.get("file_upload_fail"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加接口与文件的关联关系
|
||||
*/
|
||||
public void addFileResource(ApiFileResourceUpdateRequest resourceUpdateRequest, List<MultipartFile> files) {
|
||||
List<String> addFileIds = resourceUpdateRequest.getAddFileIds();
|
||||
String resourceId = resourceUpdateRequest.getResourceId();
|
||||
String projectId = resourceUpdateRequest.getProjectId();
|
||||
ApiResourceType apiResourceType = resourceUpdateRequest.getApiResourceType();
|
||||
if (CollectionUtils.isEmpty(addFileIds) || CollectionUtils.isEmpty(files)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加文件与接口的关联关系
|
||||
int size = addFileIds.size() > files.size() ? addFileIds.size() : files.size();
|
||||
List<ApiFileResource> apiFileResources = new ArrayList<>();
|
||||
for (int i = 0; i < size; i++) {
|
||||
String fileId = addFileIds.get(i);
|
||||
MultipartFile file = files.get(i);
|
||||
ApiFileResource apiFileResource = new ApiFileResource();
|
||||
apiFileResource.setFileId(fileId);
|
||||
apiFileResource.setResourceId(resourceId);
|
||||
apiFileResource.setResourceType(apiResourceType.name());
|
||||
apiFileResource.setProjectId(projectId);
|
||||
apiFileResource.setCreateTime(System.currentTimeMillis());
|
||||
apiFileResource.setFileName(file.getOriginalFilename());
|
||||
apiFileResources.add(apiFileResource);
|
||||
}
|
||||
apiFileResourceMapper.batchInsert(apiFileResources);
|
||||
|
||||
// 上传文件到对象存储
|
||||
uploadFileResource(resourceUpdateRequest.getFolder(), addFileIds, files);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新接口时,更新接口与文件的关联关系
|
||||
*/
|
||||
public void updateFileResource(ApiFileResourceUpdateRequest resourceUpdateRequest, List<MultipartFile> files) {
|
||||
// fileIds == null ,则不修改,如果是空数组则删除所有关联的文件
|
||||
List<String> fileIds = resourceUpdateRequest.getFileIds();
|
||||
String resourceId = resourceUpdateRequest.getResourceId();
|
||||
if (fileIds == null) {
|
||||
return;
|
||||
}
|
||||
// 查询原本关联的文件
|
||||
ApiFileResourceExample example = new ApiFileResourceExample();
|
||||
example.createCriteria().andResourceIdEqualTo(resourceId);
|
||||
List<ApiFileResource> apiFileResources = apiFileResourceMapper.selectByExample(example);
|
||||
List<String> originFileIds = apiFileResources.stream()
|
||||
.map(ApiFileResource::getFileId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 删除没用的文件
|
||||
List<String> deleteFileIds = ListUtils.subtract(originFileIds, fileIds);
|
||||
deleteFileResource(deleteFileIds, resourceUpdateRequest);
|
||||
|
||||
// 上传新的文件
|
||||
addFileResource(resourceUpdateRequest, files);
|
||||
}
|
||||
|
||||
private void deleteFileResource(List<String> deleteFileIds, ApiFileResourceUpdateRequest resourceUpdateRequest) {
|
||||
if (CollectionUtils.isEmpty(deleteFileIds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 删除关联关系
|
||||
ApiFileResourceExample example = new ApiFileResourceExample();
|
||||
example.createCriteria()
|
||||
.andResourceIdEqualTo(resourceUpdateRequest.getResourceId())
|
||||
.andFileIdIn(deleteFileIds);
|
||||
apiFileResourceMapper.deleteByExample(example);
|
||||
|
||||
deleteFileIds.forEach(fileId -> {
|
||||
FileRequest request = new FileRequest();
|
||||
// 删除文件所在目录
|
||||
request.setFolder(resourceUpdateRequest.getFolder() + "/" + fileId);
|
||||
try {
|
||||
FileCenter.getDefaultRepository().deleteFolder(request);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteByResourceId(String apiDebugDir, String resourceId) {
|
||||
ApiFileResourceExample example = new ApiFileResourceExample();
|
||||
example.createCriteria()
|
||||
.andResourceIdEqualTo(resourceId);
|
||||
apiFileResourceMapper.deleteByExample(example);
|
||||
FileRequest request = new FileRequest();
|
||||
request.setFolder(apiDebugDir);
|
||||
try {
|
||||
FileCenter.getDefaultRepository().deleteFolder(request);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ApiFileResource> getByResourceId(String resourceId) {
|
||||
ApiFileResourceExample example = new ApiFileResourceExample();
|
||||
example.createCriteria()
|
||||
.andResourceIdEqualTo(resourceId);
|
||||
return apiFileResourceMapper.selectByExample(example);
|
||||
}
|
||||
public List<String> getFileIdsByResourceId(String resourceId) {
|
||||
return getByResourceId(resourceId).stream()
|
||||
.map(ApiFileResource::getFileId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
package io.metersphere.api.service.debug;
|
||||
|
||||
import io.metersphere.api.constants.ApiResourceType;
|
||||
import io.metersphere.api.domain.ApiDebug;
|
||||
import io.metersphere.api.domain.ApiDebugBlob;
|
||||
import io.metersphere.api.domain.ApiDebugExample;
|
||||
import io.metersphere.api.dto.debug.ApiDebugAddRequest;
|
||||
import io.metersphere.api.dto.debug.ApiDebugDTO;
|
||||
import io.metersphere.api.dto.debug.ApiDebugSimpleDTO;
|
||||
import io.metersphere.api.dto.debug.ApiDebugUpdateRequest;
|
||||
import io.metersphere.api.dto.debug.*;
|
||||
import io.metersphere.api.mapper.ApiDebugBlobMapper;
|
||||
import io.metersphere.api.mapper.ApiDebugMapper;
|
||||
import io.metersphere.api.mapper.ExtApiDebugMapper;
|
||||
import io.metersphere.api.service.ApiFileResourceService;
|
||||
import io.metersphere.api.util.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.service.ProjectService;
|
||||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
|
@ -22,6 +22,7 @@ import org.apache.commons.collections.CollectionUtils;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -34,13 +35,14 @@ import static io.metersphere.api.controller.result.ApiResultCode.API_DEBUG_EXIST
|
|||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ApiDebugService {
|
||||
|
||||
@Resource
|
||||
private ApiDebugMapper apiDebugMapper;
|
||||
@Resource
|
||||
private ApiDebugBlobMapper apiDebugBlobMapper;
|
||||
@Resource
|
||||
private ExtApiDebugMapper extApiDebugMapper;
|
||||
@Resource
|
||||
private ApiFileResourceService apiFileResourceService;
|
||||
|
||||
public List<ApiDebugSimpleDTO> list(String protocol, String userId) {
|
||||
return extApiDebugMapper.list(protocol, userId);
|
||||
|
@ -54,10 +56,11 @@ public class ApiDebugService {
|
|||
BeanUtils.copyBean(apiDebugDTO, apiDebug);
|
||||
apiDebugDTO.setRequest(ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class));
|
||||
apiDebugDTO.setResponse(apiDebugDTO.getResponse());
|
||||
apiDebugDTO.setFileIds(apiFileResourceService.getFileIdsByResourceId(id));
|
||||
return apiDebugDTO;
|
||||
}
|
||||
|
||||
public ApiDebug add(ApiDebugAddRequest request, String createUser) {
|
||||
public ApiDebug add(ApiDebugAddRequest request, List<MultipartFile> files, String createUser) {
|
||||
ProjectService.checkResourceExist(request.getProjectId());
|
||||
ApiDebug apiDebug = new ApiDebug();
|
||||
BeanUtils.copyBean(apiDebug, request);
|
||||
|
@ -68,18 +71,27 @@ public class ApiDebugService {
|
|||
apiDebug.setUpdateTime(System.currentTimeMillis());
|
||||
apiDebug.setUpdateUser(apiDebug.getCreateUser());
|
||||
apiDebugMapper.insert(apiDebug);
|
||||
|
||||
// todo 处理 body 文件
|
||||
// todo 校验 moduleId
|
||||
|
||||
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
||||
apiDebugBlob.setId(apiDebug.getId());
|
||||
apiDebugBlob.setRequest(request.getRequest().getBytes());
|
||||
apiDebugBlobMapper.insert(apiDebugBlob);
|
||||
|
||||
// 处理文件
|
||||
String apiDebugDir = DefaultRepositoryDir.getApiDebugDir(request.getProjectId(), apiDebug.getId());
|
||||
ApiFileResourceUpdateRequest resourceUpdateRequest = new ApiFileResourceUpdateRequest();
|
||||
resourceUpdateRequest.setProjectId(apiDebug.getProjectId());
|
||||
resourceUpdateRequest.setFileIds(request.getFileIds());
|
||||
resourceUpdateRequest.setAddFileIds(request.getFileIds());
|
||||
resourceUpdateRequest.setFolder(apiDebugDir);
|
||||
resourceUpdateRequest.setResourceId(apiDebug.getId());
|
||||
resourceUpdateRequest.setApiResourceType(ApiResourceType.API_DEBUG);
|
||||
apiFileResourceService.addFileResource(resourceUpdateRequest, files);
|
||||
return apiDebug;
|
||||
}
|
||||
|
||||
public ApiDebug update(ApiDebugUpdateRequest request, String updateUser) {
|
||||
|
||||
public ApiDebug update(ApiDebugUpdateRequest request, List<MultipartFile> files, String updateUser) {
|
||||
checkResourceExist(request.getId());
|
||||
ApiDebug apiDebug = BeanUtils.copyBean(new ApiDebug(), request);
|
||||
ApiDebug originApiDebug = apiDebugMapper.selectByPrimaryKey(request.getId());
|
||||
|
@ -87,21 +99,34 @@ public class ApiDebugService {
|
|||
apiDebug.setUpdateUser(updateUser);
|
||||
apiDebug.setUpdateTime(System.currentTimeMillis());
|
||||
apiDebugMapper.updateByPrimaryKeySelective(apiDebug);
|
||||
|
||||
// todo 处理 body 文件
|
||||
// todo 校验 moduleId
|
||||
|
||||
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
||||
apiDebugBlob.setId(request.getId());
|
||||
apiDebugBlob.setRequest(request.getRequest().getBytes());
|
||||
apiDebugBlobMapper.updateByPrimaryKeySelective(apiDebugBlob);
|
||||
|
||||
String apiDebugDir = DefaultRepositoryDir.getApiDebugDir(originApiDebug.getProjectId(), originApiDebug.getId());
|
||||
|
||||
// 处理文件
|
||||
ApiFileResourceUpdateRequest resourceUpdateRequest = new ApiFileResourceUpdateRequest();
|
||||
resourceUpdateRequest.setProjectId(originApiDebug.getProjectId());
|
||||
resourceUpdateRequest.setFileIds(request.getFileIds());
|
||||
resourceUpdateRequest.setAddFileIds(request.getAddFileIds());
|
||||
resourceUpdateRequest.setFolder(apiDebugDir);
|
||||
resourceUpdateRequest.setResourceId(apiDebug.getId());
|
||||
resourceUpdateRequest.setApiResourceType(ApiResourceType.API_DEBUG);
|
||||
apiFileResourceService.updateFileResource(resourceUpdateRequest, files);
|
||||
return apiDebug;
|
||||
}
|
||||
|
||||
public void delete(String id) {
|
||||
ApiDebug apiDebug = apiDebugMapper.selectByPrimaryKey(id);
|
||||
checkResourceExist(id);
|
||||
apiDebugMapper.deleteByPrimaryKey(id);
|
||||
apiDebugBlobMapper.deleteByPrimaryKey(id);
|
||||
String apiDebugDir = DefaultRepositoryDir.getApiDebugDir(apiDebug.getProjectId(), apiDebug.getId());
|
||||
apiFileResourceService.deleteByResourceId(apiDebugDir, id);
|
||||
}
|
||||
|
||||
private void checkAddExist(ApiDebug apiDebug) {
|
||||
|
|
|
@ -1,29 +1,35 @@
|
|||
package io.metersphere.api.controller;
|
||||
|
||||
import io.metersphere.api.controller.param.ApiDebugAddRequestDefinition;
|
||||
import io.metersphere.api.controller.param.ApiDebugUpdateRequestDefinition;
|
||||
import io.metersphere.api.domain.ApiDebug;
|
||||
import io.metersphere.api.domain.ApiDebugBlob;
|
||||
import io.metersphere.api.domain.ApiFileResource;
|
||||
import io.metersphere.api.dto.debug.ApiDebugAddRequest;
|
||||
import io.metersphere.api.dto.debug.ApiDebugDTO;
|
||||
import io.metersphere.api.dto.debug.ApiDebugSimpleDTO;
|
||||
import io.metersphere.api.dto.debug.ApiDebugUpdateRequest;
|
||||
import io.metersphere.api.mapper.ApiDebugBlobMapper;
|
||||
import io.metersphere.api.mapper.ApiDebugMapper;
|
||||
import io.metersphere.api.service.ApiFileResourceService;
|
||||
import io.metersphere.api.util.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.dto.api.request.http.MsHTTPElement;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.file.FileCenter;
|
||||
import io.metersphere.system.file.FileRequest;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static io.metersphere.api.controller.result.ApiResultCode.API_DEBUG_EXIST;
|
||||
|
@ -45,6 +51,8 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
private ApiDebugMapper apiDebugMapper;
|
||||
@Resource
|
||||
private ApiDebugBlobMapper apiDebugBlobMapper;
|
||||
@Resource
|
||||
private ApiFileResourceService apiFileResourceService;
|
||||
private static ApiDebug addApiDebug;
|
||||
private static ApiDebug anotherAddApiDebug;
|
||||
@Override
|
||||
|
@ -72,33 +80,42 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
|
||||
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request);
|
||||
|
||||
File bodyFile = new File(
|
||||
this.getClass().getClassLoader().getResource("file/file_upload.JPG")
|
||||
.getPath()
|
||||
);
|
||||
request.setFileIds(List.of(IDGenerator.nextStr()));
|
||||
MvcResult mvcResult = this.requestMultipartWithOkAndReturn(DEFAULT_ADD, getDefaultMultiPartParam(List.of(bodyFile), request));
|
||||
// 校验请求成功数据
|
||||
ApiDebug resultData = getResultData(mvcResult, ApiDebug.class);
|
||||
this.addApiDebug = assertUpdateApiDebug(request, msHttpElement, resultData.getId());
|
||||
this.addApiDebug = assertUpdateApiDebug(request, msHttpElement, resultData.getId(), request.getFileIds());
|
||||
|
||||
|
||||
// 再插入一条数据,便于修改时重名校验
|
||||
request.setName("test1");
|
||||
mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request);
|
||||
request.setFileIds(null);
|
||||
mvcResult = this.requestMultipartWithOkAndReturn(DEFAULT_ADD, getDefaultMultiPartParam(List.of(bodyFile), request));
|
||||
resultData = getResultData(mvcResult, ApiDebug.class);
|
||||
this.anotherAddApiDebug = assertUpdateApiDebug(request, msHttpElement, resultData.getId());
|
||||
this.anotherAddApiDebug = assertUpdateApiDebug(request, msHttpElement, resultData.getId(), request.getFileIds());
|
||||
|
||||
// 增加覆盖率
|
||||
apiFileResourceService.uploadFileResource(null, null, null);
|
||||
|
||||
// @@重名校验异常
|
||||
assertErrorCode(this.requestPost(DEFAULT_ADD, request), API_DEBUG_EXIST);
|
||||
assertErrorCode(this.requestMultipart(DEFAULT_ADD, getDefaultMultiPartParam(List.of(), request)), API_DEBUG_EXIST);
|
||||
// 校验项目是否存在
|
||||
request.setProjectId("111");
|
||||
assertErrorCode(this.requestPost(DEFAULT_ADD, request), NOT_FOUND);
|
||||
assertErrorCode(this.requestMultipart(DEFAULT_ADD, getDefaultMultiPartParam(List.of(), request)), NOT_FOUND);
|
||||
|
||||
// @@校验日志
|
||||
checkLog(this.addApiDebug.getId(), OperationLogType.ADD);
|
||||
// @@异常参数校验
|
||||
createdGroupParamValidateTest(ApiDebugAddRequestDefinition.class, DEFAULT_ADD);
|
||||
checkLog(this.addApiDebug.getId(), OperationLogType.ADD);
|
||||
// @@校验权限
|
||||
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_ADD, DEFAULT_ADD, request);
|
||||
requestMultipartPermissionTest(PermissionConstants.PROJECT_API_DEBUG_ADD, DEFAULT_ADD, getDefaultMultiPartParam(List.of(), request));
|
||||
}
|
||||
|
||||
private ApiDebug assertUpdateApiDebug(Object request, MsHTTPElement msHttpElement, String id) {
|
||||
private ApiDebug assertUpdateApiDebug(Object request, MsHTTPElement msHttpElement, String id, List<String> fileIds) throws Exception {
|
||||
ApiDebug apiDebug = apiDebugMapper.selectByPrimaryKey(id);
|
||||
ApiDebugBlob apiDebugBlob = apiDebugBlobMapper.selectByPrimaryKey(id);
|
||||
ApiDebug copyApiDebug = BeanUtils.copyBean(new ApiDebug(), apiDebug);
|
||||
|
@ -106,6 +123,28 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
Assertions.assertEquals(apiDebug, copyApiDebug);
|
||||
ApiDataUtils.setResolver(MsHTTPElement.class);
|
||||
Assertions.assertEquals(msHttpElement, ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class));
|
||||
|
||||
if (fileIds != null) {
|
||||
// 验证文件的关联关系,以及是否存入对象存储
|
||||
List<ApiFileResource> apiFileResources = apiFileResourceService.getByResourceId(id);
|
||||
Assertions.assertEquals(apiFileResources.size(), fileIds.size());
|
||||
|
||||
String apiDebugDir = DefaultRepositoryDir.getApiDebugDir(apiDebug.getProjectId(), id);
|
||||
FileRequest fileRequest = new FileRequest();
|
||||
if (fileIds.size() > 0) {
|
||||
for (ApiFileResource apiFileResource : apiFileResources) {
|
||||
Assertions.assertEquals(apiFileResource.getProjectId(), apiDebug.getProjectId());
|
||||
fileRequest.setFolder(apiDebugDir + "/" + apiFileResource.getFileId());
|
||||
fileRequest.setFileName(apiFileResource.getFileName());
|
||||
Assertions.assertNotNull(FileCenter.getDefaultRepository().getFile(fileRequest));
|
||||
}
|
||||
fileRequest.setFolder(apiDebugDir);
|
||||
} else {
|
||||
fileRequest.setFolder(apiDebugDir);
|
||||
Assertions.assertTrue(CollectionUtils.isEmpty(FileCenter.getDefaultRepository().getFolderFileNames(fileRequest)));
|
||||
}
|
||||
}
|
||||
|
||||
return apiDebug;
|
||||
}
|
||||
|
||||
|
@ -122,20 +161,49 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
|
||||
msHttpElement.setName("test1");
|
||||
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
|
||||
this.requestPostWithOk(DEFAULT_UPDATE, request);
|
||||
|
||||
// 不带文件的更新
|
||||
this.requestMultipartWithOk(DEFAULT_UPDATE, getDefaultMultiPartParam(null, request));
|
||||
// 校验请求成功数据
|
||||
assertUpdateApiDebug(request, msHttpElement, request.getId());
|
||||
assertUpdateApiDebug(request, msHttpElement, request.getId(), request.getFileIds());
|
||||
|
||||
File bodyFile = new File(
|
||||
this.getClass().getClassLoader().getResource("file/file_upload.JPG")
|
||||
.getPath()
|
||||
);
|
||||
|
||||
// 带文件的更新
|
||||
request.setAddFileIds(List.of(IDGenerator.nextStr()));
|
||||
request.setFileIds(request.getAddFileIds());
|
||||
this.requestMultipartWithOk(DEFAULT_UPDATE, getDefaultMultiPartParam(List.of(bodyFile), request));
|
||||
// 校验请求成功数据
|
||||
assertUpdateApiDebug(request, msHttpElement, request.getId(), request.getFileIds());
|
||||
|
||||
// 删除了上一次上传的文件,重新上传一个文件
|
||||
request.setAddFileIds(List.of(IDGenerator.nextStr()));
|
||||
request.setFileIds(request.getAddFileIds());
|
||||
this.requestMultipartWithOk(DEFAULT_UPDATE, getDefaultMultiPartParam(List.of(bodyFile), request));
|
||||
assertUpdateApiDebug(request, msHttpElement, request.getId(), request.getFileIds());
|
||||
|
||||
// 已有一个文件,再上传一个文件
|
||||
request.setAddFileIds(List.of(IDGenerator.nextStr()));
|
||||
List<String> fileIds = apiFileResourceService.getFileIdsByResourceId(request.getId());
|
||||
fileIds.addAll(request.getAddFileIds());
|
||||
request.setFileIds(fileIds);
|
||||
this.requestMultipartWithOk(DEFAULT_UPDATE, getDefaultMultiPartParam(List.of(bodyFile), request));
|
||||
assertUpdateApiDebug(request, msHttpElement, request.getId(), request.getFileIds());
|
||||
|
||||
// 校验请求成功数据
|
||||
assertUpdateApiDebug(request, msHttpElement, request.getId(), request.getFileIds());
|
||||
|
||||
// @@重名校验异常
|
||||
request.setModuleId("default");
|
||||
assertErrorCode(this.requestPost(DEFAULT_UPDATE, request), API_DEBUG_EXIST);
|
||||
assertErrorCode(this.requestMultipart(DEFAULT_UPDATE, getDefaultMultiPartParam(List.of(), request)), API_DEBUG_EXIST);
|
||||
|
||||
// @@校验日志
|
||||
checkLog(request.getId(), OperationLogType.UPDATE);
|
||||
// @@异常参数校验
|
||||
updatedGroupParamValidateTest(ApiDebugUpdateRequestDefinition.class, DEFAULT_UPDATE);
|
||||
// @@校验权限
|
||||
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_UPDATE, DEFAULT_UPDATE, request);
|
||||
requestMultipartPermissionTest(PermissionConstants.PROJECT_API_DEBUG_UPDATE, DEFAULT_UPDATE, getDefaultMultiPartParam(List.of(), request));
|
||||
}
|
||||
@Test
|
||||
@Order(3)
|
||||
|
@ -168,6 +236,7 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
ApiDebugDTO copyApiDebugDTO = BeanUtils.copyBean(new ApiDebugDTO(), apiDebugMapper.selectByPrimaryKey(addApiDebug.getId()));
|
||||
ApiDebugBlob apiDebugBlob = apiDebugBlobMapper.selectByPrimaryKey(addApiDebug.getId());
|
||||
copyApiDebugDTO.setRequest(ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class));
|
||||
copyApiDebugDTO.setFileIds(apiFileResourceService.getFileIdsByResourceId(addApiDebug.getId()));
|
||||
Assertions.assertEquals(apiDebugDTO, copyApiDebugDTO);
|
||||
// @@校验权限
|
||||
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ, DEFAULT_GET, apiDebugDTO.getId());
|
||||
|
@ -181,6 +250,11 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
// 校验请求成功数据
|
||||
Assertions.assertNull(apiDebugMapper.selectByPrimaryKey(addApiDebug.getId()));
|
||||
Assertions.assertNull(apiDebugBlobMapper.selectByPrimaryKey(addApiDebug.getId()));
|
||||
List<ApiFileResource> apiFileResources = apiFileResourceService.getByResourceId(addApiDebug.getId());
|
||||
Assertions.assertTrue(CollectionUtils.isEmpty(apiFileResources));
|
||||
FileRequest fileRequest = new FileRequest();
|
||||
fileRequest.setFolder(DefaultRepositoryDir.getApiDebugDir(addApiDebug.getProjectId(), addApiDebug.getId()));
|
||||
Assertions.assertTrue(CollectionUtils.isEmpty(FileCenter.getDefaultRepository().getFolderFileNames(fileRequest)));
|
||||
// @@校验日志
|
||||
checkLog(addApiDebug.getId(), OperationLogType.DELETE);
|
||||
// @@校验权限
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.springframework.test.web.servlet.ResultActions;
|
|||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
|
@ -56,7 +57,7 @@ import java.util.function.Supplier;
|
|||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@AutoConfigureMockMvc
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public abstract class BaseTest {
|
||||
|
@ -228,18 +229,29 @@ public abstract class BaseTest {
|
|||
List list = value;
|
||||
for (Object o : list) {
|
||||
try {
|
||||
MockMultipartFile multipartFile;
|
||||
if (o instanceof File) {
|
||||
File file = (File) o;
|
||||
multipartFile = new MockMultipartFile(key, file.getName(),
|
||||
MediaType.APPLICATION_OCTET_STREAM_VALUE, Files.readAllBytes(file.toPath()));
|
||||
} else if (o instanceof MockMultipartFile) {
|
||||
multipartFile = (MockMultipartFile) o;
|
||||
} else {
|
||||
multipartFile = new MockMultipartFile(key, null,
|
||||
MediaType.APPLICATION_JSON_VALUE, o.toString().getBytes());
|
||||
if (o == null) {
|
||||
continue;
|
||||
}
|
||||
MockMultipartFile multipartFile;
|
||||
if (o instanceof List) {
|
||||
List listObject = ((List) o);
|
||||
if (CollectionUtils.isEmpty(listObject)) {
|
||||
continue;
|
||||
}
|
||||
if (listObject.get(0) instanceof File || listObject.get(0) instanceof MockMultipartFile) {
|
||||
// 参数是多个文件时,设置多个文件
|
||||
for (Object subObject : ((List) o)) {
|
||||
multipartFile = getMockMultipartFile(key, subObject);
|
||||
requestBuilder.file(multipartFile);
|
||||
}
|
||||
} else {
|
||||
multipartFile = getMockMultipartFile(key, o);
|
||||
requestBuilder.file(multipartFile);
|
||||
}
|
||||
} else {
|
||||
multipartFile = getMockMultipartFile(key, o);
|
||||
requestBuilder.file(multipartFile);
|
||||
}
|
||||
requestBuilder.file(multipartFile);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -249,6 +261,31 @@ public abstract class BaseTest {
|
|||
return requestBuilder;
|
||||
}
|
||||
|
||||
private static MockMultipartFile getMockMultipartFile(String key, Object value) throws IOException {
|
||||
MockMultipartFile multipartFile;
|
||||
if (value instanceof File) {
|
||||
File file = (File) value;
|
||||
multipartFile = new MockMultipartFile(key, file.getName(),
|
||||
MediaType.APPLICATION_OCTET_STREAM_VALUE, Files.readAllBytes(file.toPath()));
|
||||
} else if (value instanceof MockMultipartFile) {
|
||||
multipartFile = (MockMultipartFile) value;
|
||||
// 有些地方的参数 name 写的是文件名,这里统一处理成参数名 key
|
||||
multipartFile = new MockMultipartFile(key, multipartFile.getOriginalFilename(),
|
||||
MediaType.APPLICATION_OCTET_STREAM_VALUE, multipartFile.getBytes());
|
||||
} else {
|
||||
multipartFile = new MockMultipartFile(key, key,
|
||||
MediaType.APPLICATION_JSON_VALUE, value.toString().getBytes());
|
||||
}
|
||||
return multipartFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认的 MultiValue 参数
|
||||
*
|
||||
* @param param
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
protected MultiValueMap<String, Object> getDefaultMultiPartParam(Object param, File file) {
|
||||
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
|
||||
paramMap.add("file", file);
|
||||
|
@ -256,6 +293,23 @@ public abstract class BaseTest {
|
|||
return paramMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认的 MultiValue 参数
|
||||
* 这里参数位置与上面的方法对调
|
||||
* 以便于方法重载时,可以 files 可以传 null
|
||||
* 不会与上面方法混淆
|
||||
*
|
||||
* @param files
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
protected MultiValueMap<String, Object> getDefaultMultiPartParam(List<File> files, Object param) {
|
||||
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
|
||||
paramMap.add("files", files);
|
||||
paramMap.add("request", JSON.toJSONString(param));
|
||||
return paramMap;
|
||||
}
|
||||
|
||||
protected <T> T getResultData(MvcResult mvcResult, Class<T> clazz) throws Exception {
|
||||
Object data = parseResponse(mvcResult).get("data");
|
||||
return JSON.parseObject(JSON.toJSONString(data), clazz);
|
||||
|
|
Loading…
Reference in New Issue