feat(测试跟踪): 功能用例&缺陷管理附件功能改造
--story=1006991 --user=宋昌昌 【测试跟踪】功能用例&缺陷增加附件功能支持视频文件(1.20分支同步上) https://www.tapd.cn/55049933/s/1194201
This commit is contained in:
parent
f08efd25bd
commit
4ccc8c0b03
|
@ -0,0 +1,25 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FileAttachmentMetadata implements Serializable {
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private Long size;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private Long updateTime;
|
||||
|
||||
private String creator;
|
||||
|
||||
private String filePath;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -0,0 +1,730 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FileAttachmentMetadataExample {
|
||||
protected String orderByClause;
|
||||
|
||||
protected boolean distinct;
|
||||
|
||||
protected List<Criteria> oredCriteria;
|
||||
|
||||
public FileAttachmentMetadataExample() {
|
||||
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 andSizeIsNull() {
|
||||
addCriterion("`size` is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeIsNotNull() {
|
||||
addCriterion("`size` is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeEqualTo(Long value) {
|
||||
addCriterion("`size` =", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotEqualTo(Long value) {
|
||||
addCriterion("`size` <>", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeGreaterThan(Long value) {
|
||||
addCriterion("`size` >", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("`size` >=", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeLessThan(Long value) {
|
||||
addCriterion("`size` <", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeLessThanOrEqualTo(Long value) {
|
||||
addCriterion("`size` <=", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeIn(List<Long> values) {
|
||||
addCriterion("`size` in", values, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotIn(List<Long> values) {
|
||||
addCriterion("`size` not in", values, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeBetween(Long value1, Long value2) {
|
||||
addCriterion("`size` between", value1, value2, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotBetween(Long value1, Long value2) {
|
||||
addCriterion("`size` not between", value1, value2, "size");
|
||||
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 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 Criteria andCreatorIsNull() {
|
||||
addCriterion("creator is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorIsNotNull() {
|
||||
addCriterion("creator is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorEqualTo(String value) {
|
||||
addCriterion("creator =", value, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorNotEqualTo(String value) {
|
||||
addCriterion("creator <>", value, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorGreaterThan(String value) {
|
||||
addCriterion("creator >", value, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("creator >=", value, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorLessThan(String value) {
|
||||
addCriterion("creator <", value, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorLessThanOrEqualTo(String value) {
|
||||
addCriterion("creator <=", value, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorLike(String value) {
|
||||
addCriterion("creator like", value, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorNotLike(String value) {
|
||||
addCriterion("creator not like", value, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorIn(List<String> values) {
|
||||
addCriterion("creator in", values, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorNotIn(List<String> values) {
|
||||
addCriterion("creator not in", values, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorBetween(String value1, String value2) {
|
||||
addCriterion("creator between", value1, value2, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatorNotBetween(String value1, String value2) {
|
||||
addCriterion("creator not between", value1, value2, "creator");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathIsNull() {
|
||||
addCriterion("file_path is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathIsNotNull() {
|
||||
addCriterion("file_path is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathEqualTo(String value) {
|
||||
addCriterion("file_path =", value, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathNotEqualTo(String value) {
|
||||
addCriterion("file_path <>", value, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathGreaterThan(String value) {
|
||||
addCriterion("file_path >", value, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("file_path >=", value, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathLessThan(String value) {
|
||||
addCriterion("file_path <", value, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathLessThanOrEqualTo(String value) {
|
||||
addCriterion("file_path <=", value, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathLike(String value) {
|
||||
addCriterion("file_path like", value, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathNotLike(String value) {
|
||||
addCriterion("file_path not like", value, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathIn(List<String> values) {
|
||||
addCriterion("file_path in", values, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathNotIn(List<String> values) {
|
||||
addCriterion("file_path not in", values, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathBetween(String value1, String value2) {
|
||||
addCriterion("file_path between", value1, value2, "filePath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFilePathNotBetween(String value1, String value2) {
|
||||
addCriterion("file_path not between", value1, value2, "filePath");
|
||||
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,13 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class IssueFile implements Serializable {
|
||||
private String issueId;
|
||||
|
||||
private String fileId;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -0,0 +1,340 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IssueFileExample {
|
||||
protected String orderByClause;
|
||||
|
||||
protected boolean distinct;
|
||||
|
||||
protected List<Criteria> oredCriteria;
|
||||
|
||||
public IssueFileExample() {
|
||||
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 andIssueIdIsNull() {
|
||||
addCriterion("issue_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdIsNotNull() {
|
||||
addCriterion("issue_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdEqualTo(String value) {
|
||||
addCriterion("issue_id =", value, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdNotEqualTo(String value) {
|
||||
addCriterion("issue_id <>", value, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdGreaterThan(String value) {
|
||||
addCriterion("issue_id >", value, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("issue_id >=", value, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdLessThan(String value) {
|
||||
addCriterion("issue_id <", value, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("issue_id <=", value, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdLike(String value) {
|
||||
addCriterion("issue_id like", value, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdNotLike(String value) {
|
||||
addCriterion("issue_id not like", value, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdIn(List<String> values) {
|
||||
addCriterion("issue_id in", values, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdNotIn(List<String> values) {
|
||||
addCriterion("issue_id not in", values, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdBetween(String value1, String value2) {
|
||||
addCriterion("issue_id between", value1, value2, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIssueIdNotBetween(String value1, String value2) {
|
||||
addCriterion("issue_id not between", value1, value2, "issueId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdIsNull() {
|
||||
addCriterion("file_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdIsNotNull() {
|
||||
addCriterion("file_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdEqualTo(String value) {
|
||||
addCriterion("file_id =", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdNotEqualTo(String value) {
|
||||
addCriterion("file_id <>", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdGreaterThan(String value) {
|
||||
addCriterion("file_id >", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("file_id >=", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdLessThan(String value) {
|
||||
addCriterion("file_id <", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("file_id <=", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdLike(String value) {
|
||||
addCriterion("file_id like", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdNotLike(String value) {
|
||||
addCriterion("file_id not like", value, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdIn(List<String> values) {
|
||||
addCriterion("file_id in", values, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdNotIn(List<String> values) {
|
||||
addCriterion("file_id not in", values, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdBetween(String value1, String value2) {
|
||||
addCriterion("file_id between", value1, value2, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFileIdNotBetween(String value1, String value2) {
|
||||
addCriterion("file_id not between", value1, value2, "fileId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public 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,30 @@
|
|||
package io.metersphere.base.mapper;
|
||||
|
||||
import io.metersphere.base.domain.FileAttachmentMetadata;
|
||||
import io.metersphere.base.domain.FileAttachmentMetadataExample;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface FileAttachmentMetadataMapper {
|
||||
long countByExample(FileAttachmentMetadataExample example);
|
||||
|
||||
int deleteByExample(FileAttachmentMetadataExample example);
|
||||
|
||||
int deleteByPrimaryKey(String id);
|
||||
|
||||
int insert(FileAttachmentMetadata record);
|
||||
|
||||
int insertSelective(FileAttachmentMetadata record);
|
||||
|
||||
List<FileAttachmentMetadata> selectByExample(FileAttachmentMetadataExample example);
|
||||
|
||||
FileAttachmentMetadata selectByPrimaryKey(String id);
|
||||
|
||||
int updateByExampleSelective(@Param("record") FileAttachmentMetadata record, @Param("example") FileAttachmentMetadataExample example);
|
||||
|
||||
int updateByExample(@Param("record") FileAttachmentMetadata record, @Param("example") FileAttachmentMetadataExample example);
|
||||
|
||||
int updateByPrimaryKeySelective(FileAttachmentMetadata record);
|
||||
|
||||
int updateByPrimaryKey(FileAttachmentMetadata record);
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
<?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.base.mapper.FileAttachmentMetadataMapper">
|
||||
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.FileAttachmentMetadata">
|
||||
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="type" jdbcType="VARCHAR" property="type" />
|
||||
<result column="size" jdbcType="BIGINT" property="size" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
<result column="creator" jdbcType="VARCHAR" property="creator" />
|
||||
<result column="file_path" jdbcType="VARCHAR" property="filePath" />
|
||||
</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`, `size`, create_time, update_time, creator, file_path
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.FileAttachmentMetadataExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
from file_attachment_metadata
|
||||
<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 file_attachment_metadata
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</select>
|
||||
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
|
||||
delete from file_attachment_metadata
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</delete>
|
||||
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.FileAttachmentMetadataExample">
|
||||
delete from file_attachment_metadata
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.FileAttachmentMetadata">
|
||||
insert into file_attachment_metadata (id, `name`, `type`,
|
||||
`size`, create_time, update_time,
|
||||
creator, file_path)
|
||||
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
|
||||
#{size,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||
#{creator,jdbcType=VARCHAR}, #{filePath,jdbcType=VARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.FileAttachmentMetadata">
|
||||
insert into file_attachment_metadata
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
id,
|
||||
</if>
|
||||
<if test="name != null">
|
||||
`name`,
|
||||
</if>
|
||||
<if test="type != null">
|
||||
`type`,
|
||||
</if>
|
||||
<if test="size != null">
|
||||
`size`,
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time,
|
||||
</if>
|
||||
<if test="updateTime != null">
|
||||
update_time,
|
||||
</if>
|
||||
<if test="creator != null">
|
||||
creator,
|
||||
</if>
|
||||
<if test="filePath != null">
|
||||
file_path,
|
||||
</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="size != null">
|
||||
#{size,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
#{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="updateTime != null">
|
||||
#{updateTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="creator != null">
|
||||
#{creator,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="filePath != null">
|
||||
#{filePath,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.FileAttachmentMetadataExample" resultType="java.lang.Long">
|
||||
select count(*) from file_attachment_metadata
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</select>
|
||||
<update id="updateByExampleSelective" parameterType="map">
|
||||
update file_attachment_metadata
|
||||
<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.size != null">
|
||||
`size` = #{record.size,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="record.createTime != null">
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="record.updateTime != null">
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="record.creator != null">
|
||||
creator = #{record.creator,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.filePath != null">
|
||||
file_path = #{record.filePath,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update file_attachment_metadata
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
`name` = #{record.name,jdbcType=VARCHAR},
|
||||
`type` = #{record.type,jdbcType=VARCHAR},
|
||||
`size` = #{record.size,jdbcType=BIGINT},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
creator = #{record.creator,jdbcType=VARCHAR},
|
||||
file_path = #{record.filePath,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.FileAttachmentMetadata">
|
||||
update file_attachment_metadata
|
||||
<set>
|
||||
<if test="name != null">
|
||||
`name` = #{name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="type != null">
|
||||
`type` = #{type,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="size != null">
|
||||
`size` = #{size,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="updateTime != null">
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="creator != null">
|
||||
creator = #{creator,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="filePath != null">
|
||||
file_path = #{filePath,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.FileAttachmentMetadata">
|
||||
update file_attachment_metadata
|
||||
set `name` = #{name,jdbcType=VARCHAR},
|
||||
`type` = #{type,jdbcType=VARCHAR},
|
||||
`size` = #{size,jdbcType=BIGINT},
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
creator = #{creator,jdbcType=VARCHAR},
|
||||
file_path = #{filePath,jdbcType=VARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.base.mapper;
|
||||
|
||||
import io.metersphere.base.domain.IssueFile;
|
||||
import io.metersphere.base.domain.IssueFileExample;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface IssueFileMapper {
|
||||
long countByExample(IssueFileExample example);
|
||||
|
||||
int deleteByExample(IssueFileExample example);
|
||||
|
||||
int insert(IssueFile record);
|
||||
|
||||
int insertSelective(IssueFile record);
|
||||
|
||||
List<IssueFile> selectByExample(IssueFileExample example);
|
||||
|
||||
int updateByExampleSelective(@Param("record") IssueFile record, @Param("example") IssueFileExample example);
|
||||
|
||||
int updateByExample(@Param("record") IssueFile record, @Param("example") IssueFileExample example);
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
<?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.base.mapper.IssueFileMapper">
|
||||
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.IssueFile">
|
||||
<result column="issue_id" jdbcType="VARCHAR" property="issueId" />
|
||||
<result column="file_id" jdbcType="VARCHAR" property="fileId" />
|
||||
</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">
|
||||
issue_id, file_id
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.IssueFileExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
from issue_file
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.IssueFileExample">
|
||||
delete from issue_file
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.IssueFile">
|
||||
insert into issue_file (issue_id, file_id)
|
||||
values (#{issueId,jdbcType=VARCHAR}, #{fileId,jdbcType=VARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.IssueFile">
|
||||
insert into issue_file
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="issueId != null">
|
||||
issue_id,
|
||||
</if>
|
||||
<if test="fileId != null">
|
||||
file_id,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="issueId != null">
|
||||
#{issueId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="fileId != null">
|
||||
#{fileId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.IssueFileExample" resultType="java.lang.Long">
|
||||
select count(*) from issue_file
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</select>
|
||||
<update id="updateByExampleSelective" parameterType="map">
|
||||
update issue_file
|
||||
<set>
|
||||
<if test="record.issueId != null">
|
||||
issue_id = #{record.issueId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.fileId != null">
|
||||
file_id = #{record.fileId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update issue_file
|
||||
set issue_id = #{record.issueId,jdbcType=VARCHAR},
|
||||
file_id = #{record.fileId,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
</mapper>
|
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public enum AttachmentType {
|
||||
|
||||
TEST_CASE("testcase"), ISSUE("issue");
|
||||
|
||||
// 附件类型名称
|
||||
private String type;
|
||||
|
||||
AttachmentType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String type() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@ public enum FileType {
|
|||
JPG(".jpg"), PNG(".png"), JPEG(".jpeg"), DOC(".doc"),
|
||||
XLSX(".xlsx"), DOCX(".docx"), JAR(".jar"), JS(".js"), TXT(".txt"),
|
||||
P12(".p12"), JKS(".jks"), PFX(".pfx"),
|
||||
DER(".der"), CER(".cer"), PEM(".pem"), CRT(".crt"), SIDE(".side")
|
||||
DER(".der"), CER(".cer"), PEM(".pem"), CRT(".crt"), SIDE(".side"),
|
||||
MP4(".mp4"), MOV(".mov"), DCM(".dcm"), ZIP(".zip"), RAR(".rar")
|
||||
;
|
||||
|
||||
// 保存后缀
|
||||
|
|
|
@ -26,6 +26,10 @@ public class FileUtils {
|
|||
public static final String BODY_FILE_DIR = "/opt/metersphere/data/body";
|
||||
public static final String MD_IMAGE_DIR = "/opt/metersphere/data/image/markdown";
|
||||
public static final String UI_IMAGE_DIR = "/opt/metersphere/data/image/ui/screenshots";
|
||||
public static final String ATTACHMENT_DIR = "/opt/metersphere/data/attachment";
|
||||
public static final String TEST_CASE_ATTACHMENT_DIR = "/opt/metersphere/data/attachment/testcase";
|
||||
public static final String ISSUE_ATTACHMENT_DIR = "/opt/metersphere/data/attachment/issue";
|
||||
|
||||
|
||||
public static byte[] listBytesToZip(Map<String, byte[]> mapReport) {
|
||||
try {
|
||||
|
@ -339,6 +343,41 @@ public class FileUtils {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
public static File byteToFile(byte[] buf, String filePath, String fileName){
|
||||
BufferedOutputStream bos = null;
|
||||
FileOutputStream fos = null;
|
||||
File file = null;
|
||||
try{
|
||||
File dir = new File(filePath);
|
||||
if (!dir.exists()){
|
||||
dir.mkdirs();
|
||||
}
|
||||
file = new File(filePath + "/" + fileName);
|
||||
fos = new FileOutputStream(file);
|
||||
bos = new BufferedOutputStream(fos);
|
||||
bos.write(buf);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally{
|
||||
if (bos != null){
|
||||
try{
|
||||
bos.close();
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (fos != null){
|
||||
try{
|
||||
fos.close();
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public static String fileToStr(File tradeFile) {
|
||||
String buffer = null;
|
||||
try (FileInputStream fis = new FileInputStream(tradeFile);
|
||||
|
|
|
@ -80,6 +80,7 @@ public class ShiroUtils {
|
|||
filterChainDefinitionMap.put("/", "apikey, authc"); // 跳转到 / 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/language", "apikey, authc");// 跳转到 /language 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/test/case/file/preview/**", "apikey, authc"); // 预览测试用例附件 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/test/case/attachment/preview/**", "apikey, authc"); // 预览测试用例附件 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/mock", "apikey, authc"); // 跳转到 /mock接口 不用校验 csrf
|
||||
}
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
|
|||
initOnceOperate(mockConfigService::initExpectNum, "init.mock.expectNum");
|
||||
initOnceOperate(customFieldResourceService::compatibleData, "init.custom.field.resource");
|
||||
initOnceOperate(jarConfigService::initJarPath, "init.jar.path");
|
||||
initOnceOperate(testCaseService::initAttachment, "init.attachment.test.case");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.FileContentMapper;
|
||||
import io.metersphere.base.mapper.FileMetadataMapper;
|
||||
import io.metersphere.base.mapper.TestCaseFileMapper;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.commons.constants.FileType;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.RsaKey;
|
||||
import io.metersphere.commons.utils.RsaUtil;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.performance.request.QueryProjectFileRequest;
|
||||
import org.apache.commons.lang3.SerializationUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -32,9 +28,13 @@ public class FileService {
|
|||
@Resource
|
||||
private FileMetadataMapper fileMetadataMapper;
|
||||
@Resource
|
||||
private FileAttachmentMetadataMapper fileAttachmentMetadataMapper;
|
||||
@Resource
|
||||
private FileContentMapper fileContentMapper;
|
||||
@Resource
|
||||
private TestCaseFileMapper testCaseFileMapper;
|
||||
@Resource
|
||||
private IssueFileMapper issueFileMapper;
|
||||
|
||||
public byte[] loadFileAsBytes(String id) {
|
||||
FileContent fileContent = fileContentMapper.selectByPrimaryKey(id);
|
||||
|
@ -42,6 +42,12 @@ public class FileService {
|
|||
return fileContent.getFile();
|
||||
}
|
||||
|
||||
public byte[] getAttachmentBytes(String id) {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileAttachmentMetadataMapper.selectByPrimaryKey(id);
|
||||
File attachmentFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||
return FileUtils.fileToByte(attachmentFile);
|
||||
}
|
||||
|
||||
public FileContent getFileContent(String fileId) {
|
||||
return fileContentMapper.selectByPrimaryKey(fileId);
|
||||
}
|
||||
|
@ -70,6 +76,23 @@ public class FileService {
|
|||
deleteFileByIds(ids);
|
||||
}
|
||||
|
||||
public void deleteFileAttachmentByIds(List<String> ids) {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
FileAttachmentMetadataExample example = new FileAttachmentMetadataExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
fileAttachmentMetadataMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
public List<FileMetadata> getAllFileMeta() {
|
||||
return fileMetadataMapper.selectByExample(new FileMetadataExample());
|
||||
}
|
||||
|
||||
public List<FileContent> getAllFileContent() {
|
||||
return fileContentMapper.selectByExampleWithBLOBs(new FileContentExample());
|
||||
}
|
||||
|
||||
public FileMetadata saveFile(MultipartFile file, String projectId, String fileId) {
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
if (StringUtils.isEmpty(fileId)) {
|
||||
|
@ -98,6 +121,34 @@ public class FileService {
|
|||
return fileMetadata;
|
||||
}
|
||||
|
||||
public FileAttachmentMetadata saveAttachment(MultipartFile file, String attachmentType, String belongId) {
|
||||
String uploadPath = FileUtils.ATTACHMENT_DIR + "/" + attachmentType + "/" + belongId;
|
||||
FileUtils.uploadFile(file, uploadPath);
|
||||
final FileAttachmentMetadata fileAttachmentMetadata = new FileAttachmentMetadata();
|
||||
fileAttachmentMetadata.setId(UUID.randomUUID().toString());
|
||||
fileAttachmentMetadata.setName(file.getOriginalFilename());
|
||||
fileAttachmentMetadata.setType(getFileType(fileAttachmentMetadata.getName()).name());
|
||||
fileAttachmentMetadata.setSize(file.getSize());
|
||||
fileAttachmentMetadata.setCreateTime(System.currentTimeMillis());
|
||||
fileAttachmentMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
fileAttachmentMetadata.setCreator(SessionUtils.getUser().getName());
|
||||
fileAttachmentMetadata.setFilePath(uploadPath);
|
||||
fileAttachmentMetadataMapper.insert(fileAttachmentMetadata);
|
||||
return fileAttachmentMetadata;
|
||||
}
|
||||
|
||||
public void deleteAttachment(List<String> ids) {
|
||||
for (String id : ids) {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileAttachmentMetadataMapper.selectByPrimaryKey(id);
|
||||
FileUtils.deleteFile(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteAttachment(String attachmentType, String belongId) {
|
||||
String deletePath = FileUtils.ATTACHMENT_DIR + "/" + attachmentType + "/" + belongId;
|
||||
FileUtils.deleteDir(deletePath);
|
||||
}
|
||||
|
||||
public FileMetadata saveFile(MultipartFile file, String projectId) {
|
||||
return saveFile(file, projectId, null);
|
||||
}
|
||||
|
@ -224,6 +275,26 @@ public class FileService {
|
|||
return fileMetadata;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public FileAttachmentMetadata copyAttachment(String fileId, String attachmentType, String belongId) {
|
||||
String copyPath = FileUtils.ATTACHMENT_DIR + "/" + attachmentType + "/" + belongId;
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileAttachmentMetadataMapper.selectByPrimaryKey(fileId);
|
||||
if (fileAttachmentMetadata != null) {
|
||||
File copyFile = new File(copyPath);
|
||||
if (!copyFile.exists()) {
|
||||
FileUtils.copyFolder(fileAttachmentMetadata.getFilePath(), copyPath);
|
||||
}
|
||||
fileAttachmentMetadata.setId(UUID.randomUUID().toString());
|
||||
fileAttachmentMetadata.setCreateTime(System.currentTimeMillis());
|
||||
fileAttachmentMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
fileAttachmentMetadata.setCreator(SessionUtils.getUser().getName());
|
||||
fileAttachmentMetadata.setFilePath(copyPath);
|
||||
fileAttachmentMetadataMapper.insert(fileAttachmentMetadata);
|
||||
}
|
||||
return fileAttachmentMetadata;
|
||||
}
|
||||
|
||||
private FileType getFileType(String filename) {
|
||||
int s = filename.lastIndexOf(".") + 1;
|
||||
String type = filename.substring(s);
|
||||
|
@ -245,6 +316,38 @@ public class FileService {
|
|||
return fileMetadataMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public List<FileAttachmentMetadata> getFileAttachmentMetadataByCaseId(String caseId) {
|
||||
TestCaseFileExample testCaseFileExample = new TestCaseFileExample();
|
||||
testCaseFileExample.createCriteria().andCaseIdEqualTo(caseId);
|
||||
final List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(testCaseFileExample);
|
||||
|
||||
if (CollectionUtils.isEmpty(testCaseFiles)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<String> fileIds = testCaseFiles.stream().map(TestCaseFile::getFileId).collect(Collectors.toList());
|
||||
FileAttachmentMetadataExample example = new FileAttachmentMetadataExample();
|
||||
example.createCriteria().andIdIn(fileIds);
|
||||
return fileAttachmentMetadataMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public List<FileAttachmentMetadata> getFileAttachmentMetadataByIssueId(String issueId) {
|
||||
IssueFileExample issueFileExample = new IssueFileExample();
|
||||
issueFileExample.createCriteria().andIssueIdEqualTo(issueId);
|
||||
final List<IssueFile> issueFiles = issueFileMapper.selectByExample(issueFileExample);
|
||||
|
||||
if (CollectionUtils.isEmpty(issueFiles)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<String> fileIds = issueFiles.stream().map(IssueFile::getFileId).collect(Collectors.toList());
|
||||
FileAttachmentMetadataExample example = new FileAttachmentMetadataExample();
|
||||
example.createCriteria().andIdIn(fileIds);
|
||||
return fileAttachmentMetadataMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void deleteFileById(String fileId) {
|
||||
deleteFileByIds(Collections.singletonList(fileId));
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.track.controller;
|
|||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.FileAttachmentMetadata;
|
||||
import io.metersphere.base.domain.Issues;
|
||||
import io.metersphere.base.domain.IssuesDao;
|
||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||
|
@ -14,6 +15,7 @@ import io.metersphere.commons.utils.Pager;
|
|||
import io.metersphere.dto.IssueTemplateDao;
|
||||
import io.metersphere.log.annotation.MsAuditLog;
|
||||
import io.metersphere.notice.annotation.SendNotice;
|
||||
import io.metersphere.service.FileService;
|
||||
import io.metersphere.track.dto.DemandDTO;
|
||||
import io.metersphere.track.dto.PlatformStatusDTO;
|
||||
import io.metersphere.track.issue.domain.PlatformUser;
|
||||
|
@ -27,6 +29,7 @@ import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
|||
import io.metersphere.track.service.IssuesService;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
@ -37,6 +40,8 @@ public class IssuesController {
|
|||
|
||||
@Resource
|
||||
private IssuesService issuesService;
|
||||
@Resource
|
||||
private FileService fileService;
|
||||
|
||||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_ISSUE_READ)
|
||||
|
@ -59,22 +64,27 @@ public class IssuesController {
|
|||
return PageUtils.setPageInfo(page, issuesService.relateList(request));
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
@PostMapping(value = "/add", consumes = {"multipart/form-data"})
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_ISSUE_READ_CREATE)
|
||||
@MsAuditLog(module = OperLogModule.TRACK_BUG, type = OperLogConstants.CREATE, content = "#msClass.getLogDetails(#issuesRequest)", msClass = IssuesService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.DEFECT_TASK, target = "#issuesRequest",
|
||||
event = NoticeConstants.Event.CREATE, subject = "缺陷通知")
|
||||
public IssuesWithBLOBs addIssues(@RequestBody IssuesUpdateRequest issuesRequest) {
|
||||
return issuesService.addIssues(issuesRequest);
|
||||
public IssuesWithBLOBs addIssues(@RequestPart(value = "request") IssuesUpdateRequest issuesRequest, @RequestPart(value = "file", required = false) List<MultipartFile> files) {
|
||||
return issuesService.addIssuesRefactor(issuesRequest, files);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@PostMapping(value = "/update", consumes = {"multipart/form-data"})
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_ISSUE_READ_EDIT)
|
||||
@MsAuditLog(module = OperLogModule.TRACK_BUG, type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#issuesRequest.id)", content = "#msClass.getLogDetails(#issuesRequest.id)", msClass = IssuesService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.DEFECT_TASK, target = "#issuesRequest",
|
||||
event = NoticeConstants.Event.UPDATE, subject = "缺陷通知")
|
||||
public void updateIssues(@RequestBody IssuesUpdateRequest issuesRequest) {
|
||||
issuesService.updateIssues(issuesRequest);
|
||||
public void updateIssues(@RequestPart(value = "request") IssuesUpdateRequest issuesRequest, @RequestPart(value = "file", required = false) List<MultipartFile> files) {
|
||||
issuesService.updateIssuesRefactor(issuesRequest, files);
|
||||
}
|
||||
|
||||
@GetMapping("/file/attachmentMetadata/{issueId}")
|
||||
public List<FileAttachmentMetadata> getFileAttachmentMetadataByIssueId(@PathVariable String issueId) {
|
||||
return fileService.getFileAttachmentMetadataByIssueId(issueId);
|
||||
}
|
||||
|
||||
@GetMapping("/get/case/{refType}/{id}")
|
||||
|
|
|
@ -6,10 +6,7 @@ import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
|||
import io.metersphere.api.dto.automation.ApiScenarioRequest;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.base.domain.TestCase;
|
||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.TestCaseMapper;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
|
@ -224,7 +221,7 @@ public class TestCaseController {
|
|||
} else {
|
||||
//复制,前端生成 id
|
||||
}
|
||||
return testCaseService.save(request, files);
|
||||
return testCaseService.refactorSave(request, files);
|
||||
}
|
||||
|
||||
@PostMapping("/edit/order")
|
||||
|
@ -238,7 +235,7 @@ public class TestCaseController {
|
|||
@SendNotice(taskType = NoticeConstants.TaskType.TRACK_TEST_CASE_TASK, target = "#targetClass.getTestCase(#request.id)", targetClass = TestCaseService.class,
|
||||
event = NoticeConstants.Event.UPDATE, subject = "测试用例通知")
|
||||
public TestCase editTestCase(@RequestPart("request") EditTestCaseRequest request, @RequestPart(value = "file", required = false) List<MultipartFile> files) {
|
||||
return testCaseService.edit(request, files);
|
||||
return testCaseService.refactorEdit(request, files);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/edit/testPlan", consumes = {"multipart/form-data"})
|
||||
|
@ -374,6 +371,11 @@ public class TestCaseController {
|
|||
return fileService.getFileMetadataByCaseId(caseId);
|
||||
}
|
||||
|
||||
@GetMapping("/file/attachmentMetadata/{caseId}")
|
||||
public List<FileAttachmentMetadata> getFileAttachmentMetadataByCaseId(@PathVariable String caseId) {
|
||||
return fileService.getFileAttachmentMetadataByCaseId(caseId);
|
||||
}
|
||||
|
||||
@PostMapping("/file/download")
|
||||
public ResponseEntity<byte[]> download(@RequestBody FileOperationRequest fileOperationRequest) {
|
||||
byte[] bytes = fileService.loadFileAsBytes(fileOperationRequest.getId());
|
||||
|
@ -383,6 +385,15 @@ public class TestCaseController {
|
|||
.body(bytes);
|
||||
}
|
||||
|
||||
@PostMapping("/attachment/download")
|
||||
public ResponseEntity<byte[]> attachmentDownload(@RequestBody FileOperationRequest fileOperationRequest) {
|
||||
byte[] bytes = fileService.getAttachmentBytes(fileOperationRequest.getId());
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + URLEncoder.encode(fileOperationRequest.getName(), StandardCharsets.UTF_8) + "\"")
|
||||
.body(bytes);
|
||||
}
|
||||
|
||||
@GetMapping("/file/preview/{fileId}")
|
||||
public ResponseEntity<byte[]> preview(@PathVariable String fileId) {
|
||||
byte[] bytes = fileService.loadFileAsBytes(fileId);
|
||||
|
@ -392,6 +403,15 @@ public class TestCaseController {
|
|||
.body(bytes);
|
||||
}
|
||||
|
||||
@GetMapping("/attachment/preview/{fileId}")
|
||||
public ResponseEntity<byte[]> attachmentPreview(@PathVariable String fileId) {
|
||||
byte[] bytes = fileService.getAttachmentBytes(fileId);
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileId + "\"")
|
||||
.body(bytes);
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE, type = OperLogConstants.CREATE, title = "#testCaseWithBLOBs.name", content = "#msClass.getLogDetails(#testCaseWithBLOBs.id)", msClass = TestCaseService.class)
|
||||
public TestCaseWithBLOBs saveTestCase(@RequestBody EditTestCaseRequest request) {
|
||||
|
|
|
@ -22,6 +22,10 @@ public class EditTestCaseRequest extends TestCaseWithBLOBs {
|
|||
*/
|
||||
private List<String> fileIds = new ArrayList<>();
|
||||
private List<List<String>> selected = new ArrayList<>();
|
||||
/**
|
||||
* 复制测试用例时原始用例ID
|
||||
*/
|
||||
private String copyCaseId;
|
||||
// 是否处理附件文件
|
||||
private boolean handleAttachment = true;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package io.metersphere.track.request.testcase;
|
||||
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||
import io.metersphere.track.issue.domain.jira.JiraTransitionsResponse;
|
||||
import io.metersphere.track.dto.PlatformStatusDTO;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -41,4 +41,14 @@ public class IssuesUpdateRequest extends IssuesWithBLOBs {
|
|||
private String devopsFields;
|
||||
|
||||
private PlatformStatusDTO transitions;
|
||||
|
||||
/**
|
||||
* 缺陷附件上传更新的文件数据
|
||||
*/
|
||||
private List<FileMetadata> updatedFileList;
|
||||
|
||||
/**
|
||||
* 复制缺陷时原始缺陷ID
|
||||
*/
|
||||
private String copyIssueId;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.github.pagehelper.PageHelper;
|
|||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtIssuesMapper;
|
||||
import io.metersphere.commons.constants.AttachmentType;
|
||||
import io.metersphere.commons.constants.IssueRefType;
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.constants.IssuesStatus;
|
||||
|
@ -34,11 +35,13 @@ import io.metersphere.track.request.testcase.IssuesRequest;
|
|||
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||
import io.metersphere.track.request.testcase.TestCaseBatchRequest;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
@ -84,6 +87,12 @@ public class IssuesService {
|
|||
private CustomFieldIssuesMapper customFieldIssuesMapper;
|
||||
@Resource
|
||||
StringRedisTemplate stringRedisTemplate;
|
||||
@Resource
|
||||
FileService fileService;
|
||||
@Resource
|
||||
IssueFileMapper issueFileMapper;
|
||||
@Resource
|
||||
private FileAttachmentMetadataMapper fileAttachmentMetadataMapper;
|
||||
|
||||
private static final String SYNC_THIRD_PARTY_ISSUES_KEY = "ISSUE:SYNC";
|
||||
|
||||
|
@ -123,6 +132,90 @@ public class IssuesService {
|
|||
// todo 缺陷更新事件?
|
||||
}
|
||||
|
||||
public IssuesWithBLOBs addIssuesRefactor(IssuesUpdateRequest issuesRequest, List<MultipartFile> files) {
|
||||
List<AbstractIssuePlatform> platformList = getAddPlatforms(issuesRequest);
|
||||
IssuesWithBLOBs issues = null;
|
||||
for (AbstractIssuePlatform platform : platformList) {
|
||||
issues = platform.addIssue(issuesRequest);
|
||||
}
|
||||
if (issuesRequest.getIsPlanEdit()) {
|
||||
issuesRequest.getAddResourceIds().forEach(l -> {
|
||||
testCaseIssueService.updateIssuesCount(l);
|
||||
});
|
||||
}
|
||||
saveFollows(issuesRequest.getId(), issuesRequest.getFollows());
|
||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
||||
|
||||
// copy的附件
|
||||
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
||||
final String addIssueId = issues.getId();
|
||||
IssueFileExample example = new IssueFileExample();
|
||||
example.createCriteria().andIssueIdEqualTo(issuesRequest.getCopyIssueId());
|
||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(example);
|
||||
if (issueFiles != null) {
|
||||
issueFiles.forEach(issueFile -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.copyAttachment(issueFile.getFileId(), AttachmentType.ISSUE.type(), addIssueId);
|
||||
IssueFile newIssueFile = new IssueFile();
|
||||
newIssueFile.setIssueId(addIssueId);
|
||||
newIssueFile.setFileId(fileAttachmentMetadata.getId());
|
||||
issueFileMapper.insert(newIssueFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 新的附件
|
||||
if (files != null) {
|
||||
files.forEach(file -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachment(file, AttachmentType.ISSUE.type(), issuesRequest.getId());
|
||||
IssueFile issueFile = new IssueFile();
|
||||
issueFile.setIssueId(issuesRequest.getId());
|
||||
issueFile.setFileId(fileAttachmentMetadata.getId());
|
||||
issueFileMapper.insert(issueFile);
|
||||
});
|
||||
}
|
||||
return issues;
|
||||
}
|
||||
|
||||
|
||||
public void updateIssuesRefactor(IssuesUpdateRequest issuesRequest, List<MultipartFile> files) {
|
||||
issuesRequest.getId();
|
||||
List<AbstractIssuePlatform> platformList = getUpdatePlatforms(issuesRequest);
|
||||
platformList.forEach(platform -> {
|
||||
platform.updateIssue(issuesRequest);
|
||||
});
|
||||
customFieldIssuesService.editFields(issuesRequest.getId(), issuesRequest.getEditFields());
|
||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
||||
// todo 缺陷更新事件?
|
||||
|
||||
// 删除原来的文件
|
||||
List<FileMetadata> updatedFiles = issuesRequest.getUpdatedFileList();
|
||||
List<FileAttachmentMetadata> originFiles = fileService.getFileAttachmentMetadataByIssueId(issuesRequest.getId());
|
||||
List<String> updatedFileIds = updatedFiles.stream().map(FileMetadata::getId).collect(Collectors.toList());
|
||||
List<String> originFileIds = originFiles.stream().map(FileAttachmentMetadata::getId).collect(Collectors.toList());
|
||||
// 获得差异的附件ID
|
||||
List<String> deleteFileIds = ListUtils.subtract(originFileIds, updatedFileIds);
|
||||
// 删除差异附件记录, 目录下附件文件
|
||||
fileService.deleteAttachment(deleteFileIds);
|
||||
fileService.deleteFileAttachmentByIds(deleteFileIds);
|
||||
//删除用例文件关联记录
|
||||
if (!CollectionUtils.isEmpty(deleteFileIds)) {
|
||||
IssueFileExample issueFileExample = new IssueFileExample();
|
||||
issueFileExample.createCriteria().andFileIdIn(deleteFileIds);
|
||||
issueFileMapper.deleteByExample(issueFileExample);
|
||||
}
|
||||
|
||||
// 保存新的附件
|
||||
if (files != null) {
|
||||
files.forEach(file -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachment(file, AttachmentType.ISSUE.type(), issuesRequest.getId());
|
||||
IssueFile issueFile = new IssueFile();
|
||||
issueFile.setIssueId(issuesRequest.getId());
|
||||
issueFile.setFileId(fileAttachmentMetadata.getId());
|
||||
issueFileMapper.insert(issueFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void saveFollows(String issueId, List<String> follows) {
|
||||
IssueFollowExample example = new IssueFollowExample();
|
||||
example.createCriteria().andIssueIdEqualTo(issueId);
|
||||
|
@ -321,6 +414,16 @@ public class IssuesService {
|
|||
issuesRequest.setWorkspaceId(project.getWorkspaceId());
|
||||
AbstractIssuePlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
|
||||
platform.deleteIssue(id);
|
||||
// 删除缺陷对应的附件
|
||||
IssueFileExample issueFileExample = new IssueFileExample();
|
||||
issueFileExample.createCriteria().andIssueIdEqualTo(id);
|
||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(issueFileExample);
|
||||
List<String> fileIds = issueFiles.stream().map(IssueFile::getFileId).collect(Collectors.toList());
|
||||
FileAttachmentMetadataExample fileAttachmentMetadataExample = new FileAttachmentMetadataExample();
|
||||
fileAttachmentMetadataExample.createCriteria().andIdIn(fileIds);
|
||||
fileAttachmentMetadataMapper.deleteByExample(fileAttachmentMetadataExample);
|
||||
issueFileMapper.deleteByExample(issueFileExample);
|
||||
fileService.deleteAttachment(AttachmentType.ISSUE.type(), id);
|
||||
}
|
||||
|
||||
public IssuesWithBLOBs get(String id) {
|
||||
|
|
|
@ -176,6 +176,8 @@ public class TestCaseService {
|
|||
@Lazy
|
||||
@Resource
|
||||
private TestReviewTestCaseService testReviewTestCaseService;
|
||||
@Resource
|
||||
private FileAttachmentMetadataMapper fileAttachmentMetadataMapper;
|
||||
|
||||
private ThreadLocal<Integer> importCreateNum = new ThreadLocal<>();
|
||||
private ThreadLocal<Integer> beforeImportCreateNum = new ThreadLocal<>();
|
||||
|
@ -607,6 +609,16 @@ public class TestCaseService {
|
|||
deleteFollows(testCaseId);
|
||||
customFieldTestCaseService.deleteByResourceId(testCaseId); // 删除自定义字段关联关系
|
||||
functionCaseExecutionInfoService.deleteBySourceId(testCaseId);
|
||||
// 删除用例附件关联数据, 附件内容
|
||||
TestCaseFileExample testCaseFileExample = new TestCaseFileExample();
|
||||
testCaseFileExample.createCriteria().andCaseIdEqualTo(testCaseId);
|
||||
List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(testCaseFileExample);
|
||||
List<String> fileIds = testCaseFiles.stream().map(TestCaseFile::getFileId).collect(Collectors.toList());
|
||||
FileAttachmentMetadataExample fileAttachmentMetadataExample = new FileAttachmentMetadataExample();
|
||||
fileAttachmentMetadataExample.createCriteria().andIdIn(fileIds);
|
||||
fileAttachmentMetadataMapper.deleteByExample(fileAttachmentMetadataExample);
|
||||
testCaseFileMapper.deleteByExample(testCaseFileExample);
|
||||
fileService.deleteAttachment(AttachmentType.TEST_CASE.type(), testCaseId);
|
||||
return testCaseMapper.deleteByPrimaryKey(testCaseId);
|
||||
}
|
||||
|
||||
|
@ -1958,6 +1970,39 @@ public class TestCaseService {
|
|||
return testCaseWithBLOBs;
|
||||
}
|
||||
|
||||
public TestCase refactorSave(EditTestCaseRequest request, List<MultipartFile> files) {
|
||||
final TestCaseWithBLOBs testCaseWithBLOBs = addTestCase(request);
|
||||
|
||||
// 复制用例时复制对应附件数据
|
||||
if (StringUtils.isNotEmpty(request.getCopyCaseId())) {
|
||||
TestCaseFileExample example = new TestCaseFileExample();
|
||||
example.createCriteria().andCaseIdEqualTo(request.getCopyCaseId());
|
||||
List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(example);
|
||||
if (testCaseFiles != null) {
|
||||
testCaseFiles.forEach(testCaseFile -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.copyAttachment(testCaseFile.getFileId(), AttachmentType.TEST_CASE.type(), testCaseWithBLOBs.getId());
|
||||
TestCaseFile newTestCaseFile = new TestCaseFile();
|
||||
newTestCaseFile.setCaseId(testCaseWithBLOBs.getId());
|
||||
newTestCaseFile.setFileId(fileAttachmentMetadata.getId());
|
||||
testCaseFileMapper.insert(newTestCaseFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 新的附件
|
||||
if (files != null) {
|
||||
files.forEach(file -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachment(file, AttachmentType.TEST_CASE.type(), request.getId());
|
||||
TestCaseFile testCaseFile = new TestCaseFile();
|
||||
testCaseFile.setFileId(fileAttachmentMetadata.getId());
|
||||
testCaseFile.setCaseId(request.getId());
|
||||
testCaseFileMapper.insert(testCaseFile);
|
||||
});
|
||||
}
|
||||
|
||||
return testCaseWithBLOBs;
|
||||
}
|
||||
|
||||
public TestCase edit(EditTestCaseRequest request, List<MultipartFile> files) {
|
||||
TestCaseWithBLOBs testCaseWithBLOBs = testCaseMapper.selectByPrimaryKey(request.getId());
|
||||
request.setNum(testCaseWithBLOBs.getNum());
|
||||
|
@ -1996,6 +2041,47 @@ public class TestCaseService {
|
|||
return editTestCase(request);
|
||||
}
|
||||
|
||||
public TestCase refactorEdit(EditTestCaseRequest request, List<MultipartFile> files) {
|
||||
TestCaseWithBLOBs testCaseWithBLOBs = testCaseMapper.selectByPrimaryKey(request.getId());
|
||||
request.setNum(testCaseWithBLOBs.getNum());
|
||||
if (testCaseWithBLOBs == null) {
|
||||
MSException.throwException(Translator.get("edit_load_test_not_found") + request.getId());
|
||||
}
|
||||
|
||||
if (BooleanUtils.isTrue(request.isHandleAttachment())) {
|
||||
// 新选择了一个文件,删除原来的文件
|
||||
List<FileMetadata> updatedFiles = request.getUpdatedFileList();
|
||||
List<FileAttachmentMetadata> originFiles = fileService.getFileAttachmentMetadataByCaseId(request.getId());
|
||||
List<String> updatedFileIds = updatedFiles.stream().map(FileMetadata::getId).collect(Collectors.toList());
|
||||
List<String> originFileIds = originFiles.stream().map(FileAttachmentMetadata::getId).collect(Collectors.toList());
|
||||
// 获得差异的附件ID
|
||||
List<String> deleteFileIds = ListUtils.subtract(originFileIds, updatedFileIds);
|
||||
// 删除差异附件记录, 目录下附件文件
|
||||
fileService.deleteAttachment(deleteFileIds);
|
||||
fileService.deleteFileAttachmentByIds(deleteFileIds);
|
||||
//删除用例文件关联记录
|
||||
if (!CollectionUtils.isEmpty(deleteFileIds)) {
|
||||
TestCaseFileExample testCaseFileExample = new TestCaseFileExample();
|
||||
testCaseFileExample.createCriteria().andFileIdIn(deleteFileIds);
|
||||
testCaseFileMapper.deleteByExample(testCaseFileExample);
|
||||
}
|
||||
|
||||
// 保存新的附件
|
||||
if (files != null) {
|
||||
files.forEach(file -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachment(file, AttachmentType.TEST_CASE.type(), request.getId());
|
||||
TestCaseFile testCaseFile = new TestCaseFile();
|
||||
testCaseFile.setFileId(fileAttachmentMetadata.getId());
|
||||
testCaseFile.setCaseId(request.getId());
|
||||
testCaseFileMapper.insert(testCaseFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.setNode(request);
|
||||
return editTestCase(request);
|
||||
}
|
||||
|
||||
public String editTestCase(EditTestCaseRequest request, List<MultipartFile> files) {
|
||||
String testCaseId = testPlanTestCaseMapper.selectByPrimaryKey(request.getId()).getCaseId();
|
||||
request.setId(testCaseId);
|
||||
|
@ -2505,6 +2591,45 @@ public class TestCaseService {
|
|||
extTestCaseMapper::getIdsOrderByUpdateTime);
|
||||
}
|
||||
|
||||
public void initAttachment() {
|
||||
TestCaseFileExample example = new TestCaseFileExample();
|
||||
List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(example);
|
||||
List<FileMetadata> allFileMeta = fileService.getAllFileMeta();
|
||||
List<FileContent> allFileContent = fileService.getAllFileContent();
|
||||
Map<String, List<TestCaseFile>> testCaseFileGroup = testCaseFiles.stream().collect(Collectors.groupingBy(TestCaseFile::getCaseId));
|
||||
for(Map.Entry<String, List<TestCaseFile>> entry : testCaseFileGroup.entrySet()) {
|
||||
final String caseId = entry.getKey();
|
||||
final String uploadPath = FileUtils.ATTACHMENT_DIR + "/" + AttachmentType.TEST_CASE.type() + "/" + caseId;
|
||||
entry.getValue().stream().forEach(testCaseFile -> {
|
||||
String filename = "";
|
||||
List<FileMetadata> fileMetadatas = allFileMeta.stream().filter(fileMetadata -> fileMetadata.getId().equals(testCaseFile.getFileId()))
|
||||
.collect(Collectors.toList());
|
||||
List<FileContent> fileContents = allFileContent.stream().filter(fileContent -> fileContent.getFileId().equals(testCaseFile.getFileId()))
|
||||
.collect(Collectors.toList());
|
||||
if (fileMetadatas.size() == 1) {
|
||||
FileMetadata fileMetadata = fileMetadatas.get(0);
|
||||
filename = fileMetadata.getName();
|
||||
FileAttachmentMetadata fileAttachmentMetadata = new FileAttachmentMetadata();
|
||||
BeanUtils.copyBean(fileAttachmentMetadata, fileMetadata);
|
||||
fileAttachmentMetadata.setId(UUID.randomUUID().toString());
|
||||
fileAttachmentMetadata.setCreator("");
|
||||
fileAttachmentMetadata.setFilePath(uploadPath);
|
||||
fileAttachmentMetadataMapper.insert(fileAttachmentMetadata);
|
||||
TestCaseFile newTestCaseFile = new TestCaseFile();
|
||||
newTestCaseFile.setFileId(fileAttachmentMetadata.getId());
|
||||
TestCaseFileExample testCaseFileExample = new TestCaseFileExample();
|
||||
testCaseFileExample.createCriteria().andCaseIdEqualTo(testCaseFile.getCaseId()).andFileIdEqualTo(testCaseFile.getFileId());
|
||||
testCaseFileMapper.updateByExampleSelective(newTestCaseFile, testCaseFileExample);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(filename) && fileContents.size() == 1) {
|
||||
byte[] bytes = fileContents.get(0).getFile();
|
||||
FileUtils.byteToFile(bytes, uploadPath, filename);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 用例自定义排序
|
||||
*
|
||||
|
|
|
@ -6,16 +6,26 @@
|
|||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('load_test.file_name')">
|
||||
<template v-slot:default="scope">
|
||||
<el-tooltip class="item" effect="dark" :content="scope.row.name" placement="top">
|
||||
<el-progress
|
||||
:color="scope.row.percentage >= 100 ? '' : uploadProgressColor"
|
||||
type="line"
|
||||
:format="clearPercentage(scope.row)"
|
||||
:stroke-width="40"
|
||||
:text-inside="true"
|
||||
:percentage="scope.row.percentage >= 100 ? 100 : scope.row.percentage"
|
||||
></el-progress>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="size"
|
||||
:width="100"
|
||||
:label="$t('load_test.file_size')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="type"
|
||||
:label="$t('load_test.file_type')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:width="200"
|
||||
:label="$t('test_track.case.upload_time')">
|
||||
<template v-slot:default="scope">
|
||||
<i class="el-icon-time"/>
|
||||
|
@ -23,18 +33,36 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="status"
|
||||
:width="70"
|
||||
:label="$t('commons.status')">
|
||||
<template v-slot:default="scope">
|
||||
<span :class="scope.row.status === '完成' ? 'green' : scope.row.status === '失败' ? 'red' : ''">{{ scope.row.status | formatProgressPercentage}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="creator"
|
||||
:width="120"
|
||||
:label="$t('group.operator')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:width="140"
|
||||
:label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button @click="preview(scope.row)" :disabled="!scope.row.id" type="primary"
|
||||
v-if="isPreview(scope.row)"
|
||||
icon="el-icon-view"
|
||||
size="mini" circle/>
|
||||
v-if="scope.row.percentage === 100 && isPreview(scope.row)"
|
||||
icon="el-icon-view" size="mini" circle/>
|
||||
<el-button @click="handleDownload(scope.row)" type="primary" :disabled="!scope.row.id"
|
||||
icon="el-icon-download"
|
||||
size="mini" circle/>
|
||||
<el-button :disabled="readOnly || !isDelete" @click="handleDelete(scope.row, scope.$index)" type="danger"
|
||||
v-if="scope.row.percentage === 100"
|
||||
icon="el-icon-download" size="mini" circle/>
|
||||
<el-button :disabled="readOnly || !isDelete || isCopy" @click="handleDelete(scope.row, scope.$index)" type="danger"
|
||||
v-if="scope.row.percentage === 100"
|
||||
icon="el-icon-delete" size="mini"
|
||||
circle/>
|
||||
<el-button :disabled="readOnly || !isDelete" @click="handleCancel(scope.row, scope.$index)" type="danger"
|
||||
v-if="scope.row.percentage < 100"
|
||||
icon="el-icon-close" size="mini"
|
||||
circle/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -62,13 +90,23 @@ export default {
|
|||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isCopy: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
uploadProgressColor: '#d4f6d4',
|
||||
uploadSuccessColor: '#FFFFFF'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clearPercentage(row) {
|
||||
return () => {
|
||||
return row.name;
|
||||
}
|
||||
},
|
||||
preview(row) {
|
||||
this.$refs.testCaseFile.open(row);
|
||||
},
|
||||
|
@ -82,7 +120,7 @@ export default {
|
|||
id: file.id,
|
||||
};
|
||||
let config = {
|
||||
url: '/test/case/file/download',
|
||||
url: '/test/case/attachment/download',
|
||||
method: 'post',
|
||||
data: data,
|
||||
responseType: 'blob'
|
||||
|
@ -109,10 +147,43 @@ export default {
|
|||
handleDelete(file, index) {
|
||||
this.$emit("handleDelete", file, index);
|
||||
},
|
||||
handleCancel(file, index) {
|
||||
this.$emit("handleCancel", file, index);
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
formatProgressPercentage(percentage) {
|
||||
if (isNaN(percentage)) {
|
||||
return percentage
|
||||
}
|
||||
return Math.floor(percentage * 100 / 100) + "%";
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-progress-bar__innerText {
|
||||
color: black;
|
||||
}
|
||||
|
||||
::v-deep .el-progress-bar__outer,
|
||||
::v-deep .el-progress-bar__inner {
|
||||
border-radius: inherit ;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
::v-deep .el-progress-bar__innerText {
|
||||
float: left;
|
||||
color: #606266;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.green {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
|
||||
<test-case-edit-other-info :read-only="readOnly" :project-id="projectIds" :form="form"
|
||||
:is-copy="currentTestCaseInfo.isCopy"
|
||||
:copy-case-id="copyCaseId"
|
||||
:label-width="formLabelWidth" :case-id="form.id"
|
||||
:type="type" :comments.sync="comments"
|
||||
@openComment="openComment"
|
||||
|
@ -141,6 +142,7 @@
|
|||
import {TokenKey} from '@/common/js/constants';
|
||||
import MsDialogFooter from '../../../common/components/MsDialogFooter';
|
||||
import {
|
||||
byteToSize,
|
||||
getCurrentProjectID,
|
||||
getCurrentUser,
|
||||
getNodePath,
|
||||
|
@ -287,6 +289,7 @@ export default {
|
|||
{value: 'manual', label: this.$t('test_track.case.manual')}
|
||||
],
|
||||
testCase: {},
|
||||
copyCaseId: "",
|
||||
showInputTag: true,
|
||||
tableType: "",
|
||||
stepFilter: new STEP,
|
||||
|
@ -302,7 +305,7 @@ export default {
|
|||
selectedOtherInfo: null,
|
||||
currentProjectId: "",
|
||||
casePublic: false,
|
||||
isClickAttachmentTab: false,
|
||||
isClickAttachmentTab: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -599,10 +602,12 @@ export default {
|
|||
if (testCase) {
|
||||
//修改
|
||||
this.operationType = 'edit';
|
||||
this.copyCaseId = '';
|
||||
//复制
|
||||
if (this.type === 'copy') {
|
||||
this.showInputTag = false;
|
||||
this.operationType = 'add';
|
||||
this.copyCaseId = testCase.copyId;
|
||||
this.setFormData(testCase);
|
||||
this.setTestCaseExtInfo(testCase);
|
||||
this.getSelectOptions();
|
||||
|
@ -623,6 +628,7 @@ export default {
|
|||
}
|
||||
}
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
this.copyCaseId = '';
|
||||
this.form.priority = 'P3';
|
||||
this.form.type = 'functional';
|
||||
this.form.method = 'manual';
|
||||
|
@ -776,6 +782,7 @@ export default {
|
|||
Object.assign(param, this.form);
|
||||
param.steps = JSON.stringify(this.form.steps);
|
||||
param.nodeId = this.form.module;
|
||||
param.copyCaseId = this.copyCaseId
|
||||
if (!this.publicEnable) {
|
||||
param.nodePath = getNodePath(this.form.module, this.moduleOptions);
|
||||
if (this.projectId) {
|
||||
|
|
|
@ -55,29 +55,31 @@
|
|||
|
||||
<el-tab-pane :label="$t('test_track.case.attachment')" name="attachment">
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="1">
|
||||
<el-col :span="22">
|
||||
<el-upload
|
||||
accept=".jpg,.jpeg,.png,.xlsx,.doc,.pdf,.docx,.txt,.json,.jmx,.side"
|
||||
action=""
|
||||
accept=".jpg,.jpeg,.png,.xlsx,.doc,.pdf,.docx,.txt,.json,.jmx,.side,.mp4,.mov,.dcm,.zip,.rar"
|
||||
action="#"
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeUpload"
|
||||
:http-request="handleUpload"
|
||||
:on-exceed="handleExceed"
|
||||
multiple
|
||||
:limit="8"
|
||||
:disabled="readOnly && !isTestPlanEdit"
|
||||
:disabled="readOnly && isTestPlanEdit"
|
||||
:file-list="fileList">
|
||||
<el-button icon="el-icon-plus" :disabled="readOnly && !isTestPlanEdit" size="mini"></el-button>
|
||||
<el-button :disabled="readOnly && isTestPlanEdit" type="primary" size="mini">{{$t('test_track.case.add_attachment')}}</el-button>
|
||||
<span slot="tip" class="el-upload__tip"> {{ $t('test_track.case.upload_tip') }} </span>
|
||||
</el-upload>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="19" :offset="2">
|
||||
<el-col :span="22">
|
||||
<test-case-attachment :table-data="tableData"
|
||||
:read-only="readOnly"
|
||||
:is-copy="isCopy"
|
||||
:is-delete="!isTestPlan"
|
||||
@handleDelete="handleDelete"/>
|
||||
@handleDelete="handleDelete"
|
||||
@handleCancel="handleCancel"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
|
@ -128,6 +130,8 @@ import TabPaneCount from "@/business/components/track/plan/view/comonents/report
|
|||
import {getRelationshipCountCase} from "@/network/testCase";
|
||||
import TestCaseComment from "@/business/components/track/case/components/TestCaseComment";
|
||||
import ReviewCommentItem from "@/business/components/track/review/commom/ReviewCommentItem";
|
||||
import {byteToSize} from "@/common/js/utils";
|
||||
import {TokenKey} from "@/common/js/constants";
|
||||
|
||||
export default {
|
||||
name: "TestCaseEditOtherInfo",
|
||||
|
@ -139,7 +143,7 @@ export default {
|
|||
ReviewCommentItem,
|
||||
FormRichTextItem, TestCaseIssueRelate, TestCaseAttachment, MsRichText, TestCaseRichText
|
||||
},
|
||||
props: ['form', 'labelWidth', 'caseId', 'readOnly', 'projectId', 'isTestPlan', 'planId', 'versionEnable', 'isCopy', 'isTestPlanEdit',
|
||||
props: ['form', 'labelWidth', 'caseId', 'readOnly', 'projectId', 'isTestPlan', 'planId', 'versionEnable', 'isCopy', 'copyCaseId', 'isTestPlanEdit',
|
||||
'type', 'comments', 'isClickAttachmentTab',
|
||||
'defaultOpen'
|
||||
],
|
||||
|
@ -159,6 +163,7 @@ export default {
|
|||
//lazy: true,
|
||||
//lazyLoad:this.lazyLoad
|
||||
},
|
||||
intervalMap: new Map()
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -236,15 +241,17 @@ export default {
|
|||
return false;
|
||||
}
|
||||
|
||||
let type = file.name.substring(file.name.lastIndexOf(".") + 1);
|
||||
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
this.tableData.push({
|
||||
name: file.name,
|
||||
size: file.size + ' Bytes', /// todo: 按照大小显示Byte、KB、MB等
|
||||
type: type.toUpperCase(),
|
||||
size: byteToSize(file.size),
|
||||
updateTime: new Date().getTime(),
|
||||
percentage: 0,
|
||||
status: 0,
|
||||
creator: user.name
|
||||
});
|
||||
|
||||
this.handleProcess(file);
|
||||
return true;
|
||||
},
|
||||
handleUpload(uploadResources) {
|
||||
|
@ -290,6 +297,17 @@ export default {
|
|||
}
|
||||
});
|
||||
},
|
||||
handleCancel(file, index) {
|
||||
this.fileList.splice(index, 1);
|
||||
let i = this.uploadList.findIndex(upLoadFile => upLoadFile.name === file.name);
|
||||
if (i > -1) {
|
||||
this.uploadList.splice(i, 1);
|
||||
}
|
||||
let cancelFile = this.tableData.filter(f => f.name === file.name)[0];
|
||||
clearInterval(this.intervalMap.get(cancelFile.name));
|
||||
cancelFile.percentage = 100;
|
||||
cancelFile.status = this.$t('notice.result.EXECUTE_FAILED');
|
||||
},
|
||||
_handleDelete(file, index) {
|
||||
this.fileList.splice(index, 1);
|
||||
this.tableData.splice(index, 1);
|
||||
|
@ -301,6 +319,21 @@ export default {
|
|||
handleExceed() {
|
||||
this.$error(this.$t('load_test.file_size_limit'));
|
||||
},
|
||||
handleProcess(file) {
|
||||
let currentUploadFile = this.tableData.filter(f => f.name === file.name)[0];
|
||||
const interval = setInterval(() => {
|
||||
let randomNum = Math.floor(Math.random() * 10);
|
||||
if (currentUploadFile.percentage + randomNum > 100) {
|
||||
clearInterval(interval)
|
||||
currentUploadFile.percentage = 100;
|
||||
currentUploadFile.status = this.$t('notice.result.EXECUTE_COMPLETED')
|
||||
return
|
||||
}
|
||||
currentUploadFile.percentage += randomNum;
|
||||
currentUploadFile.status += randomNum;
|
||||
}, file.size > 1024 * 1024 ? 200 : 100)
|
||||
this.intervalMap.set(currentUploadFile.name, interval);
|
||||
},
|
||||
getFileMetaData(id) {
|
||||
this.$emit("update:isClickAttachmentTab", true);
|
||||
// 保存用例后传入用例id,刷新文件列表,可以预览和下载
|
||||
|
@ -310,9 +343,14 @@ export default {
|
|||
this.fileList = [];
|
||||
this.tableData = [];
|
||||
this.uploadList = [];
|
||||
let testCaseId = id ? id : this.caseId;
|
||||
let testCaseId;
|
||||
if (this.isCopy) {
|
||||
testCaseId = this.copyCaseId
|
||||
} else {
|
||||
testCaseId = id ? id : this.caseId;
|
||||
}
|
||||
if (testCaseId) {
|
||||
this.result = this.$get("test/case/file/metadata/" + testCaseId, response => {
|
||||
this.result = this.$get("test/case/file/attachmentMetadata/" + testCaseId, response => {
|
||||
let files = response.data;
|
||||
|
||||
if (!files) {
|
||||
|
@ -322,7 +360,9 @@ export default {
|
|||
this.fileList = JSON.parse(JSON.stringify(files));
|
||||
this.tableData = JSON.parse(JSON.stringify(files));
|
||||
this.tableData.map(f => {
|
||||
f.size = f.size + ' Bytes';
|
||||
f.size = byteToSize(f.size);
|
||||
f.status = this.$t('notice.result.EXECUTE_COMPLETED');
|
||||
f.percentage = 100
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogVisible" width="80%" :destroy-on-close="true" :before-close="close" :append-to-body="true">
|
||||
<div>
|
||||
<img :src="'/test/case/file/preview/' + file.id" :alt="$t('test_track.case.img_loading_fail')" style="width: 100%;height: 100%;"
|
||||
<img :src="'/test/case/attachment/preview/' + file.id" :alt="$t('test_track.case.img_loading_fail')" style="width: 100%;height: 100%;"
|
||||
v-if="file.type === 'JPG' || file.type === 'JPEG' || file.type === 'PNG'">
|
||||
<div v-if="file.type === 'PDF'">
|
||||
<test-case-pdf :file-id="file.id"/>
|
||||
|
|
|
@ -900,6 +900,7 @@ export default {
|
|||
let testCase = response.data;
|
||||
testCase.name = 'copy_' + testCase.name;
|
||||
//复制的时候只复制当前版本
|
||||
testCase.copyId = testCase.id;
|
||||
testCase.id = getUUID();
|
||||
testCase.refId = null;
|
||||
testCase.versionId = null;
|
||||
|
|
|
@ -21,7 +21,7 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.loading = true;
|
||||
this.loadingTask = pdf.createLoadingTask("/test/case/file/preview/" + this.fileId);
|
||||
this.loadingTask = pdf.createLoadingTask("/test/case/attachment/preview/" + this.fileId);
|
||||
this.loadingTask.promise.then(pdf => {
|
||||
this.numPages = pdf.numPages
|
||||
this.loading = false;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<el-scrollbar>
|
||||
<el-form :model="form" :rules="rules" label-position="right" label-width="80px" ref="form">
|
||||
|
||||
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
||||
<el-form-item v-if="!enableThirdPartTemplate" :label="$t('commons.title')" prop="title">
|
||||
<el-row>
|
||||
<el-col :span="22">
|
||||
|
@ -89,35 +90,87 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item v-if="!isCaseEdit">
|
||||
<test-case-issue-list :issues-id="form.id"
|
||||
ref="testCaseIssueList"/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- <form-rich-text-item :title="$t('commons.remark')" :data="form" prop="remark"/>-->
|
||||
|
||||
<el-row style="margin-top: 10px" v-if="type!=='add'">
|
||||
<el-col :span="20" :offset="1">{{ $t('test_track.review.comment') }}:
|
||||
<el-button icon="el-icon-plus" type="mini" @click="openComment"></el-button>
|
||||
<el-row class="other-info-rows" style="margin-top: 20px">
|
||||
<el-col :span="2">
|
||||
<ms-form-divider :title="$t('test_track.case.other_info')"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="1">
|
||||
<el-col :span="22">
|
||||
<el-tabs class="other-info-tabs" v-loading="result.loading" v-model="tabActiveName">
|
||||
<el-tab-pane :label="$t('test_track.review_view.relevance_case')" name="relateTestCase">
|
||||
<el-form-item v-if="!isCaseEdit" style="margin-left: -80px">
|
||||
<test-case-issue-list :issues-id="form.id"
|
||||
ref="testCaseIssueList"/>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
|
||||
<review-comment-item v-for="(comment,index) in comments"
|
||||
:key="index"
|
||||
:comment="comment"
|
||||
@refresh="getComments" api-url="/issues"/>
|
||||
<div v-if="comments.length === 0" style="text-align: center">
|
||||
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
|
||||
<el-tab-pane :label="$t('test_track.case.attachment')" name="attachment">
|
||||
<el-row>
|
||||
<el-col :span="22">
|
||||
<el-upload
|
||||
accept=".jpg,.jpeg,.png,.xlsx,.doc,.pdf,.docx,.txt,.json,.jmx,.side,.mp4,.mov,.dcm,.zip,.rar"
|
||||
action="#"
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeUpload"
|
||||
:http-request="handleUpload"
|
||||
:on-exceed="handleExceed"
|
||||
multiple
|
||||
:limit="8"
|
||||
:file-list="fileList">
|
||||
<el-button type="primary" size="mini">{{$t('test_track.case.add_attachment')}}</el-button>
|
||||
<span slot="tip" class="el-upload__tip"> {{ $t('test_track.case.upload_tip') }} </span>
|
||||
</el-upload>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 10px">
|
||||
<el-col :span="22">
|
||||
<test-case-attachment :table-data="tableData"
|
||||
:read-only="readOnly"
|
||||
:is-delete="isDelete"
|
||||
:is-copy="type === 'copy'"
|
||||
@handleDelete="handleDelete"
|
||||
@handleCancel="handleCancel"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('test_track.review.comment')" name="comment">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('test_track.review.comment')" placement="top-start"
|
||||
slot="label">
|
||||
<span>
|
||||
{{ $t('test_track.review.comment') }}
|
||||
<div class="el-step__icon is-text ms-api-col ms-header" v-if="comments && comments.length>0">
|
||||
<div class="el-step__icon-inner">{{ comments.length }}</div>
|
||||
</div>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<el-row style="margin-top: 10px" v-if="type!=='add'">
|
||||
<el-col :span="20" :offset="1">{{ $t('test_track.review.comment') }}:
|
||||
<el-button icon="el-icon-plus" type="mini" @click="openComment"></el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 10px">
|
||||
<el-col :span="20" :offset="1">
|
||||
|
||||
<review-comment-item v-for="(comment,index) in comments"
|
||||
:key="index"
|
||||
:comment="comment"
|
||||
@refresh="getComments" api-url="/issues"/>
|
||||
<div v-if="comments.length === 0" style="text-align: center">
|
||||
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
|
||||
<span style="font-size: 15px; color: #8a8b8d;">
|
||||
{{ $t('test_track.comment.no_comment') }}
|
||||
</span>
|
||||
</i>
|
||||
</div>
|
||||
</i>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- <form-rich-text-item :title="$t('commons.remark')" :data="form" prop="remark"/>-->
|
||||
|
||||
<issue-comment :issues-id="form.id"
|
||||
@getComments="getComments"
|
||||
ref="issueComment"/>
|
||||
|
@ -139,13 +192,21 @@ import {buildCustomFields, parseCustomField} from "@/common/js/custom_field";
|
|||
import CustomFiledComponent from "@/business/components/project/template/CustomFiledComponent";
|
||||
import TestCaseIssueList from "@/business/components/track/issue/TestCaseIssueList";
|
||||
import IssueEditDetail from "@/business/components/track/issue/IssueEditDetail";
|
||||
import {getCurrentProjectID, getCurrentUser, getCurrentUserId, getCurrentWorkspaceId,} from "@/common/js/utils";
|
||||
import {
|
||||
byteToSize,
|
||||
getCurrentProjectID,
|
||||
getCurrentUser,
|
||||
getCurrentUserId,
|
||||
getCurrentWorkspaceId,
|
||||
} from "@/common/js/utils";
|
||||
import {enableThirdPartTemplate, getIssuePartTemplateWithProject, getPlatformTransitions} from "@/network/Issue";
|
||||
import CustomFiledFormItem from "@/business/components/common/components/form/CustomFiledFormItem";
|
||||
import MsMarkDownText from "@/business/components/track/case/components/MsMarkDownText";
|
||||
import IssueComment from "@/business/components/track/issue/IssueComment";
|
||||
import ReviewCommentItem from "@/business/components/track/review/commom/ReviewCommentItem";
|
||||
import {JIRA} from "@/common/js/constants";
|
||||
import {TokenKey} from "@/common/js/constants";
|
||||
import {Message} from "element-ui";
|
||||
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
||||
|
||||
const {getIssuesById} = require("@/network/Issue");
|
||||
|
||||
|
@ -163,7 +224,8 @@ export default {
|
|||
TemplateComponentEditHeader,
|
||||
MsMarkDownText,
|
||||
IssueComment,
|
||||
ReviewCommentItem
|
||||
ReviewCommentItem,
|
||||
TestCaseAttachment
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -196,7 +258,8 @@ export default {
|
|||
tapdUsers:[],
|
||||
zentaoBuilds:[],
|
||||
zentaoAssigned: '',
|
||||
platformStatus: null
|
||||
platformStatus: null,
|
||||
copyIssueId: ''
|
||||
},
|
||||
tapdUsers: [],
|
||||
zentaoUsers: [],
|
||||
|
@ -241,7 +304,14 @@ export default {
|
|||
preview: false, // 预览
|
||||
},
|
||||
comments: [],
|
||||
richTextDefaultOpen: 'preview'
|
||||
richTextDefaultOpen: 'preview',
|
||||
tabActiveName: 'relateTestCase',
|
||||
uploadList: [],
|
||||
fileList: [],
|
||||
tableData: [],
|
||||
readOnly: false,
|
||||
isDelete: true,
|
||||
intervalMap: new Map()
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -368,6 +438,9 @@ export default {
|
|||
}
|
||||
},
|
||||
initEdit(data) {
|
||||
this.tableData = [];
|
||||
this.fileList = [];
|
||||
this.uploadList = [];
|
||||
if (data) {
|
||||
Object.assign(this.form, data);
|
||||
if (!(data.options instanceof Array)) {
|
||||
|
@ -383,6 +456,7 @@ export default {
|
|||
this.form.creator = getCurrentUserId();
|
||||
}
|
||||
this.form.title = data.title + '_copy';
|
||||
this.form.copyIssueId = data.copyIssueId;
|
||||
}
|
||||
} else {
|
||||
this.form = {
|
||||
|
@ -400,6 +474,11 @@ export default {
|
|||
if (this.$refs.testCaseIssueList) {
|
||||
this.$refs.testCaseIssueList.initTableData();
|
||||
}
|
||||
if (this.type === 'copy' && data.copyIssueId != null) {
|
||||
this.getFileMetaData(data.copyIssueId);
|
||||
} else if (this.type === 'edit' && data.id != null) {
|
||||
this.getFileMetaData(data.id);
|
||||
}
|
||||
this.getComments();
|
||||
});
|
||||
},
|
||||
|
@ -465,7 +544,8 @@ export default {
|
|||
_save() {
|
||||
let param = this.buildPram();
|
||||
this.parseOldFields(param);
|
||||
this.result = this.$post(this.url, param, (response) => {
|
||||
let option = this.getOption(param);
|
||||
this.result = this.$request(option, (response) => {
|
||||
this.$emit('close');
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$emit('refresh', response.data);
|
||||
|
@ -482,6 +562,39 @@ export default {
|
|||
});
|
||||
}
|
||||
},
|
||||
getOption(param) {
|
||||
let formData = new FormData();
|
||||
|
||||
if (this.uploadList) {
|
||||
this.uploadList.forEach(f => {
|
||||
formData.append("file", f);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.fileList) {
|
||||
// 如果是copy,则把文件的ID传到后台进行文件复制 TODO
|
||||
param.updatedFileList = this.fileList;
|
||||
} else {
|
||||
param.fileIds = [];
|
||||
param.updatedFileList = [];
|
||||
}
|
||||
|
||||
let requestJson = JSON.stringify(param, function (key, value) {
|
||||
return key === "file" ? undefined : value
|
||||
});
|
||||
|
||||
formData.append('request', new Blob([requestJson], {
|
||||
type: "application/json"
|
||||
}));
|
||||
return {
|
||||
method: 'POST',
|
||||
url: this.url,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': undefined
|
||||
}
|
||||
};
|
||||
},
|
||||
saveFollow(){
|
||||
if(!this.form.follows){
|
||||
this.form.follows = [];
|
||||
|
@ -513,6 +626,139 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
fileValidator(file) {
|
||||
/// todo: 是否需要对文件内容和大小做限制
|
||||
return file.size > 0;
|
||||
},
|
||||
beforeUpload(file) {
|
||||
if (!this.fileValidator(file)) {
|
||||
/// todo: 显示错误信息
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.tableData.filter(f => f.name === file.name).length > 0) {
|
||||
this.$error(this.$t('load_test.delete_file') + ', name: ' + file.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
this.tableData.push({
|
||||
name: file.name,
|
||||
size: byteToSize(file.size),
|
||||
updateTime: new Date().getTime(),
|
||||
percentage: 0,
|
||||
status: 0,
|
||||
creator: user.name
|
||||
});
|
||||
|
||||
this.handleProcess(file);
|
||||
return true;
|
||||
},
|
||||
handleUpload(uploadResources) {
|
||||
this.uploadList.push(uploadResources.file);
|
||||
},
|
||||
handleDownload(file) {
|
||||
let data = {
|
||||
name: file.name,
|
||||
id: file.id,
|
||||
};
|
||||
let config = {
|
||||
url: '/test/case/file/download',
|
||||
method: 'post',
|
||||
data: data,
|
||||
responseType: 'blob'
|
||||
};
|
||||
this.result = this.$request(config).then(response => {
|
||||
const content = response.data;
|
||||
const blob = new Blob([content]);
|
||||
if ("download" in document.createElement("a")) {
|
||||
// 非IE下载
|
||||
// chrome/firefox
|
||||
let aTag = document.createElement('a');
|
||||
aTag.download = file.name;
|
||||
aTag.href = URL.createObjectURL(blob);
|
||||
aTag.click();
|
||||
URL.revokeObjectURL(aTag.href);
|
||||
} else {
|
||||
// IE10+下载
|
||||
navigator.msSaveBlob(blob, this.filename);
|
||||
}
|
||||
}).catch(e => {
|
||||
Message.error({message: e.message, showClose: true});
|
||||
});
|
||||
},
|
||||
handleDelete(file, index) {
|
||||
this.$alert(this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this._handleDelete(file, index);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleCancel(file, index) {
|
||||
this.fileList.splice(index, 1);
|
||||
let i = this.uploadList.findIndex(upLoadFile => upLoadFile.name === file.name);
|
||||
if (i > -1) {
|
||||
this.uploadList.splice(i, 1);
|
||||
}
|
||||
let cancelFile = this.tableData.filter(f => f.name === file.name)[0];
|
||||
clearInterval(this.intervalMap.get(cancelFile.name));
|
||||
cancelFile.percentage = 100;
|
||||
cancelFile.status = this.$t('notice.result.EXECUTE_FAILED');
|
||||
},
|
||||
_handleDelete(file, index) {
|
||||
this.fileList.splice(index, 1);
|
||||
this.tableData.splice(index, 1);
|
||||
let i = this.uploadList.findIndex(upLoadFile => upLoadFile.name === file.name);
|
||||
if (i > -1) {
|
||||
this.uploadList.splice(i, 1);
|
||||
}
|
||||
},
|
||||
handleExceed() {
|
||||
this.$error(this.$t('load_test.file_size_limit'));
|
||||
},
|
||||
handleProcess(file) {
|
||||
let currentUploadFile = this.tableData.filter(f => f.name === file.name)[0];
|
||||
const interval = setInterval(() => {
|
||||
let randomNum = Math.floor(Math.random() * 10);
|
||||
if (currentUploadFile.percentage + randomNum > 100) {
|
||||
clearInterval(interval)
|
||||
currentUploadFile.percentage = 100;
|
||||
currentUploadFile.status = this.$t('notice.result.EXECUTE_COMPLETED')
|
||||
return
|
||||
}
|
||||
currentUploadFile.percentage += randomNum;
|
||||
currentUploadFile.status += randomNum;
|
||||
}, file.size > 1024 * 1024 ? 200 : 100)
|
||||
this.intervalMap.set(currentUploadFile.name, interval);
|
||||
},
|
||||
getFileMetaData(id) {
|
||||
// 保存用例后传入用例id,刷新文件列表,可以预览和下载
|
||||
if (this.uploadList && this.uploadList.length > 0 && !id) {
|
||||
return;
|
||||
}
|
||||
this.fileList = [];
|
||||
this.tableData = [];
|
||||
this.uploadList = [];
|
||||
if (id) {
|
||||
this.result = this.$get("issues/file/attachmentMetadata/" + id, response => {
|
||||
let files = response.data;
|
||||
if (!files) {
|
||||
return;
|
||||
}
|
||||
// deep copy
|
||||
this.fileList = JSON.parse(JSON.stringify(files));
|
||||
this.tableData = JSON.parse(JSON.stringify(files));
|
||||
this.tableData.map(f => {
|
||||
f.size = byteToSize(f.size);
|
||||
f.status = this.$t('notice.result.EXECUTE_COMPLETED');
|
||||
f.percentage = 100
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
openComment() {
|
||||
if (!this.issueId) {
|
||||
this.$warning(this.$t('test_track.issue.save_before_open_comment'));
|
||||
|
@ -532,6 +778,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.other-info-tabs >>> .el-tabs__content {
|
||||
padding: 20px 0px;
|
||||
}
|
||||
|
||||
.top-input-class{
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -543,4 +793,13 @@ export default {
|
|||
.custom-field-row {
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.ms-header {
|
||||
background: #783887;
|
||||
color: white;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
font-size: xx-small;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -359,7 +359,8 @@ export default {
|
|||
},
|
||||
handleCopy(data) {
|
||||
let copyData = {};
|
||||
Object.assign(copyData, data);
|
||||
Object.assign(copyData, data)
|
||||
copyData.copyIssueId = copyData.id
|
||||
copyData.id = null;
|
||||
copyData.name = data.name + '_copy';
|
||||
this.$refs.issueEdit.open(copyData, 'copy');
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-button type="primary" @click="relateTestCase">{{$t('test_track.review_view.relevance_case')}}</el-button>
|
||||
<el-button type="primary" size="small" @click="relateTestCase">{{$t('test_track.review_view.relevance_case')}}</el-button>
|
||||
|
||||
<ms-table
|
||||
v-loading="result.loading"
|
||||
|
|
|
@ -577,3 +577,15 @@ function _resizeTextarea(i, size, textareaList) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function byteToSize(bytes) {
|
||||
if (bytes === 0) {
|
||||
return '0 B';
|
||||
}
|
||||
let k = 1024,
|
||||
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
|
||||
i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
|
|
|
@ -2146,7 +2146,8 @@ export default {
|
|||
cancel_relevance_project: "Disassociating the project will also cancel the associated test cases under the project",
|
||||
img_loading_fail: "Image failed to load",
|
||||
pdf_loading_fail: "PDF loading failed",
|
||||
upload_tip: "Only jpg, jpeg, png, docx, doc, pdf, xlsx, txt, json, jmx, side files can be uploaded",
|
||||
upload_tip: "Only jpg, jpeg, png, docx, doc, pdf, xlsx, txt, json, jmx, side, mp4, mov, dcm, zip, rar files can be uploaded",
|
||||
add_attachment: "Add Attachment",
|
||||
attachment: "Attachment",
|
||||
upload_time: "Upload Time",
|
||||
total: "Total Case",
|
||||
|
|
|
@ -2143,7 +2143,8 @@ export default {
|
|||
cancel_relevance_project: "取消项目关联会同时取消该项目下已关联的测试用例",
|
||||
img_loading_fail: "图片加载失败",
|
||||
pdf_loading_fail: "PDF加载失败",
|
||||
upload_tip: "只能上传jpg、jpeg、png、docx、doc、pdf、xlsx、txt、json、jmx、side文件",
|
||||
upload_tip: "只能上传jpg、jpeg、png、docx、doc、pdf、xlsx、txt、json、jmx、side、mp4、mov、dcm、zip、rar文件",
|
||||
add_attachment: "添加附件",
|
||||
attachment: "附件",
|
||||
upload_time: "上传时间",
|
||||
total: "用例总数",
|
||||
|
|
|
@ -2138,7 +2138,8 @@ export default {
|
|||
cancel_relevance_project: "取消項目關聯會同時取消該項目下已關聯的測試用例",
|
||||
img_loading_fail: "圖片加載失敗",
|
||||
pdf_loading_fail: "PDF加載失敗",
|
||||
upload_tip: "只能上傳jpg、jpeg、png、docx、doc、pdf、xlsx、txt、json、jmx、side文件",
|
||||
upload_tip: "只能上傳jpg、jpeg、png、docx、doc、pdf、xlsx、txt、json、jmx、side、mp4、mov、dcm、zip、rar文件",
|
||||
add_attachment: "添加附件",
|
||||
attachment: "附件",
|
||||
upload_time: "上傳時間",
|
||||
total: "用例總數",
|
||||
|
|
Loading…
Reference in New Issue