feat(用例管理): 新增停止导出
This commit is contained in:
parent
6c40f93f0c
commit
6b921d4aa3
|
@ -0,0 +1,126 @@
|
||||||
|
package io.metersphere.functional.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 ExportTask implements Serializable {
|
||||||
|
@Schema(description = "任务唯一ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{export_task.id.not_blank}", groups = {Updated.class})
|
||||||
|
@Size(min = 1, max = 50, message = "{export_task.id.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "资源类型", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{export_task.type.not_blank}", groups = {Created.class})
|
||||||
|
@Size(min = 1, max = 50, message = "{export_task.type.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "文件id")
|
||||||
|
private String fileid;
|
||||||
|
|
||||||
|
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{export_task.state.not_blank}", groups = {Created.class})
|
||||||
|
@Size(min = 1, max = 50, message = "{export_task.state.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private String createUser;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Long createTime;
|
||||||
|
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private String updateUser;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Long updateTime;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public enum Column {
|
||||||
|
id("id", "id", "VARCHAR", false),
|
||||||
|
name("name", "name", "VARCHAR", true),
|
||||||
|
type("type", "type", "VARCHAR", true),
|
||||||
|
fileid("fileId", "fileid", "VARCHAR", false),
|
||||||
|
state("state", "state", "VARCHAR", true),
|
||||||
|
createUser("create_user", "createUser", "VARCHAR", false),
|
||||||
|
createTime("create_time", "createTime", "BIGINT", false),
|
||||||
|
updateUser("update_user", "updateUser", "VARCHAR", false),
|
||||||
|
updateTime("update_time", "updateTime", "BIGINT", 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,810 @@
|
||||||
|
package io.metersphere.functional.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ExportTaskExample {
|
||||||
|
protected String orderByClause;
|
||||||
|
|
||||||
|
protected boolean distinct;
|
||||||
|
|
||||||
|
protected List<Criteria> oredCriteria;
|
||||||
|
|
||||||
|
public ExportTaskExample() {
|
||||||
|
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 andIdIsNull() {
|
||||||
|
addCriterion("id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdIsNotNull() {
|
||||||
|
addCriterion("id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdEqualTo(String value) {
|
||||||
|
addCriterion("id =", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotEqualTo(String value) {
|
||||||
|
addCriterion("id <>", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdGreaterThan(String value) {
|
||||||
|
addCriterion("id >", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("id >=", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLessThan(String value) {
|
||||||
|
addCriterion("id <", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("id <=", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLike(String value) {
|
||||||
|
addCriterion("id like", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotLike(String value) {
|
||||||
|
addCriterion("id not like", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdIn(List<String> values) {
|
||||||
|
addCriterion("id in", values, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotIn(List<String> values) {
|
||||||
|
addCriterion("id not in", values, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("id between", value1, value2, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("id not between", value1, value2, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameIsNull() {
|
||||||
|
addCriterion("`name` is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameIsNotNull() {
|
||||||
|
addCriterion("`name` is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameEqualTo(String value) {
|
||||||
|
addCriterion("`name` =", value, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameNotEqualTo(String value) {
|
||||||
|
addCriterion("`name` <>", value, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameGreaterThan(String value) {
|
||||||
|
addCriterion("`name` >", value, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("`name` >=", value, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameLessThan(String value) {
|
||||||
|
addCriterion("`name` <", value, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("`name` <=", value, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameLike(String value) {
|
||||||
|
addCriterion("`name` like", value, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameNotLike(String value) {
|
||||||
|
addCriterion("`name` not like", value, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameIn(List<String> values) {
|
||||||
|
addCriterion("`name` in", values, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameNotIn(List<String> values) {
|
||||||
|
addCriterion("`name` not in", values, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameBetween(String value1, String value2) {
|
||||||
|
addCriterion("`name` between", value1, value2, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andNameNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("`name` not between", value1, value2, "name");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeIsNull() {
|
||||||
|
addCriterion("`type` is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeIsNotNull() {
|
||||||
|
addCriterion("`type` is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeEqualTo(String value) {
|
||||||
|
addCriterion("`type` =", value, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeNotEqualTo(String value) {
|
||||||
|
addCriterion("`type` <>", value, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeGreaterThan(String value) {
|
||||||
|
addCriterion("`type` >", value, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("`type` >=", value, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeLessThan(String value) {
|
||||||
|
addCriterion("`type` <", value, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("`type` <=", value, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeLike(String value) {
|
||||||
|
addCriterion("`type` like", value, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeNotLike(String value) {
|
||||||
|
addCriterion("`type` not like", value, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeIn(List<String> values) {
|
||||||
|
addCriterion("`type` in", values, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeNotIn(List<String> values) {
|
||||||
|
addCriterion("`type` not in", values, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeBetween(String value1, String value2) {
|
||||||
|
addCriterion("`type` between", value1, value2, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTypeNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("`type` not between", value1, value2, "type");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidIsNull() {
|
||||||
|
addCriterion("fileId is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidIsNotNull() {
|
||||||
|
addCriterion("fileId is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidEqualTo(String value) {
|
||||||
|
addCriterion("fileId =", value, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidNotEqualTo(String value) {
|
||||||
|
addCriterion("fileId <>", value, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidGreaterThan(String value) {
|
||||||
|
addCriterion("fileId >", value, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("fileId >=", value, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidLessThan(String value) {
|
||||||
|
addCriterion("fileId <", value, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("fileId <=", value, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidLike(String value) {
|
||||||
|
addCriterion("fileId like", value, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidNotLike(String value) {
|
||||||
|
addCriterion("fileId not like", value, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidIn(List<String> values) {
|
||||||
|
addCriterion("fileId in", values, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidNotIn(List<String> values) {
|
||||||
|
addCriterion("fileId not in", values, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidBetween(String value1, String value2) {
|
||||||
|
addCriterion("fileId between", value1, value2, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andFileidNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("fileId not between", value1, value2, "fileid");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateIsNull() {
|
||||||
|
addCriterion("`state` is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateIsNotNull() {
|
||||||
|
addCriterion("`state` is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateEqualTo(String value) {
|
||||||
|
addCriterion("`state` =", value, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateNotEqualTo(String value) {
|
||||||
|
addCriterion("`state` <>", value, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateGreaterThan(String value) {
|
||||||
|
addCriterion("`state` >", value, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("`state` >=", value, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateLessThan(String value) {
|
||||||
|
addCriterion("`state` <", value, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("`state` <=", value, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateLike(String value) {
|
||||||
|
addCriterion("`state` like", value, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateNotLike(String value) {
|
||||||
|
addCriterion("`state` not like", value, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateIn(List<String> values) {
|
||||||
|
addCriterion("`state` in", values, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateNotIn(List<String> values) {
|
||||||
|
addCriterion("`state` not in", values, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateBetween(String value1, String value2) {
|
||||||
|
addCriterion("`state` between", value1, value2, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStateNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("`state` not between", value1, value2, "state");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserIsNull() {
|
||||||
|
addCriterion("create_user is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserIsNotNull() {
|
||||||
|
addCriterion("create_user is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserEqualTo(String value) {
|
||||||
|
addCriterion("create_user =", value, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserNotEqualTo(String value) {
|
||||||
|
addCriterion("create_user <>", value, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserGreaterThan(String value) {
|
||||||
|
addCriterion("create_user >", value, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("create_user >=", value, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserLessThan(String value) {
|
||||||
|
addCriterion("create_user <", value, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("create_user <=", value, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserLike(String value) {
|
||||||
|
addCriterion("create_user like", value, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserNotLike(String value) {
|
||||||
|
addCriterion("create_user not like", value, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserIn(List<String> values) {
|
||||||
|
addCriterion("create_user in", values, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserNotIn(List<String> values) {
|
||||||
|
addCriterion("create_user not in", values, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserBetween(String value1, String value2) {
|
||||||
|
addCriterion("create_user between", value1, value2, "createUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateUserNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("create_user not between", value1, value2, "createUser");
|
||||||
|
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 andUpdateUserIsNull() {
|
||||||
|
addCriterion("update_user is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserIsNotNull() {
|
||||||
|
addCriterion("update_user is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserEqualTo(String value) {
|
||||||
|
addCriterion("update_user =", value, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserNotEqualTo(String value) {
|
||||||
|
addCriterion("update_user <>", value, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserGreaterThan(String value) {
|
||||||
|
addCriterion("update_user >", value, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("update_user >=", value, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserLessThan(String value) {
|
||||||
|
addCriterion("update_user <", value, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("update_user <=", value, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserLike(String value) {
|
||||||
|
addCriterion("update_user like", value, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserNotLike(String value) {
|
||||||
|
addCriterion("update_user not like", value, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserIn(List<String> values) {
|
||||||
|
addCriterion("update_user in", values, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserNotIn(List<String> values) {
|
||||||
|
addCriterion("update_user not in", values, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserBetween(String value1, String value2) {
|
||||||
|
addCriterion("update_user between", value1, value2, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateUserNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("update_user not between", value1, value2, "updateUser");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeIsNull() {
|
||||||
|
addCriterion("update_time is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeIsNotNull() {
|
||||||
|
addCriterion("update_time is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeEqualTo(Long value) {
|
||||||
|
addCriterion("update_time =", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeNotEqualTo(Long value) {
|
||||||
|
addCriterion("update_time <>", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeGreaterThan(Long value) {
|
||||||
|
addCriterion("update_time >", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeGreaterThanOrEqualTo(Long value) {
|
||||||
|
addCriterion("update_time >=", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeLessThan(Long value) {
|
||||||
|
addCriterion("update_time <", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeLessThanOrEqualTo(Long value) {
|
||||||
|
addCriterion("update_time <=", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeIn(List<Long> values) {
|
||||||
|
addCriterion("update_time in", values, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeNotIn(List<Long> values) {
|
||||||
|
addCriterion("update_time not in", values, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeBetween(Long value1, Long value2) {
|
||||||
|
addCriterion("update_time between", value1, value2, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeNotBetween(Long value1, Long value2) {
|
||||||
|
addCriterion("update_time not between", value1, value2, "updateTime");
|
||||||
|
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.functional.mapper;
|
||||||
|
|
||||||
|
import io.metersphere.functional.domain.ExportTask;
|
||||||
|
import io.metersphere.functional.domain.ExportTaskExample;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
public interface ExportTaskMapper {
|
||||||
|
long countByExample(ExportTaskExample example);
|
||||||
|
|
||||||
|
int deleteByExample(ExportTaskExample example);
|
||||||
|
|
||||||
|
int deleteByPrimaryKey(String id);
|
||||||
|
|
||||||
|
int insert(ExportTask record);
|
||||||
|
|
||||||
|
int insertSelective(ExportTask record);
|
||||||
|
|
||||||
|
List<ExportTask> selectByExample(ExportTaskExample example);
|
||||||
|
|
||||||
|
ExportTask selectByPrimaryKey(String id);
|
||||||
|
|
||||||
|
int updateByExampleSelective(@Param("record") ExportTask record, @Param("example") ExportTaskExample example);
|
||||||
|
|
||||||
|
int updateByExample(@Param("record") ExportTask record, @Param("example") ExportTaskExample example);
|
||||||
|
|
||||||
|
int updateByPrimaryKeySelective(ExportTask record);
|
||||||
|
|
||||||
|
int updateByPrimaryKey(ExportTask record);
|
||||||
|
|
||||||
|
int batchInsert(@Param("list") List<ExportTask> list);
|
||||||
|
|
||||||
|
int batchInsertSelective(@Param("list") List<ExportTask> list, @Param("selective") ExportTask.Column ... selective);
|
||||||
|
}
|
|
@ -0,0 +1,328 @@
|
||||||
|
<?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.functional.mapper.ExportTaskMapper">
|
||||||
|
<resultMap id="BaseResultMap" type="io.metersphere.functional.domain.ExportTask">
|
||||||
|
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||||
|
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||||
|
<result column="type" jdbcType="VARCHAR" property="type" />
|
||||||
|
<result column="fileId" jdbcType="VARCHAR" property="fileid" />
|
||||||
|
<result column="state" jdbcType="VARCHAR" property="state" />
|
||||||
|
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
|
||||||
|
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||||
|
<result column="update_user" jdbcType="VARCHAR" property="updateUser" />
|
||||||
|
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||||
|
</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">
|
||||||
|
id, `name`, `type`, fileId, `state`, create_user, create_time, update_user, update_time
|
||||||
|
</sql>
|
||||||
|
<select id="selectByExample" parameterType="io.metersphere.functional.domain.ExportTaskExample" resultMap="BaseResultMap">
|
||||||
|
select
|
||||||
|
<if test="distinct">
|
||||||
|
distinct
|
||||||
|
</if>
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
from export_task
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
<if test="orderByClause != null">
|
||||||
|
order by ${orderByClause}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
|
||||||
|
select
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
from export_task
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</select>
|
||||||
|
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
|
||||||
|
delete from export_task
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</delete>
|
||||||
|
<delete id="deleteByExample" parameterType="io.metersphere.functional.domain.ExportTaskExample">
|
||||||
|
delete from export_task
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</delete>
|
||||||
|
<insert id="insert" parameterType="io.metersphere.functional.domain.ExportTask">
|
||||||
|
insert into export_task (id, `name`, `type`,
|
||||||
|
fileId, `state`, create_user,
|
||||||
|
create_time, update_user, update_time
|
||||||
|
)
|
||||||
|
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
|
||||||
|
#{fileid,jdbcType=VARCHAR}, #{state,jdbcType=VARCHAR}, #{createUser,jdbcType=VARCHAR},
|
||||||
|
#{createTime,jdbcType=BIGINT}, #{updateUser,jdbcType=VARCHAR}, #{updateTime,jdbcType=BIGINT}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
<insert id="insertSelective" parameterType="io.metersphere.functional.domain.ExportTask">
|
||||||
|
insert into export_task
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">
|
||||||
|
id,
|
||||||
|
</if>
|
||||||
|
<if test="name != null">
|
||||||
|
`name`,
|
||||||
|
</if>
|
||||||
|
<if test="type != null">
|
||||||
|
`type`,
|
||||||
|
</if>
|
||||||
|
<if test="fileid != null">
|
||||||
|
fileId,
|
||||||
|
</if>
|
||||||
|
<if test="state != null">
|
||||||
|
`state`,
|
||||||
|
</if>
|
||||||
|
<if test="createUser != null">
|
||||||
|
create_user,
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
create_time,
|
||||||
|
</if>
|
||||||
|
<if test="updateUser != null">
|
||||||
|
update_user,
|
||||||
|
</if>
|
||||||
|
<if test="updateTime != null">
|
||||||
|
update_time,
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">
|
||||||
|
#{id,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="name != null">
|
||||||
|
#{name,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="type != null">
|
||||||
|
#{type,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="fileid != null">
|
||||||
|
#{fileid,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="state != null">
|
||||||
|
#{state,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="createUser != null">
|
||||||
|
#{createUser,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
#{createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="updateUser != null">
|
||||||
|
#{updateUser,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="updateTime != null">
|
||||||
|
#{updateTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
<select id="countByExample" parameterType="io.metersphere.functional.domain.ExportTaskExample" resultType="java.lang.Long">
|
||||||
|
select count(*) from export_task
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
<update id="updateByExampleSelective" parameterType="map">
|
||||||
|
update export_task
|
||||||
|
<set>
|
||||||
|
<if test="record.id != null">
|
||||||
|
id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.name != null">
|
||||||
|
`name` = #{record.name,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.type != null">
|
||||||
|
`type` = #{record.type,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.fileid != null">
|
||||||
|
fileId = #{record.fileid,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.state != null">
|
||||||
|
`state` = #{record.state,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.createUser != null">
|
||||||
|
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.createTime != null">
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="record.updateUser != null">
|
||||||
|
update_user = #{record.updateUser,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.updateTime != null">
|
||||||
|
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
<update id="updateByExample" parameterType="map">
|
||||||
|
update export_task
|
||||||
|
set id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
`name` = #{record.name,jdbcType=VARCHAR},
|
||||||
|
`type` = #{record.type,jdbcType=VARCHAR},
|
||||||
|
fileId = #{record.fileid,jdbcType=VARCHAR},
|
||||||
|
`state` = #{record.state,jdbcType=VARCHAR},
|
||||||
|
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
update_user = #{record.updateUser,jdbcType=VARCHAR},
|
||||||
|
update_time = #{record.updateTime,jdbcType=BIGINT}
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.functional.domain.ExportTask">
|
||||||
|
update export_task
|
||||||
|
<set>
|
||||||
|
<if test="name != null">
|
||||||
|
`name` = #{name,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="type != null">
|
||||||
|
`type` = #{type,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="fileid != null">
|
||||||
|
fileId = #{fileid,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="state != null">
|
||||||
|
`state` = #{state,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="createUser != null">
|
||||||
|
create_user = #{createUser,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="updateUser != null">
|
||||||
|
update_user = #{updateUser,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="updateTime != null">
|
||||||
|
update_time = #{updateTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKey" parameterType="io.metersphere.functional.domain.ExportTask">
|
||||||
|
update export_task
|
||||||
|
set `name` = #{name,jdbcType=VARCHAR},
|
||||||
|
`type` = #{type,jdbcType=VARCHAR},
|
||||||
|
fileId = #{fileid,jdbcType=VARCHAR},
|
||||||
|
`state` = #{state,jdbcType=VARCHAR},
|
||||||
|
create_user = #{createUser,jdbcType=VARCHAR},
|
||||||
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
|
update_user = #{updateUser,jdbcType=VARCHAR},
|
||||||
|
update_time = #{updateTime,jdbcType=BIGINT}
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</update>
|
||||||
|
<insert id="batchInsert" parameterType="map">
|
||||||
|
insert into export_task
|
||||||
|
(id, `name`, `type`, fileId, `state`, create_user, create_time, update_user, update_time
|
||||||
|
)
|
||||||
|
values
|
||||||
|
<foreach collection="list" item="item" separator=",">
|
||||||
|
(#{item.id,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, #{item.type,jdbcType=VARCHAR},
|
||||||
|
#{item.fileid,jdbcType=VARCHAR}, #{item.state,jdbcType=VARCHAR}, #{item.createUser,jdbcType=VARCHAR},
|
||||||
|
#{item.createTime,jdbcType=BIGINT}, #{item.updateUser,jdbcType=VARCHAR}, #{item.updateTime,jdbcType=BIGINT}
|
||||||
|
)
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
<insert id="batchInsertSelective" parameterType="map">
|
||||||
|
insert into export_task (
|
||||||
|
<foreach collection="selective" item="column" separator=",">
|
||||||
|
${column.escapedColumnName}
|
||||||
|
</foreach>
|
||||||
|
)
|
||||||
|
values
|
||||||
|
<foreach collection="list" item="item" separator=",">
|
||||||
|
(
|
||||||
|
<foreach collection="selective" item="column" separator=",">
|
||||||
|
<if test="'id'.toString() == column.value">
|
||||||
|
#{item.id,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="'name'.toString() == column.value">
|
||||||
|
#{item.name,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="'type'.toString() == column.value">
|
||||||
|
#{item.type,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="'fileId'.toString() == column.value">
|
||||||
|
#{item.fileid,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="'state'.toString() == column.value">
|
||||||
|
#{item.state,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="'create_user'.toString() == column.value">
|
||||||
|
#{item.createUser,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="'create_time'.toString() == column.value">
|
||||||
|
#{item.createTime,jdbcType=BIGINT}
|
||||||
|
</if>
|
||||||
|
<if test="'update_user'.toString() == column.value">
|
||||||
|
#{item.updateUser,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="'update_time'.toString() == column.value">
|
||||||
|
#{item.updateTime,jdbcType=BIGINT}
|
||||||
|
</if>
|
||||||
|
</foreach>
|
||||||
|
)
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
</mapper>
|
|
@ -7,6 +7,29 @@ ALTER TABLE api_test_case ADD ignore_api_diff BIT(1) DEFAULT 0 NOT NULL COMMENT
|
||||||
ALTER TABLE test_plan_report_bug MODIFY bug_handle_user VARCHAR(255) NULL COMMENT '缺陷处理人';
|
ALTER TABLE test_plan_report_bug MODIFY bug_handle_user VARCHAR(255) NULL COMMENT '缺陷处理人';
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE export_task(
|
||||||
|
`id` VARCHAR(50) NOT NULL COMMENT '任务唯一ID' ,
|
||||||
|
`name` VARCHAR(255) COMMENT '名称' ,
|
||||||
|
`type` VARCHAR(50) NOT NULL COMMENT '资源类型' ,
|
||||||
|
`fileId` VARCHAR(255) COMMENT '文件id' ,
|
||||||
|
`state` VARCHAR(50) NOT NULL COMMENT '状态' ,
|
||||||
|
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
|
||||||
|
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
|
||||||
|
`update_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
|
||||||
|
`update_time` BIGINT NOT NULL COMMENT '创建时间' ,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
) ENGINE = InnoDB
|
||||||
|
DEFAULT CHARSET = utf8mb4
|
||||||
|
COLLATE = utf8mb4_general_ci COMMENT = '导出任务';
|
||||||
|
|
||||||
|
|
||||||
|
CREATE INDEX idx_create_user ON export_task(`create_user`);
|
||||||
|
CREATE INDEX idx_state ON export_task(`state`);
|
||||||
|
CREATE INDEX idx_create_time ON export_task(`create_time`);
|
||||||
|
CREATE INDEX idx_type ON export_task(`type`);
|
||||||
|
CREATE INDEX idx_update_user ON export_task(`update_user`);
|
||||||
|
CREATE INDEX idx_update_time ON export_task(`update_time`);
|
||||||
|
|
||||||
-- set innodb lock wait timeout to default
|
-- set innodb lock wait timeout to default
|
||||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.sdk.constants;
|
||||||
|
|
||||||
public class KafkaTopicConstants {
|
public class KafkaTopicConstants {
|
||||||
public static final String PLUGIN = "PLUGIN";
|
public static final String PLUGIN = "PLUGIN";
|
||||||
|
public static final String EXPORT = "EXPORT";
|
||||||
// API TOPIC
|
// API TOPIC
|
||||||
public static final String API_REPORT_TOPIC = "API_REPORT_TOPIC";
|
public static final String API_REPORT_TOPIC = "API_REPORT_TOPIC";
|
||||||
public static final String API_REPORT_TASK_TOPIC = "API_REPORT_TASK_TOPIC";
|
public static final String API_REPORT_TASK_TOPIC = "API_REPORT_TASK_TOPIC";
|
||||||
|
|
|
@ -3,8 +3,13 @@ package io.metersphere.sdk.util;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MsFileUtils {
|
public class MsFileUtils {
|
||||||
public static void validateFileName(String... fileNames) {
|
public static void validateFileName(String... fileNames) {
|
||||||
|
@ -21,4 +26,38 @@ public class MsFileUtils {
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
FileUtils.deleteDirectory(file);
|
FileUtils.deleteDirectory(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取流文件
|
||||||
|
*/
|
||||||
|
private static void inputStreamToFile(InputStream ins, File file) {
|
||||||
|
try (OutputStream os = new FileOutputStream(file);) {
|
||||||
|
int bytesRead = 0;
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
|
||||||
|
os.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MultipartFile 转 File
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
= */
|
||||||
|
public static File multipartFileToFile(MultipartFile file) {
|
||||||
|
if (file != null && file.getSize() > 0) {
|
||||||
|
try (InputStream ins = file.getInputStream()) {
|
||||||
|
validateFileName(file.getOriginalFilename());
|
||||||
|
File toFile = new File(Objects.requireNonNull(file.getOriginalFilename()));
|
||||||
|
inputStreamToFile(ins, toFile);
|
||||||
|
return toFile;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
package io.metersphere.sdk.util;
|
package io.metersphere.sdk.util;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.StreamReadConstraints;
|
||||||
|
import com.fasterxml.jackson.core.json.JsonReadFeature;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dom4j.Document;
|
import org.dom4j.*;
|
||||||
import org.dom4j.DocumentException;
|
|
||||||
import org.dom4j.Element;
|
|
||||||
import org.dom4j.Node;
|
|
||||||
import org.dom4j.io.OutputFormat;
|
import org.dom4j.io.OutputFormat;
|
||||||
import org.dom4j.io.SAXReader;
|
import org.dom4j.io.SAXReader;
|
||||||
import org.dom4j.io.XMLWriter;
|
import org.dom4j.io.XMLWriter;
|
||||||
|
@ -22,6 +31,29 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class XMLUtils {
|
public class XMLUtils {
|
||||||
|
private static final ObjectMapper objectMapper = JsonMapper.builder()
|
||||||
|
.enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
|
||||||
|
.build();
|
||||||
|
public static final int DEFAULT_MAX_STRING_LEN = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
// 自动检测所有类的全部属性
|
||||||
|
objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
|
||||||
|
// 如果一个对象中没有任何的属性,那么在序列化的时候就会报错
|
||||||
|
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
|
||||||
|
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
|
||||||
|
// 使用BigDecimal来序列化
|
||||||
|
objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
|
||||||
|
// 设置JSON处理字符长度限制
|
||||||
|
objectMapper.getFactory()
|
||||||
|
.setStreamReadConstraints(StreamReadConstraints.builder().maxStringLength(DEFAULT_MAX_STRING_LEN).build());
|
||||||
|
// 处理时间格式
|
||||||
|
objectMapper.registerModule(new JavaTimeModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final boolean IS_TRANS = false;
|
public static final boolean IS_TRANS = false;
|
||||||
|
|
||||||
public static Document getDocument(InputStream source) throws DocumentException {
|
public static Document getDocument(InputStream source) throws DocumentException {
|
||||||
|
@ -173,4 +205,91 @@ public class XMLUtils {
|
||||||
matcher.appendTail(result);
|
matcher.appendTail(result);
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String delXmlHeader(String xml) {
|
||||||
|
int begin = xml.indexOf("?>");
|
||||||
|
if (begin != -1) {
|
||||||
|
if (begin + 2 >= xml.length()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
xml = xml.substring(begin + 2);
|
||||||
|
} // <?xml version="1.0" encoding="utf-8"?> 若存在,则去除
|
||||||
|
String rgex = ">";
|
||||||
|
Pattern pattern = Pattern.compile(rgex);
|
||||||
|
Matcher m = pattern.matcher(xml);
|
||||||
|
xml = m.replaceAll("> ");
|
||||||
|
rgex = "\\s*</";
|
||||||
|
pattern = Pattern.compile(rgex);
|
||||||
|
m = pattern.matcher(xml);
|
||||||
|
xml = m.replaceAll(" </");
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 传入完整的 xml 文本,转换成 json 对象
|
||||||
|
public static JsonNode xmlConvertJson(String xml) {
|
||||||
|
if (StringUtils.isBlank(xml)) return null;
|
||||||
|
xml = delXmlHeader(xml);
|
||||||
|
if (xml == null) return null;
|
||||||
|
try {
|
||||||
|
if (stringToDocument(xml) == null) {
|
||||||
|
LogUtils.error("xml内容转换失败!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
Element node = null;
|
||||||
|
try {
|
||||||
|
node = stringToDocument(xml).getRootElement();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return getJsonObjectByDC(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonNode getJsonObjectByDC(Element node) {
|
||||||
|
ObjectNode result = objectMapper.createObjectNode();;
|
||||||
|
List<Element> listElement = node.elements();// 所有一级子节点的list
|
||||||
|
if (!listElement.isEmpty()) {
|
||||||
|
List<JsonNode> list = new LinkedList<>();
|
||||||
|
for (Element e : listElement) {// 遍历所有一级子节点
|
||||||
|
JsonNode jsonObject = getJsonObjectByDC(e);
|
||||||
|
//加xml标签上的属性 eg: <field length="2" scale="0" type="string">RB</field>
|
||||||
|
//这里添加 length scale type
|
||||||
|
if (!e.attributes().isEmpty()) {
|
||||||
|
ObjectNode attributeJson = objectMapper.createObjectNode();;
|
||||||
|
for (Attribute attribute : e.attributes()) {
|
||||||
|
try {
|
||||||
|
attributeJson.putIfAbsent(attribute.getName(), objectMapper.readTree(attribute.getValue()));
|
||||||
|
} catch (JsonProcessingException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ObjectNode jsonObjectNode = (ObjectNode) jsonObject;
|
||||||
|
jsonObjectNode.putIfAbsent("attribute", attributeJson);
|
||||||
|
}
|
||||||
|
list.add(jsonObject);
|
||||||
|
}
|
||||||
|
if (list.size() == 1) {
|
||||||
|
result.putIfAbsent(node.getName(), list.get(0));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
String s = objectMapper.writeValueAsString(list);
|
||||||
|
result.putIfAbsent(node.getName(), objectMapper.readTree(s));
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!StringUtils.isAllBlank(node.getName(), node.getText())) {
|
||||||
|
try {
|
||||||
|
result.putIfAbsent(node.getName(), objectMapper.readTree(node.getText()));
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,5 +173,9 @@ case.minder.all.case=全部用例
|
||||||
case.minder.status.success=成功
|
case.minder.status.success=成功
|
||||||
case.minder.status.error=失败
|
case.minder.status.error=失败
|
||||||
case.minder.status.blocked=阻塞
|
case.minder.status.blocked=阻塞
|
||||||
|
#import
|
||||||
|
case.find_file_error=找不到该文件
|
||||||
|
|
||||||
|
export_case_task_stop=停止导出
|
||||||
|
export_case_task_existed=已有导出任务
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,9 @@ case.execute.status.pending=Pending
|
||||||
functional_case_comment_template=【评论:%s(%s)】\n%s\n
|
functional_case_comment_template=【评论:%s(%s)】\n%s\n
|
||||||
functional_case_execute_comment_template=[Execute comment:%s %s(%s)]\n%s\n
|
functional_case_execute_comment_template=[Execute comment:%s %s(%s)]\n%s\n
|
||||||
functional_case_review_comment_template=[Review comment:%s %s(%s)]\n%s\n
|
functional_case_review_comment_template=[Review comment:%s %s(%s)]\n%s\n
|
||||||
|
|
||||||
|
#import
|
||||||
|
case.find_file_error=The file cannot be found
|
||||||
functional_case_xmind_template=Functional case xmind template
|
functional_case_xmind_template=Functional case xmind template
|
||||||
download_template_failed=Download template failed
|
download_template_failed=Download template failed
|
||||||
functional_case=Functional case
|
functional_case=Functional case
|
||||||
|
@ -279,3 +282,6 @@ case.export.system.other.columns.create_user=Create user
|
||||||
case.export.system.other.columns.create_time=Create time
|
case.export.system.other.columns.create_time=Create time
|
||||||
case.export.system.other.columns.update_user=Update user
|
case.export.system.other.columns.update_user=Update user
|
||||||
case.export.system.other.columns.update_time=Update time
|
case.export.system.other.columns.update_time=Update time
|
||||||
|
|
||||||
|
export_case_task_stop=Stop export
|
||||||
|
export_case_task_existed=Export task already exists
|
|
@ -255,6 +255,8 @@ case.execute.status.pending=未执行
|
||||||
functional_case_comment_template=【评论:%s(%s)】\n%s\n
|
functional_case_comment_template=【评论:%s(%s)】\n%s\n
|
||||||
functional_case_execute_comment_template=【执行评论:%s %s(%s)】\n%s\n
|
functional_case_execute_comment_template=【执行评论:%s %s(%s)】\n%s\n
|
||||||
functional_case_review_comment_template=【评审评论:%s %s(%s)】\n%s\n
|
functional_case_review_comment_template=【评审评论:%s %s(%s)】\n%s\n
|
||||||
|
#import
|
||||||
|
case.find_file_error=找不到该文件
|
||||||
functional_case_xmind_template=思维导图用例模版
|
functional_case_xmind_template=思维导图用例模版
|
||||||
download_template_failed=下载思维导图模版失败
|
download_template_failed=下载思维导图模版失败
|
||||||
functional_case=功能用例
|
functional_case=功能用例
|
||||||
|
@ -277,3 +279,6 @@ case.export.system.other.columns.create_user=创建人
|
||||||
case.export.system.other.columns.create_time=创建时间
|
case.export.system.other.columns.create_time=创建时间
|
||||||
case.export.system.other.columns.update_user=更新人
|
case.export.system.other.columns.update_user=更新人
|
||||||
case.export.system.other.columns.update_time=更新时间
|
case.export.system.other.columns.update_time=更新时间
|
||||||
|
|
||||||
|
export_case_task_stop=停止导出
|
||||||
|
export_case_task_existed=已有导出任务
|
|
@ -266,6 +266,11 @@ xmind_textDescription=文本描述
|
||||||
xmind_expectedResult=預期結果
|
xmind_expectedResult=預期結果
|
||||||
xmind_step=用例步驟
|
xmind_step=用例步驟
|
||||||
xmind_stepDescription=步驟描述
|
xmind_stepDescription=步驟描述
|
||||||
|
|
||||||
|
#import
|
||||||
|
case.find_file_error=找不到該文件
|
||||||
|
|
||||||
|
|
||||||
# case export columns
|
# case export columns
|
||||||
case.export.system.columns.name=用例名稱
|
case.export.system.columns.name=用例名稱
|
||||||
case.export.system.columns.id=ID
|
case.export.system.columns.id=ID
|
||||||
|
@ -278,3 +283,6 @@ case.export.system.other.columns.create_user=創建人
|
||||||
case.export.system.other.columns.create_time=創建時間
|
case.export.system.other.columns.create_time=創建時間
|
||||||
case.export.system.other.columns.update_user=更新人
|
case.export.system.other.columns.update_user=更新人
|
||||||
case.export.system.other.columns.update_time=更新時間
|
case.export.system.other.columns.update_time=更新時間
|
||||||
|
|
||||||
|
export_case_task_stop=停止導出
|
||||||
|
export_case_task_existed=已有導出任務
|
|
@ -255,7 +255,15 @@ public class FunctionalCaseController {
|
||||||
@Operation(summary = "用例管理-功能用例-excel导出")
|
@Operation(summary = "用例管理-功能用例-excel导出")
|
||||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_EXPORT)
|
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_EXPORT)
|
||||||
public void testCaseExport(@Validated @RequestBody FunctionalCaseExportRequest request) {
|
public void testCaseExport(@Validated @RequestBody FunctionalCaseExportRequest request) {
|
||||||
functionalCaseFileService.exportFunctionalCaseZip(request);
|
functionalCaseFileService.export(SessionUtils.getUserId(), request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/stop/{projectId}")
|
||||||
|
@Operation(summary = "用例管理-功能用例-导出-停止导出")
|
||||||
|
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_EXPORT)
|
||||||
|
@CheckOwner(resourceId = "#projectId", resourceType = "project")
|
||||||
|
public void caseStopExport(@PathVariable String projectId) {
|
||||||
|
functionalCaseFileService.stopExport(projectId, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/download/xmind/template/{projectId}")
|
@GetMapping("/download/xmind/template/{projectId}")
|
||||||
|
|
|
@ -22,6 +22,7 @@ import io.metersphere.functional.excel.listener.FunctionalCaseImportEventListene
|
||||||
import io.metersphere.functional.excel.listener.FunctionalCasePretreatmentListener;
|
import io.metersphere.functional.excel.listener.FunctionalCasePretreatmentListener;
|
||||||
import io.metersphere.functional.excel.validate.AbstractCustomFieldValidator;
|
import io.metersphere.functional.excel.validate.AbstractCustomFieldValidator;
|
||||||
import io.metersphere.functional.excel.validate.CustomFieldValidatorFactory;
|
import io.metersphere.functional.excel.validate.CustomFieldValidatorFactory;
|
||||||
|
import io.metersphere.functional.mapper.ExportTaskMapper;
|
||||||
import io.metersphere.functional.mapper.ExtFunctionalCaseCommentMapper;
|
import io.metersphere.functional.mapper.ExtFunctionalCaseCommentMapper;
|
||||||
import io.metersphere.functional.request.FunctionalCaseExportRequest;
|
import io.metersphere.functional.request.FunctionalCaseExportRequest;
|
||||||
import io.metersphere.functional.request.FunctionalCaseImportRequest;
|
import io.metersphere.functional.request.FunctionalCaseImportRequest;
|
||||||
|
@ -36,6 +37,7 @@ import io.metersphere.sdk.dto.SocketMsgDTO;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.file.FileRequest;
|
import io.metersphere.sdk.file.FileRequest;
|
||||||
import io.metersphere.sdk.util.*;
|
import io.metersphere.sdk.util.*;
|
||||||
|
import io.metersphere.system.constants.ExportConstants;
|
||||||
import io.metersphere.system.domain.CustomFieldOption;
|
import io.metersphere.system.domain.CustomFieldOption;
|
||||||
import io.metersphere.system.domain.SystemParameter;
|
import io.metersphere.system.domain.SystemParameter;
|
||||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||||
|
@ -43,6 +45,7 @@ import io.metersphere.system.dto.sdk.SessionUser;
|
||||||
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
|
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
|
||||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||||
import io.metersphere.system.excel.utils.EasyExcelExporter;
|
import io.metersphere.system.excel.utils.EasyExcelExporter;
|
||||||
|
import io.metersphere.system.manager.ExportTaskManager;
|
||||||
import io.metersphere.system.mapper.SystemParameterMapper;
|
import io.metersphere.system.mapper.SystemParameterMapper;
|
||||||
import io.metersphere.system.service.FileService;
|
import io.metersphere.system.service.FileService;
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
|
@ -57,7 +60,6 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
@ -103,6 +105,10 @@ public class FunctionalCaseFileService {
|
||||||
@Resource
|
@Resource
|
||||||
private SystemParameterMapper systemParameterMapper;
|
private SystemParameterMapper systemParameterMapper;
|
||||||
private static final String EXPORT_FILE_NAME = "case_export";
|
private static final String EXPORT_FILE_NAME = "case_export";
|
||||||
|
@Resource
|
||||||
|
private ExportTaskManager exportTaskManager;
|
||||||
|
@Resource
|
||||||
|
private ExportTaskMapper exportTaskMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载excel导入模板
|
* 下载excel导入模板
|
||||||
|
@ -327,15 +333,28 @@ public class FunctionalCaseFileService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void export(String userId, FunctionalCaseExportRequest request){
|
||||||
|
try {
|
||||||
|
ExportTaskExample exportTaskExample = new ExportTaskExample();
|
||||||
|
exportTaskExample.createCriteria().andTypeEqualTo(ExportConstants.ExportType.CASE.toString()).andStateEqualTo(ExportConstants.ExportState.PREPARED.toString());
|
||||||
|
long preparedCount = exportTaskMapper.countByExample(exportTaskExample);
|
||||||
|
if (preparedCount>0) {
|
||||||
|
throw new MSException(Translator.get("export_case_task_existed"));
|
||||||
|
}
|
||||||
|
exportTaskManager.exportAsyncTask(userId, ExportConstants.ExportType.CASE.toString(), request, t->exportFunctionalCaseZip(request));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LogUtils.error("导出失败:"+e);
|
||||||
|
throw new MSException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出excel
|
* 导出excel
|
||||||
*
|
*
|
||||||
* @param request
|
* @param request
|
||||||
* @param url
|
|
||||||
*/
|
*/
|
||||||
@Async
|
public String exportFunctionalCaseZip(FunctionalCaseExportRequest request) {
|
||||||
public void exportFunctionalCaseZip(FunctionalCaseExportRequest request) {
|
|
||||||
File tmpDir = null;
|
File tmpDir = null;
|
||||||
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
|
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
|
||||||
try {
|
try {
|
||||||
|
@ -356,14 +375,39 @@ public class FunctionalCaseFileService {
|
||||||
uploadFileToMinio(singeFile, request.getFileId());
|
uploadFileToMinio(singeFile, request.getFileId());
|
||||||
}
|
}
|
||||||
functionalCaseLogService.exportExcelLog(request);
|
functionalCaseLogService.exportExcelLog(request);
|
||||||
SocketMsgDTO socketMsgDTO = new SocketMsgDTO(request.getFileId(), "", MsgType.CONNECT.name(), MsgType.CONNECT.name());
|
List<ExportTask> exportTasks = getExportTasks();
|
||||||
|
String taskId;
|
||||||
|
if (CollectionUtils.isNotEmpty(exportTasks)) {
|
||||||
|
taskId = exportTasks.getFirst().getId();
|
||||||
|
updateExportTask(ExportConstants.ExportState.SUCCESS.toString(), taskId);
|
||||||
|
} else {
|
||||||
|
taskId = MsgType.CONNECT.name();
|
||||||
|
}
|
||||||
|
SocketMsgDTO socketMsgDTO = new SocketMsgDTO(request.getFileId(), "", MsgType.CONNECT.name(), taskId);
|
||||||
socketMsgDTO.setReportId(request.getFileId());
|
socketMsgDTO.setReportId(request.getFileId());
|
||||||
ExportWebSocketHandler.sendMessageSingle(socketMsgDTO);
|
ExportWebSocketHandler.sendMessageSingle(socketMsgDTO);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
List<ExportTask> exportTasks = getExportTasks();
|
||||||
|
if (CollectionUtils.isNotEmpty(exportTasks)) {
|
||||||
|
updateExportTask(ExportConstants.ExportState.SUCCESS.toString(), exportTasks.getFirst().getId());
|
||||||
|
}
|
||||||
LogUtils.error(e);
|
LogUtils.error(e);
|
||||||
throw new MSException(e);
|
throw new MSException(e);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ExportTask> getExportTasks() {
|
||||||
|
ExportTaskExample exportTaskExample = new ExportTaskExample();
|
||||||
|
exportTaskExample.createCriteria().andTypeEqualTo(ExportConstants.ExportType.CASE.toString()).andStateEqualTo(ExportConstants.ExportState.PREPARED.toString());
|
||||||
|
return exportTaskMapper.selectByExample(exportTaskExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateExportTask(String state, String taskId) {
|
||||||
|
ExportTask exportTask = new ExportTask();
|
||||||
|
exportTask.setState(state);
|
||||||
|
exportTask.setId(taskId);
|
||||||
|
exportTaskMapper.updateByPrimaryKey(exportTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadFileToMinio(File file, String fileId) {
|
private void uploadFileToMinio(File file, String fileId) {
|
||||||
|
@ -757,4 +801,8 @@ public class FunctionalCaseFileService {
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + "Metersphere_case_" + project.getName() + "\"")
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + "Metersphere_case_" + project.getName() + "\"")
|
||||||
.body(bytes);
|
.body(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stopExport(String projectId, String userId) {
|
||||||
|
exportTaskManager.sendStopMessage(projectId, userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
package io.metersphere.functional.xmind.parser;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import io.metersphere.sdk.util.XMLUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.dom4j.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class XMindLegacy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回content.xml和comments.xml合并后的json
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static List<String> getContent(String xmlContent, String xmlComments) throws IOException, DocumentException {
|
||||||
|
// 删除content.xml里面不能识别的字符串
|
||||||
|
xmlContent = xmlContent.replace("xmlns=\"urn:xmind:xmap:xmlns:content:2.0\"", StringUtils.EMPTY);
|
||||||
|
xmlContent = xmlContent.replace("xmlns:fo=\"http://www.w3.org/1999/XSL/Format\"", StringUtils.EMPTY);
|
||||||
|
try {
|
||||||
|
xmlContent = removeTopicsFromString(xmlContent);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error("移除xml中的Topic出错:", e);
|
||||||
|
}
|
||||||
|
// 去除title中svg:width属性
|
||||||
|
xmlContent = xmlContent.replaceAll("<title svg:width=\"[0-9]*\">", "<title>");
|
||||||
|
Document document = DocumentHelper.parseText(xmlContent);// 读取XML文件,获得document对象
|
||||||
|
Element root = document.getRootElement();
|
||||||
|
List<Node> topics = root.selectNodes("//topic");
|
||||||
|
|
||||||
|
if (xmlComments != null) {
|
||||||
|
// 删除comments.xml里面不能识别的字符串
|
||||||
|
xmlComments = xmlComments.replace("xmlns=\"urn:xmind:xmap:xmlns:comments:2.0\"", StringUtils.EMPTY);
|
||||||
|
|
||||||
|
// 添加评论到content中
|
||||||
|
Document commentDocument = DocumentHelper.parseText(xmlComments);
|
||||||
|
List<Node> commentsList = commentDocument.selectNodes("//comment");
|
||||||
|
|
||||||
|
for (Node topic : topics) {
|
||||||
|
for (Node commentNode : commentsList) {
|
||||||
|
Element commentElement = (Element) commentNode;
|
||||||
|
Element topicElement = (Element) topic;
|
||||||
|
if (topicElement.attribute("id").getValue()
|
||||||
|
.equals(commentElement.attribute("object-id").getValue())) {
|
||||||
|
Element comment = topicElement.addElement("comments");
|
||||||
|
comment.addAttribute("creationTime", commentElement.attribute("time").getValue());
|
||||||
|
comment.addAttribute("author", commentElement.attribute("author").getValue());
|
||||||
|
comment.addAttribute("content", commentElement.element("content").getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一个topic转换为json中的rootTopic
|
||||||
|
List<Node> rootTopics = root.selectNodes("/xmap-content/sheet/topic");
|
||||||
|
for (Node rootTopic : rootTopics) {
|
||||||
|
rootTopic.setName("rootTopic");
|
||||||
|
|
||||||
|
// 将xml中topic节点转换为attached节点
|
||||||
|
List<Node> topicList = rootTopic.selectNodes("//topic");
|
||||||
|
for (Node node : topicList) {
|
||||||
|
node.setName("attached");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> sheets = new ArrayList<>();
|
||||||
|
for (Element sheet : root.elements("sheet")) {
|
||||||
|
String res = sheet.asXML();
|
||||||
|
// 将xml转为json
|
||||||
|
JsonNode xmlJSONObj = XMLUtils.xmlConvertJson(res);
|
||||||
|
JsonNode jsonNode = xmlJSONObj.get("sheet");
|
||||||
|
sheets.add(jsonNode.toString());
|
||||||
|
}
|
||||||
|
// 设置缩进
|
||||||
|
return sheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除topics节点
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static String removeTopicsFromString(String xmlContent) throws Exception {
|
||||||
|
Document doc = DocumentHelper.parseText(xmlContent);
|
||||||
|
if (doc != null) {
|
||||||
|
Element root = doc.getRootElement();
|
||||||
|
List<Element> childrenElement = root.elements();
|
||||||
|
for (Element child : childrenElement) {
|
||||||
|
removeTopicsFromElement(child);
|
||||||
|
}
|
||||||
|
xmlContent = doc.asXML();
|
||||||
|
}
|
||||||
|
return xmlContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归删除topics节点
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static void removeTopicsFromElement(Element element) {
|
||||||
|
if (element != null) {
|
||||||
|
List<Element> childrenElement = element.elements();
|
||||||
|
List<Element> removeElements = new ArrayList<>();
|
||||||
|
List<Element> addElements = new ArrayList<>();
|
||||||
|
for (Element child : childrenElement) {
|
||||||
|
if (StringUtils.equalsIgnoreCase("topics", child.getName()) && StringUtils.equalsAnyIgnoreCase(child.attributeValue("type"), "attached", "detached")) {
|
||||||
|
removeElements.add(child);
|
||||||
|
addElements.addAll(child.elements());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeElements.forEach(item -> {
|
||||||
|
item.getParent().remove(item);
|
||||||
|
});
|
||||||
|
addElements.forEach(item -> {
|
||||||
|
item.setParent(null);
|
||||||
|
element.add(item);
|
||||||
|
});
|
||||||
|
childrenElement = element.elements();
|
||||||
|
for (Element child : childrenElement) {
|
||||||
|
removeTopicsFromElement(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package io.metersphere.functional.xmind.parser;
|
||||||
|
|
||||||
|
import io.metersphere.functional.xmind.pojo.JsonRootBean;
|
||||||
|
import io.metersphere.sdk.exception.MSException;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.sdk.util.MsFileUtils;
|
||||||
|
import io.metersphere.sdk.util.Translator;
|
||||||
|
import org.apache.commons.compress.archivers.ArchiveException;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 解析主体
|
||||||
|
*/
|
||||||
|
public class XMindParser {
|
||||||
|
public static final String CONTENT_JSON = "content.json";
|
||||||
|
public static final String CONTENT_XML = "content.xml";
|
||||||
|
public static final String COMMENTS_XML = "comments.xml";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析脑图文件,返回content整合后的内容
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static List<String> parseJson(MultipartFile multipartFile) throws IOException {
|
||||||
|
|
||||||
|
File file = MsFileUtils.multipartFileToFile(multipartFile);
|
||||||
|
List<String> contents;
|
||||||
|
String res = null;
|
||||||
|
if (file == null || !file.exists()) {
|
||||||
|
throw new MSException (Translator.get("incorrect_format"));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
res = ZipUtils.extract(file);
|
||||||
|
if (isXMindZen(res)) {
|
||||||
|
contents = (getXMindZenContent(res));
|
||||||
|
} else {
|
||||||
|
contents = getXMindLegacyContent(res);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new MSException (e.getMessage());
|
||||||
|
} finally {
|
||||||
|
// 删除生成的文件夹
|
||||||
|
if (res != null) {
|
||||||
|
File dir = new File(res);
|
||||||
|
FileUtils.deleteDirectory(dir);
|
||||||
|
}
|
||||||
|
// 删除零时文件
|
||||||
|
if (file != null) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<JsonRootBean> parseObject(MultipartFile multipartFile) throws DocumentException, ArchiveException, IOException {
|
||||||
|
List<String> contents = parseJson(multipartFile);
|
||||||
|
int caseCount = 0;
|
||||||
|
List<JsonRootBean> jsonRootBeans = new ArrayList<>();
|
||||||
|
if (contents != null) {
|
||||||
|
for (String content : contents) {
|
||||||
|
caseCount += content.split("(case-:)").length;
|
||||||
|
JsonRootBean jsonRootBean = JSON.parseObject(content, JsonRootBean.class);
|
||||||
|
jsonRootBeans.add(jsonRootBean);
|
||||||
|
}
|
||||||
|
if (caseCount > 800) {
|
||||||
|
throw new MSException (Translator.get("import_xmind_count_error"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonRootBeans;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析xmind zen 格式的文件
|
||||||
|
* @param extractFileDir 解压后的文件夹名字
|
||||||
|
*/
|
||||||
|
public static List<String> getXMindZenContent(String extractFileDir)
|
||||||
|
throws IOException {
|
||||||
|
List<String> keys = new ArrayList<>();
|
||||||
|
keys.add(CONTENT_JSON);
|
||||||
|
Map<String, String> map = ZipUtils.getContents(keys, extractFileDir);
|
||||||
|
String content = map.get(CONTENT_JSON);
|
||||||
|
return XMindZen.getContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析正常xmind 格式的文件
|
||||||
|
* @param extractFileDir 解压后的文件夹名字
|
||||||
|
*/
|
||||||
|
public static List<String> getXMindLegacyContent(String extractFileDir)
|
||||||
|
throws IOException, DocumentException {
|
||||||
|
List<String> keys = new ArrayList<>();
|
||||||
|
keys.add(CONTENT_XML);
|
||||||
|
keys.add(COMMENTS_XML);
|
||||||
|
Map<String, String> map = ZipUtils.getContents(keys, extractFileDir);
|
||||||
|
|
||||||
|
String contentXml = map.get(CONTENT_XML);
|
||||||
|
String commentsXml = map.get(COMMENTS_XML);
|
||||||
|
|
||||||
|
return XMindLegacy.getContent(contentXml, commentsXml);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isXMindZen(String res){
|
||||||
|
// 解压
|
||||||
|
File parent = new File(res);
|
||||||
|
if (parent.isDirectory()) {
|
||||||
|
String[] files = parent.list(new ZipUtils.FileFilter());
|
||||||
|
for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
|
||||||
|
if (files[i].equals(CONTENT_JSON)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package io.metersphere.functional.xmind.parser;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class XMindZen {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回content.json 解析后的的json
|
||||||
|
*/
|
||||||
|
public static List<String> getContent(String jsonContent) {
|
||||||
|
List jsonArray = JSON.parseArray(jsonContent);//.getJSONObject(0);
|
||||||
|
List<String> contents = new ArrayList<>();
|
||||||
|
for (Object object : jsonArray) {
|
||||||
|
Map<String, Map> jsonObject = (Map) object;
|
||||||
|
Map<String, Map> rootTopic = jsonObject.get("rootTopic");
|
||||||
|
transferNotes(rootTopic);
|
||||||
|
Map children = rootTopic.get("children");
|
||||||
|
recursionChildren(children);
|
||||||
|
contents.add(JSON.toJSONString(jsonObject));
|
||||||
|
}
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归转换children
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static void recursionChildren(Map<String, List> children) {
|
||||||
|
if (children == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<Map> attachedArray = children.get("attached");
|
||||||
|
if (attachedArray == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Object attached : attachedArray) {
|
||||||
|
Map<String, Map> attachedObject = (Map) attached;
|
||||||
|
transferNotes(attachedObject);
|
||||||
|
Map<String, List> childrenObject = attachedObject.get("children");
|
||||||
|
if (childrenObject == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
recursionChildren(childrenObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void transferNotes(Map object) {
|
||||||
|
Map notes = (Map) object.get("notes");
|
||||||
|
if (notes == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map plain = (Map) notes.get("plain");
|
||||||
|
if (plain != null) {
|
||||||
|
String content = plain.get("content").toString();
|
||||||
|
notes.remove("plain");
|
||||||
|
notes.put("content", content);
|
||||||
|
} else {
|
||||||
|
notes.put("content", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package io.metersphere.functional.xmind.parser;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.util.Translator;
|
||||||
|
import org.apache.commons.compress.archivers.ArchiveException;
|
||||||
|
import org.apache.commons.compress.archivers.examples.Expander;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description zip解压工具
|
||||||
|
*/
|
||||||
|
public class ZipUtils {
|
||||||
|
|
||||||
|
private static final String CURRENT_PATH = System.getProperty("user.dir");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 找到压缩文件中匹配的子文件,返回的为 getContents("comments.xml, unzip
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getContents(List<String> subFileNames, String extractFileDir)
|
||||||
|
throws IOException {
|
||||||
|
Map<String, String> map = new HashMap<>(16);
|
||||||
|
File destFile = new File(extractFileDir);
|
||||||
|
if (destFile.isDirectory()) {
|
||||||
|
String[] res = destFile.list(new FileFilter());
|
||||||
|
for (int i = 0; i < Objects.requireNonNull(res).length; i++) {
|
||||||
|
if (subFileNames.contains(res[i])) {
|
||||||
|
String s = extractFileDir + File.separator + res[i];
|
||||||
|
String content = getFileContent(s);
|
||||||
|
map.put(res[i], content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回解压后的文件夹名字
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static String extract(File file) throws IOException, ArchiveException {
|
||||||
|
Expander expander = new Expander();
|
||||||
|
String destFileName = CURRENT_PATH + File.separator + "XMind" + System.currentTimeMillis();
|
||||||
|
expander.expand(file, new File(destFileName));
|
||||||
|
return destFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这是一个内部类过滤器,策略模式
|
||||||
|
*/
|
||||||
|
static class FileFilter implements FilenameFilter {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File dir, String name) {
|
||||||
|
// String的 endsWith(String str)方法 筛选出以str结尾的字符串
|
||||||
|
return name.endsWith(".xml") || name.endsWith(".json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFileContent(String fileName) throws IOException {
|
||||||
|
File file;
|
||||||
|
try {
|
||||||
|
file = new File(fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(Translator.get("case.find_file_error"));
|
||||||
|
}
|
||||||
|
FileReader fileReader = new FileReader(file);
|
||||||
|
BufferedReader bufferedReader = new BufferedReader(fileReader);
|
||||||
|
StringBuilder stringBuffer = new StringBuilder();
|
||||||
|
while (bufferedReader.ready()) {
|
||||||
|
if(!stringBuffer.isEmpty()){
|
||||||
|
stringBuffer.append("\r\n");
|
||||||
|
}
|
||||||
|
stringBuffer.append(bufferedReader.readLine());
|
||||||
|
}
|
||||||
|
// 打开的文件需关闭,在unix下可以删除,否则在windows下不能删除(file.delete())
|
||||||
|
bufferedReader.close();
|
||||||
|
fileReader.close();
|
||||||
|
return stringBuffer.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
package io.metersphere.functional.xmind.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XMind 节点对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Attached {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String title;
|
||||||
|
private Notes notes;
|
||||||
|
private String path;
|
||||||
|
private Attached parent;
|
||||||
|
private List<Comments> comments;
|
||||||
|
private Children children;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package io.metersphere.functional.xmind.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Children {
|
||||||
|
|
||||||
|
private List<Attached> attached;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package io.metersphere.functional.xmind.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Comments {
|
||||||
|
|
||||||
|
private long creationTime;
|
||||||
|
private String author;
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package io.metersphere.functional.xmind.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class JsonRootBean {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String title;
|
||||||
|
private RootTopic rootTopic;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package io.metersphere.functional.xmind.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Notes {
|
||||||
|
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package io.metersphere.functional.xmind.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class RootTopic {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String title;
|
||||||
|
private Notes notes;
|
||||||
|
private List<Comments> comments;
|
||||||
|
private Children children;
|
||||||
|
|
||||||
|
}
|
|
@ -90,6 +90,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
||||||
public static final String DOWNLOAD_XMIND_TEMPLATE_URL = "/functional/case/download/xmind/template/";
|
public static final String DOWNLOAD_XMIND_TEMPLATE_URL = "/functional/case/download/xmind/template/";
|
||||||
public static final String EXPORT_COLUMNS_URL = "/functional/case/export/columns/";
|
public static final String EXPORT_COLUMNS_URL = "/functional/case/export/columns/";
|
||||||
public static final String DOWNLOAD_FILE_URL = "/functional/case/download/file/";
|
public static final String DOWNLOAD_FILE_URL = "/functional/case/download/file/";
|
||||||
|
public static final String STOP_EXPORT_URL = "/functional/case/stop/";
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private NotificationMapper notificationMapper;
|
private NotificationMapper notificationMapper;
|
||||||
|
@ -858,4 +859,10 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
||||||
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
.header(SessionConstants.CSRF_TOKEN, csrfToken));
|
.header(SessionConstants.CSRF_TOKEN, csrfToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(25)
|
||||||
|
public void stopExport() throws Exception {
|
||||||
|
this.requestGetExcel(STOP_EXPORT_URL + DEFAULT_PROJECT_ID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package io.metersphere.system.constants;
|
||||||
|
|
||||||
|
public class ExportConstants {
|
||||||
|
|
||||||
|
public enum ExportType {
|
||||||
|
API, CASE
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ExportState {
|
||||||
|
PREPARED, STOP, SUCCESS, ERROR
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
package io.metersphere.system.manager;
|
||||||
|
|
||||||
|
import io.metersphere.functional.domain.ExportTask;
|
||||||
|
import io.metersphere.functional.mapper.ExportTaskMapper;
|
||||||
|
import io.metersphere.sdk.constants.KafkaTopicConstants;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import io.metersphere.system.constants.ExportConstants;
|
||||||
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.springframework.kafka.annotation.KafkaListener;
|
||||||
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ExportTaskManager {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private KafkaTemplate<String, String> kafkaTemplate;
|
||||||
|
@Resource
|
||||||
|
private ExportTaskMapper exportTaskMapper;
|
||||||
|
|
||||||
|
public static Map<String, Future<?>> map = new ConcurrentHashMap<>();
|
||||||
|
public static final String EXPORT_CONSUME = "export_consume";
|
||||||
|
|
||||||
|
|
||||||
|
public <T> void exportAsyncTask(String userId, String type, T t, Function<Object, Object> selectListFunc) throws InterruptedException {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||||
|
Future<?> future = executorService.submit(() -> {
|
||||||
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
|
// 线程任务逻辑
|
||||||
|
LogUtils.info("Thread has been start.");
|
||||||
|
selectListFunc.apply(t);
|
||||||
|
}
|
||||||
|
LogUtils.info("Thread has been interrupted.");
|
||||||
|
});
|
||||||
|
Thread.sleep(6000);
|
||||||
|
ExportTask exportTask = buildExportTask(userId, type);
|
||||||
|
map.put(exportTask.getId(), future);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExportTask buildExportTask(String userId, String type) {
|
||||||
|
ExportTask exportTask = new ExportTask();
|
||||||
|
exportTask.setId(IDGenerator.nextStr());
|
||||||
|
exportTask.setType(type);
|
||||||
|
exportTask.setCreateUser(userId);
|
||||||
|
exportTask.setCreateTime(System.currentTimeMillis());
|
||||||
|
exportTask.setState(ExportConstants.ExportState.PREPARED.toString());
|
||||||
|
exportTask.setUpdateUser(userId);
|
||||||
|
exportTask.setUpdateTime(System.currentTimeMillis());
|
||||||
|
exportTaskMapper.insert(exportTask);
|
||||||
|
return exportTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendStopMessage(String id, String userId) {
|
||||||
|
ExportTask exportTask = new ExportTask();
|
||||||
|
exportTask.setId(id);
|
||||||
|
exportTask.setState(ExportConstants.ExportState.STOP.toString());
|
||||||
|
exportTask.setUpdateUser(userId);
|
||||||
|
exportTask.setUpdateTime(System.currentTimeMillis());
|
||||||
|
kafkaTemplate.send(KafkaTopicConstants.EXPORT, JSON.toJSONString(exportTask));
|
||||||
|
}
|
||||||
|
|
||||||
|
@KafkaListener(id=EXPORT_CONSUME, topics = KafkaTopicConstants.EXPORT, groupId = EXPORT_CONSUME + "_" + "${random.uuid}")
|
||||||
|
public void stop(ConsumerRecord<?, String> record) {
|
||||||
|
LogUtils.info("Service consume platform_plugin message: " + record.value());
|
||||||
|
ExportTask exportTask = JSON.parseObject(record.value(), ExportTask.class);
|
||||||
|
if (exportTask!=null && StringUtils.isNotBlank(exportTask.getId())) {
|
||||||
|
String id = exportTask.getId();
|
||||||
|
map.get(id).cancel(true);
|
||||||
|
map.remove(id);
|
||||||
|
exportTaskMapper.updateByPrimaryKey(exportTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(fixedDelay = 10000)
|
||||||
|
public void checkStop() {
|
||||||
|
for (String next : map.keySet()) {
|
||||||
|
if (map.get(next) != null && map.get(next).isDone()) {
|
||||||
|
map.remove(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue