refactor(测试跟踪): 附件功能代码优化
--story=1006991 --user=宋昌昌 【测试跟踪】功能用例&缺陷增加附件功能支持视频文件(1.20分支同步上) https://www.tapd.cn/55049933/s/1204166
This commit is contained in:
parent
a89cd8f348
commit
4e5be145de
|
@ -0,0 +1,16 @@
|
||||||
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AttachmentModuleRelation implements Serializable {
|
||||||
|
private String relationId;
|
||||||
|
|
||||||
|
private String relationType;
|
||||||
|
|
||||||
|
private String attachmentId;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -0,0 +1,410 @@
|
||||||
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AttachmentModuleRelationExample {
|
||||||
|
protected String orderByClause;
|
||||||
|
|
||||||
|
protected boolean distinct;
|
||||||
|
|
||||||
|
protected List<Criteria> oredCriteria;
|
||||||
|
|
||||||
|
public AttachmentModuleRelationExample() {
|
||||||
|
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 andRelationIdIsNull() {
|
||||||
|
addCriterion("relation_id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdIsNotNull() {
|
||||||
|
addCriterion("relation_id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdEqualTo(String value) {
|
||||||
|
addCriterion("relation_id =", value, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdNotEqualTo(String value) {
|
||||||
|
addCriterion("relation_id <>", value, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdGreaterThan(String value) {
|
||||||
|
addCriterion("relation_id >", value, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("relation_id >=", value, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdLessThan(String value) {
|
||||||
|
addCriterion("relation_id <", value, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("relation_id <=", value, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdLike(String value) {
|
||||||
|
addCriterion("relation_id like", value, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdNotLike(String value) {
|
||||||
|
addCriterion("relation_id not like", value, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdIn(List<String> values) {
|
||||||
|
addCriterion("relation_id in", values, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdNotIn(List<String> values) {
|
||||||
|
addCriterion("relation_id not in", values, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("relation_id between", value1, value2, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("relation_id not between", value1, value2, "relationId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeIsNull() {
|
||||||
|
addCriterion("relation_type is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeIsNotNull() {
|
||||||
|
addCriterion("relation_type is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeEqualTo(String value) {
|
||||||
|
addCriterion("relation_type =", value, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeNotEqualTo(String value) {
|
||||||
|
addCriterion("relation_type <>", value, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeGreaterThan(String value) {
|
||||||
|
addCriterion("relation_type >", value, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("relation_type >=", value, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeLessThan(String value) {
|
||||||
|
addCriterion("relation_type <", value, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("relation_type <=", value, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeLike(String value) {
|
||||||
|
addCriterion("relation_type like", value, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeNotLike(String value) {
|
||||||
|
addCriterion("relation_type not like", value, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeIn(List<String> values) {
|
||||||
|
addCriterion("relation_type in", values, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeNotIn(List<String> values) {
|
||||||
|
addCriterion("relation_type not in", values, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeBetween(String value1, String value2) {
|
||||||
|
addCriterion("relation_type between", value1, value2, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andRelationTypeNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("relation_type not between", value1, value2, "relationType");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdIsNull() {
|
||||||
|
addCriterion("attachment_id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdIsNotNull() {
|
||||||
|
addCriterion("attachment_id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdEqualTo(String value) {
|
||||||
|
addCriterion("attachment_id =", value, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdNotEqualTo(String value) {
|
||||||
|
addCriterion("attachment_id <>", value, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdGreaterThan(String value) {
|
||||||
|
addCriterion("attachment_id >", value, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("attachment_id >=", value, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdLessThan(String value) {
|
||||||
|
addCriterion("attachment_id <", value, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("attachment_id <=", value, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdLike(String value) {
|
||||||
|
addCriterion("attachment_id like", value, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdNotLike(String value) {
|
||||||
|
addCriterion("attachment_id not like", value, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdIn(List<String> values) {
|
||||||
|
addCriterion("attachment_id in", values, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdNotIn(List<String> values) {
|
||||||
|
addCriterion("attachment_id not in", values, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("attachment_id between", value1, value2, "attachmentId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAttachmentIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("attachment_id not between", value1, value2, "attachmentId");
|
||||||
|
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,23 @@
|
||||||
|
package io.metersphere.base.mapper;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.AttachmentModuleRelation;
|
||||||
|
import io.metersphere.base.domain.AttachmentModuleRelationExample;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface AttachmentModuleRelationMapper {
|
||||||
|
long countByExample(AttachmentModuleRelationExample example);
|
||||||
|
|
||||||
|
int deleteByExample(AttachmentModuleRelationExample example);
|
||||||
|
|
||||||
|
int insert(AttachmentModuleRelation record);
|
||||||
|
|
||||||
|
int insertSelective(AttachmentModuleRelation record);
|
||||||
|
|
||||||
|
List<AttachmentModuleRelation> selectByExample(AttachmentModuleRelationExample example);
|
||||||
|
|
||||||
|
int updateByExampleSelective(@Param("record") AttachmentModuleRelation record, @Param("example") AttachmentModuleRelationExample example);
|
||||||
|
|
||||||
|
int updateByExample(@Param("record") AttachmentModuleRelation record, @Param("example") AttachmentModuleRelationExample example);
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
<?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.AttachmentModuleRelationMapper">
|
||||||
|
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.AttachmentModuleRelation">
|
||||||
|
<result column="relation_id" jdbcType="VARCHAR" property="relationId" />
|
||||||
|
<result column="relation_type" jdbcType="VARCHAR" property="relationType" />
|
||||||
|
<result column="attachment_id" jdbcType="VARCHAR" property="attachmentId" />
|
||||||
|
</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">
|
||||||
|
relation_id, relation_type, attachment_id
|
||||||
|
</sql>
|
||||||
|
<select id="selectByExample" parameterType="io.metersphere.base.domain.AttachmentModuleRelationExample" resultMap="BaseResultMap">
|
||||||
|
select
|
||||||
|
<if test="distinct">
|
||||||
|
distinct
|
||||||
|
</if>
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
from attachment_module_relation
|
||||||
|
<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.AttachmentModuleRelationExample">
|
||||||
|
delete from attachment_module_relation
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</delete>
|
||||||
|
<insert id="insert" parameterType="io.metersphere.base.domain.AttachmentModuleRelation">
|
||||||
|
insert into attachment_module_relation (relation_id, relation_type, attachment_id
|
||||||
|
)
|
||||||
|
values (#{relationId,jdbcType=VARCHAR}, #{relationType,jdbcType=VARCHAR}, #{attachmentId,jdbcType=VARCHAR}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.AttachmentModuleRelation">
|
||||||
|
insert into attachment_module_relation
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="relationId != null">
|
||||||
|
relation_id,
|
||||||
|
</if>
|
||||||
|
<if test="relationType != null">
|
||||||
|
relation_type,
|
||||||
|
</if>
|
||||||
|
<if test="attachmentId != null">
|
||||||
|
attachment_id,
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="relationId != null">
|
||||||
|
#{relationId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="relationType != null">
|
||||||
|
#{relationType,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="attachmentId != null">
|
||||||
|
#{attachmentId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
<select id="countByExample" parameterType="io.metersphere.base.domain.AttachmentModuleRelationExample" resultType="java.lang.Long">
|
||||||
|
select count(*) from attachment_module_relation
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
<update id="updateByExampleSelective" parameterType="map">
|
||||||
|
update attachment_module_relation
|
||||||
|
<set>
|
||||||
|
<if test="record.relationId != null">
|
||||||
|
relation_id = #{record.relationId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.relationType != null">
|
||||||
|
relation_type = #{record.relationType,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.attachmentId != null">
|
||||||
|
attachment_id = #{record.attachmentId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
<update id="updateByExample" parameterType="map">
|
||||||
|
update attachment_module_relation
|
||||||
|
set relation_id = #{record.relationId,jdbcType=VARCHAR},
|
||||||
|
relation_type = #{record.relationType,jdbcType=VARCHAR},
|
||||||
|
attachment_id = #{record.attachmentId,jdbcType=VARCHAR}
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
</mapper>
|
|
@ -0,0 +1,18 @@
|
||||||
|
package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.AttachmentModuleRelation;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author songcc
|
||||||
|
*/
|
||||||
|
public interface ExtAttachmentModuleRelationMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量插入
|
||||||
|
* @param attachmentModuleRelations 附件关系记录
|
||||||
|
*/
|
||||||
|
void batchInsert(@Param("attachmentModuleRelations") List<AttachmentModuleRelation> attachmentModuleRelations);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?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.ext.ExtAttachmentModuleRelationMapper">
|
||||||
|
<insert id="batchInsert" parameterType="java.util.List">
|
||||||
|
INSERT INTO
|
||||||
|
attachment_module_relation (relation_id, relation_type, attachment_id)
|
||||||
|
VALUES
|
||||||
|
<foreach collection="attachmentModuleRelations" item="relation" separator="," >
|
||||||
|
(#{relation.relationId}, #{relation.relationType}, #{relation.attachmentId})
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
</mapper>
|
|
@ -0,0 +1,28 @@
|
||||||
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author songcc
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum AttachmentSyncType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件上传
|
||||||
|
*/
|
||||||
|
UPLOAD("upload"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件删除
|
||||||
|
*/
|
||||||
|
DELETE("delete");
|
||||||
|
|
||||||
|
private String syncOperateType;
|
||||||
|
|
||||||
|
AttachmentSyncType(String syncOperateType) {
|
||||||
|
this.syncOperateType = syncOperateType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String syncOperateType() {
|
||||||
|
return syncOperateType;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,21 @@
|
||||||
package io.metersphere.commons.constants;
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author songcc
|
||||||
|
*/
|
||||||
|
|
||||||
public enum AttachmentType {
|
public enum AttachmentType {
|
||||||
|
|
||||||
TEST_CASE("testcase"), ISSUE("issue");
|
/**
|
||||||
|
* 测试用例类型
|
||||||
|
*/
|
||||||
|
TEST_CASE("testcase"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缺陷类型
|
||||||
|
*/
|
||||||
|
ISSUE("issue");
|
||||||
|
|
||||||
// 附件类型名称
|
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
AttachmentType(String type) {
|
AttachmentType(String type) {
|
||||||
|
|
|
@ -79,8 +79,7 @@ public class ShiroUtils {
|
||||||
public static void ignoreCsrfFilter(Map<String, String> filterChainDefinitionMap) {
|
public static void ignoreCsrfFilter(Map<String, String> filterChainDefinitionMap) {
|
||||||
filterChainDefinitionMap.put("/", "apikey, authc"); // 跳转到 / 不用校验 csrf
|
filterChainDefinitionMap.put("/", "apikey, authc"); // 跳转到 / 不用校验 csrf
|
||||||
filterChainDefinitionMap.put("/language", "apikey, authc");// 跳转到 /language 不用校验 csrf
|
filterChainDefinitionMap.put("/language", "apikey, authc");// 跳转到 /language 不用校验 csrf
|
||||||
filterChainDefinitionMap.put("/test/case/file/preview/**", "apikey, authc"); // 预览测试用例附件 不用校验 csrf
|
filterChainDefinitionMap.put("/attachment/preview/**", "apikey, authc"); // 预览测试用例附件 不用校验 csrf
|
||||||
filterChainDefinitionMap.put("/test/case/attachment/preview/**", "apikey, authc"); // 预览测试用例附件 不用校验 csrf
|
|
||||||
filterChainDefinitionMap.put("/mock", "apikey, authc"); // 跳转到 /mock接口 不用校验 csrf
|
filterChainDefinitionMap.put("/mock", "apikey, authc"); // 跳转到 /mock接口 不用校验 csrf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
|
||||||
@Resource
|
@Resource
|
||||||
private TestCaseService testCaseService;
|
private TestCaseService testCaseService;
|
||||||
@Resource
|
@Resource
|
||||||
|
private AttachmentService attachmentService;
|
||||||
|
@Resource
|
||||||
private ApiTestCaseService apiTestCaseService;
|
private ApiTestCaseService apiTestCaseService;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanTestCaseService testPlanTestCaseService;
|
private TestPlanTestCaseService testPlanTestCaseService;
|
||||||
|
@ -158,6 +160,7 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
|
||||||
initOnceOperate(customFieldResourceService::compatibleData, "init.custom.field.resource");
|
initOnceOperate(customFieldResourceService::compatibleData, "init.custom.field.resource");
|
||||||
initOnceOperate(jarConfigService::initJarPath, "init.jar.path");
|
initOnceOperate(jarConfigService::initJarPath, "init.jar.path");
|
||||||
initOnceOperate(testCaseService::initAttachment, "init.attachment.test.case");
|
initOnceOperate(testCaseService::initAttachment, "init.attachment.test.case");
|
||||||
|
initOnceOperate(attachmentService::initAttachment, "init.attachment.all");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package io.metersphere.track.controller;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.FileAttachmentMetadata;
|
||||||
|
import io.metersphere.service.FileService;
|
||||||
|
import io.metersphere.track.request.attachment.AttachmentRequest;
|
||||||
|
import io.metersphere.track.request.testplan.FileOperationRequest;
|
||||||
|
import io.metersphere.track.service.AttachmentService;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author songcc
|
||||||
|
*/
|
||||||
|
@RequestMapping("attachment")
|
||||||
|
@RestController
|
||||||
|
public class AttachmentController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FileService fileService;
|
||||||
|
@Resource
|
||||||
|
private AttachmentService attachmentService;
|
||||||
|
|
||||||
|
@PostMapping(value = "/upload", consumes = {"multipart/form-data"})
|
||||||
|
public void uploadAttachment(@RequestPart("request") AttachmentRequest request, @RequestPart(value = "file", required = false) MultipartFile file) {
|
||||||
|
attachmentService.uploadAttachment(request, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/preview/{fileId}")
|
||||||
|
public ResponseEntity<byte[]> previewAttachment(@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("/download")
|
||||||
|
public ResponseEntity<byte[]> downloadAttachment(@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("/delete/{attachmentType}/{attachmentId}")
|
||||||
|
public void deleteAttachment(@PathVariable String attachmentId, @PathVariable String attachmentType) {
|
||||||
|
attachmentService.deleteAttachment(attachmentId, attachmentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/metadata/list")
|
||||||
|
public List<FileAttachmentMetadata> listMetadata(@RequestBody AttachmentRequest request) {
|
||||||
|
return attachmentService.listMetadata(request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package io.metersphere.track.controller;
|
||||||
|
|
||||||
import com.github.pagehelper.Page;
|
import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.base.domain.FileAttachmentMetadata;
|
|
||||||
import io.metersphere.base.domain.Issues;
|
import io.metersphere.base.domain.Issues;
|
||||||
import io.metersphere.base.domain.IssuesDao;
|
import io.metersphere.base.domain.IssuesDao;
|
||||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||||
|
@ -27,10 +26,8 @@ import io.metersphere.track.request.testcase.AuthUserIssueRequest;
|
||||||
import io.metersphere.track.request.testcase.IssuesRequest;
|
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||||
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||||
import io.metersphere.track.service.IssuesService;
|
import io.metersphere.track.service.IssuesService;
|
||||||
import io.metersphere.track.service.TestCaseService;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -83,22 +80,6 @@ public class IssuesController {
|
||||||
issuesService.updateIssues(issuesRequest);
|
issuesService.updateIssues(issuesRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/attachment/upload", consumes = {"multipart/form-data"})
|
|
||||||
@MsAuditLog(module = OperLogModule.TRACK_BUG, type = OperLogConstants.IMPORT, beforeEvent = "#msClass.getLogDetails(#issuesRequest.id)", content = "#msClass.getLogDetails(#request.id)", msClass = TestCaseService.class)
|
|
||||||
public void uploadAttachment(@RequestPart("request") IssuesUpdateRequest issuesRequest, @RequestPart(value = "file", required = false) MultipartFile file) {
|
|
||||||
issuesService.uploadAttachment(issuesRequest, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/attachment/delete/{fileId}")
|
|
||||||
public void deleteAttachment(@PathVariable String fileId) {
|
|
||||||
issuesService.deleteAttachment(fileId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/file/attachmentMetadata/{issueId}")
|
|
||||||
public List<FileAttachmentMetadata> getFileAttachmentMetadataByIssueId(@PathVariable String issueId) {
|
|
||||||
return fileService.getFileAttachmentMetadataByIssueId(issueId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/get/case/{refType}/{id}")
|
@GetMapping("/get/case/{refType}/{id}")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_ISSUE_READ)
|
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_ISSUE_READ)
|
||||||
public List<IssuesDao> getIssues(@PathVariable String refType, @PathVariable String id) {
|
public List<IssuesDao> getIssues(@PathVariable String refType, @PathVariable String id) {
|
||||||
|
|
|
@ -6,7 +6,10 @@ import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||||
import io.metersphere.api.dto.automation.ApiScenarioRequest;
|
import io.metersphere.api.dto.automation.ApiScenarioRequest;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||||
import io.metersphere.base.domain.*;
|
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.mapper.TestCaseMapper;
|
import io.metersphere.base.mapper.TestCaseMapper;
|
||||||
import io.metersphere.commons.constants.NoticeConstants;
|
import io.metersphere.commons.constants.NoticeConstants;
|
||||||
import io.metersphere.commons.constants.OperLogConstants;
|
import io.metersphere.commons.constants.OperLogConstants;
|
||||||
|
@ -371,11 +374,6 @@ public class TestCaseController {
|
||||||
return fileService.getFileMetadataByCaseId(caseId);
|
return fileService.getFileMetadataByCaseId(caseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/file/attachmentMetadata/{caseId}")
|
|
||||||
public List<FileAttachmentMetadata> getFileAttachmentMetadataByCaseId(@PathVariable String caseId) {
|
|
||||||
return fileService.getFileAttachmentMetadataByCaseId(caseId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/file/download")
|
@PostMapping("/file/download")
|
||||||
public ResponseEntity<byte[]> download(@RequestBody FileOperationRequest fileOperationRequest) {
|
public ResponseEntity<byte[]> download(@RequestBody FileOperationRequest fileOperationRequest) {
|
||||||
byte[] bytes = fileService.loadFileAsBytes(fileOperationRequest.getId());
|
byte[] bytes = fileService.loadFileAsBytes(fileOperationRequest.getId());
|
||||||
|
@ -394,35 +392,6 @@ public class TestCaseController {
|
||||||
.body(bytes);
|
.body(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/attachment/upload", consumes = {"multipart/form-data"})
|
|
||||||
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE, type = OperLogConstants.IMPORT, beforeEvent = "#msClass.getLogDetails(#request.id)", title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = TestCaseService.class)
|
|
||||||
public void uploadAttachment(@RequestPart("request") EditTestCaseRequest request, @RequestPart(value = "file", required = false) MultipartFile file) {
|
|
||||||
testCaseService.uploadAttachment(request, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/attachment/preview/{fileId}")
|
|
||||||
public ResponseEntity<byte[]> previewAttachment(@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("/attachment/download")
|
|
||||||
public ResponseEntity<byte[]> downloadAttachment(@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("/attachment/delete/{fileId}")
|
|
||||||
public void deleteAttachment(@PathVariable String fileId) {
|
|
||||||
testCaseService.deleteAttachment(fileId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/save")
|
@PostMapping("/save")
|
||||||
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE, type = OperLogConstants.CREATE, title = "#testCaseWithBLOBs.name", content = "#msClass.getLogDetails(#testCaseWithBLOBs.id)", msClass = TestCaseService.class)
|
@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) {
|
public TestCaseWithBLOBs saveTestCase(@RequestBody EditTestCaseRequest request) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.IssueFileMapper;
|
import io.metersphere.base.mapper.AttachmentModuleRelationMapper;
|
||||||
import io.metersphere.base.mapper.IssuesMapper;
|
import io.metersphere.base.mapper.IssuesMapper;
|
||||||
import io.metersphere.base.mapper.ProjectMapper;
|
import io.metersphere.base.mapper.ProjectMapper;
|
||||||
import io.metersphere.base.mapper.TestCaseIssuesMapper;
|
import io.metersphere.base.mapper.TestCaseIssuesMapper;
|
||||||
|
@ -24,6 +24,7 @@ import io.metersphere.track.issue.domain.ProjectIssueConfig;
|
||||||
import io.metersphere.track.request.testcase.EditTestCaseRequest;
|
import io.metersphere.track.request.testcase.EditTestCaseRequest;
|
||||||
import io.metersphere.track.request.testcase.IssuesRequest;
|
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||||
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||||
|
import io.metersphere.track.service.AttachmentService;
|
||||||
import io.metersphere.track.service.IssuesService;
|
import io.metersphere.track.service.IssuesService;
|
||||||
import io.metersphere.track.service.TestCaseIssueService;
|
import io.metersphere.track.service.TestCaseIssueService;
|
||||||
import io.metersphere.track.service.TestCaseService;
|
import io.metersphere.track.service.TestCaseService;
|
||||||
|
@ -67,7 +68,8 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
||||||
protected CustomFieldService customFieldService;
|
protected CustomFieldService customFieldService;
|
||||||
protected IssuesService issuesService;
|
protected IssuesService issuesService;
|
||||||
protected FileService fileService;
|
protected FileService fileService;
|
||||||
protected IssueFileMapper issueFileMapper;
|
protected AttachmentService attachmentService;
|
||||||
|
protected AttachmentModuleRelationMapper attachmentModuleRelationMapper;
|
||||||
|
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return key;
|
return key;
|
||||||
|
@ -96,7 +98,8 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
||||||
this.customFieldService = CommonBeanFactory.getBean(CustomFieldService.class);
|
this.customFieldService = CommonBeanFactory.getBean(CustomFieldService.class);
|
||||||
this.issuesService = CommonBeanFactory.getBean(IssuesService.class);
|
this.issuesService = CommonBeanFactory.getBean(IssuesService.class);
|
||||||
this.fileService = CommonBeanFactory.getBean(FileService.class);
|
this.fileService = CommonBeanFactory.getBean(FileService.class);
|
||||||
this.issueFileMapper = CommonBeanFactory.getBean(IssueFileMapper.class);
|
this.attachmentService = CommonBeanFactory.getBean(AttachmentService.class);
|
||||||
|
this.attachmentModuleRelationMapper = CommonBeanFactory.getBean(AttachmentModuleRelationMapper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getPlatformConfig(String platform) {
|
protected String getPlatformConfig(String platform) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.track.issue;
|
||||||
import io.metersphere.base.domain.IssuesDao;
|
import io.metersphere.base.domain.IssuesDao;
|
||||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||||
import io.metersphere.base.domain.Project;
|
import io.metersphere.base.domain.Project;
|
||||||
|
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||||
import io.metersphere.dto.IssueTemplateDao;
|
import io.metersphere.dto.IssueTemplateDao;
|
||||||
import io.metersphere.dto.UserDTO;
|
import io.metersphere.dto.UserDTO;
|
||||||
import io.metersphere.track.dto.DemandDTO;
|
import io.metersphere.track.dto.DemandDTO;
|
||||||
|
@ -12,6 +13,7 @@ import io.metersphere.track.request.testcase.IssuesRequest;
|
||||||
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface IssuesPlatform {
|
public interface IssuesPlatform {
|
||||||
|
@ -113,4 +115,12 @@ public interface IssuesPlatform {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ResponseEntity proxyForGet(String url, Class responseEntityClazz);
|
ResponseEntity proxyForGet(String url, Class responseEntityClazz);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步MS缺陷附件到第三方平台
|
||||||
|
* @param issuesRequest 平台参数
|
||||||
|
* @param file 附件
|
||||||
|
* @param syncType 同步操作类型: UPLOAD, DELETE
|
||||||
|
*/
|
||||||
|
void syncIssuesAttachment(IssuesUpdateRequest issuesRequest, File file, AttachmentSyncType syncType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,7 @@ import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||||
import io.metersphere.commons.constants.AttachmentType;
|
import io.metersphere.commons.constants.*;
|
||||||
import io.metersphere.commons.constants.CustomFieldType;
|
|
||||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
|
||||||
import io.metersphere.commons.constants.IssuesStatus;
|
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
@ -22,6 +19,7 @@ import io.metersphere.track.issue.client.JiraClientV2;
|
||||||
import io.metersphere.track.issue.domain.PlatformUser;
|
import io.metersphere.track.issue.domain.PlatformUser;
|
||||||
import io.metersphere.track.issue.domain.ProjectIssueConfig;
|
import io.metersphere.track.issue.domain.ProjectIssueConfig;
|
||||||
import io.metersphere.track.issue.domain.jira.*;
|
import io.metersphere.track.issue.domain.jira.*;
|
||||||
|
import io.metersphere.track.request.attachment.AttachmentRequest;
|
||||||
import io.metersphere.track.request.testcase.IssuesRequest;
|
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||||
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||||
import io.metersphere.track.service.IssuesService;
|
import io.metersphere.track.service.IssuesService;
|
||||||
|
@ -243,15 +241,15 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
||||||
// 用例与第三方缺陷平台中的缺陷关联
|
// 用例与第三方缺陷平台中的缺陷关联
|
||||||
handleTestCaseIssues(issuesRequest);
|
handleTestCaseIssues(issuesRequest);
|
||||||
|
|
||||||
// 如果是复制新增, 同步附件到第三方平台
|
// 如果是复制新增, 同步MS附件到Jira
|
||||||
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
||||||
IssueFileExample example = new IssueFileExample();
|
AttachmentRequest request = new AttachmentRequest();
|
||||||
example.createCriteria().andIssueIdEqualTo(issuesRequest.getCopyIssueId());
|
request.setBelongId(issuesRequest.getCopyIssueId());
|
||||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(example);
|
request.setBelongType(AttachmentType.ISSUE.type());
|
||||||
if (issueFiles != null) {
|
List<String> attachmentIds = attachmentService.getAttachmentIdsByParam(request);
|
||||||
issueFiles.forEach(issueFile -> {
|
if (CollectionUtils.isNotEmpty(attachmentIds)) {
|
||||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.getFileAttachmentMetadataByFileId(issueFile.getFileId());
|
attachmentIds.forEach(attachmentId -> {
|
||||||
// 同步第三方平台附件
|
FileAttachmentMetadata fileAttachmentMetadata = fileService.getFileAttachmentMetadataByFileId(attachmentId);
|
||||||
File file = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
File file = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||||
jiraClientV2.uploadAttachment(result.getKey(), file);
|
jiraClientV2.uploadAttachment(result.getKey(), file);
|
||||||
});
|
});
|
||||||
|
@ -474,46 +472,9 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
||||||
public void updateIssue(IssuesUpdateRequest request) {
|
public void updateIssue(IssuesUpdateRequest request) {
|
||||||
setUserConfig();
|
setUserConfig();
|
||||||
Project project = getProject();
|
Project project = getProject();
|
||||||
List<File> imageFiles = getImageFiles(request);
|
|
||||||
|
|
||||||
JSONObject param = buildUpdateParam(request, getIssueType(project.getIssueConfig()), project.getJiraKey());
|
JSONObject param = buildUpdateParam(request, getIssueType(project.getIssueConfig()), project.getJiraKey());
|
||||||
jiraClientV2.updateIssue(request.getPlatformId(), JSONObject.toJSONString(param));
|
jiraClientV2.updateIssue(request.getPlatformId(), JSONObject.toJSONString(param));
|
||||||
|
|
||||||
List<FileAttachmentMetadata> newFiles = fileService.getFileAttachmentMetadataByIssueId(request.getId());
|
|
||||||
List<String> newFileNames = newFiles.stream().map(FileAttachmentMetadata::getName).collect(Collectors.toList());
|
|
||||||
Set<String> attachmentNames = new HashSet<>();
|
|
||||||
// 同步Jira平台附件
|
|
||||||
JiraIssue jiraIssue = jiraClientV2.getIssues(request.getPlatformId());
|
|
||||||
JSONObject fields = jiraIssue.getFields();
|
|
||||||
JSONArray attachments = fields.getJSONArray("attachment");
|
|
||||||
// 删除旧附件,若缺陷描述中不存在且附件上传的删除列表中存在则删除
|
|
||||||
if (!attachments.isEmpty() && attachments.size() > 0) {
|
|
||||||
for (int i = 0; i < attachments.size(); i++) {
|
|
||||||
JSONObject attachment = attachments.getJSONObject(i);
|
|
||||||
String filename = attachment.getString("filename");
|
|
||||||
attachmentNames.add(filename);
|
|
||||||
if (!request.getDescription().contains(filename) && !newFileNames.contains(filename)) {
|
|
||||||
String fileId = attachment.getString("id");
|
|
||||||
jiraClientV2.deleteAttachment(fileId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//上传新附件
|
|
||||||
if (CollectionUtils.isNotEmpty(newFiles)) {
|
|
||||||
newFiles.forEach(file -> {
|
|
||||||
if (!attachmentNames.contains(file.getName())) {
|
|
||||||
File newFile = new File(file.getFilePath() + "/" + file.getName());
|
|
||||||
jiraClientV2.uploadAttachment(request.getPlatformId(), newFile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
imageFiles.forEach(img -> {
|
|
||||||
if (!attachmentNames.contains(img.getName())) {
|
|
||||||
// 旧附件没有才上传新附件
|
|
||||||
jiraClientV2.uploadAttachment(request.getPlatformId(), img);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (request.getTransitions() != null) {
|
if (request.getTransitions() != null) {
|
||||||
try {
|
try {
|
||||||
List<JiraTransitionsResponse.Transitions> transitions = jiraClientV2.getTransitions(request.getPlatformId());
|
List<JiraTransitionsResponse.Transitions> transitions = jiraClientV2.getTransitions(request.getPlatformId());
|
||||||
|
@ -873,8 +834,35 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
||||||
return jiraClientV2.proxyForGet(url, responseEntityClazz);
|
return jiraClientV2.proxyForGet(url, responseEntityClazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncIssuesAttachment(IssuesUpdateRequest issuesRequest, File file, AttachmentSyncType syncType) {
|
||||||
|
// 同步缺陷MS附件到Jira
|
||||||
|
if ("upload".equals(syncType.syncOperateType())) {
|
||||||
|
// 上传附件
|
||||||
|
jiraClientV2.uploadAttachment(issuesRequest.getPlatformId(), file);
|
||||||
|
} else if ("delete".equals(syncType.syncOperateType())) {
|
||||||
|
// 删除附件
|
||||||
|
JiraIssue jiraIssue = jiraClientV2.getIssues(issuesRequest.getPlatformId());
|
||||||
|
JSONObject fields = jiraIssue.getFields();
|
||||||
|
JSONArray attachments = fields.getJSONArray("attachment");
|
||||||
|
if (!attachments.isEmpty() && attachments.size() > 0) {
|
||||||
|
for (int i = 0; i < attachments.size(); i++) {
|
||||||
|
JSONObject attachment = attachments.getJSONObject(i);
|
||||||
|
String filename = attachment.getString("filename");
|
||||||
|
if (filename.equals(file.getName())) {
|
||||||
|
String fileId = attachment.getString("id");
|
||||||
|
jiraClientV2.deleteAttachment(fileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void syncJiraIssueAttachments(IssuesWithBLOBs issue, JiraIssue jiraIssue) {
|
public void syncJiraIssueAttachments(IssuesWithBLOBs issue, JiraIssue jiraIssue) {
|
||||||
issuesService.deleteIssueAttachments(issue.getId());
|
AttachmentRequest request = new AttachmentRequest();
|
||||||
|
request.setBelongType(AttachmentType.ISSUE.type());
|
||||||
|
request.setBelongId(issue.getId());
|
||||||
|
attachmentService.deleteAttachment(request);
|
||||||
JSONArray attachments = jiraIssue.getFields().getJSONArray("attachment");
|
JSONArray attachments = jiraIssue.getFields().getJSONArray("attachment");
|
||||||
if (CollectionUtils.isEmpty(attachments)) {
|
if (CollectionUtils.isEmpty(attachments)) {
|
||||||
return;
|
return;
|
||||||
|
@ -882,14 +870,16 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
||||||
for (int i = 0; i < attachments.size(); i++) {
|
for (int i = 0; i < attachments.size(); i++) {
|
||||||
JSONObject attachment = attachments.getJSONObject(i);
|
JSONObject attachment = attachments.getJSONObject(i);
|
||||||
String filename = attachment.getString("filename");
|
String filename = attachment.getString("filename");
|
||||||
if (!issue.getDescription().contains(filename) && !issue.getCustomFields().contains(filename)) {
|
if ((issue.getDescription() == null || !issue.getDescription().contains(filename))
|
||||||
|
&& (issue.getCustomFields() == null || !issue.getCustomFields().contains(filename))) {
|
||||||
String id = attachment.getString("id");
|
String id = attachment.getString("id");
|
||||||
byte[] content = jiraClientV2.getAttachmentContent(id);
|
byte[] content = jiraClientV2.getAttachmentContent(id);
|
||||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachmentByBytes(content, AttachmentType.ISSUE.type(), issue.getId(), filename);
|
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachmentByBytes(content, AttachmentType.ISSUE.type(), issue.getId(), filename);
|
||||||
IssueFile issueFile = new IssueFile();
|
AttachmentModuleRelation attachmentModuleRelation = new AttachmentModuleRelation();
|
||||||
issueFile.setIssueId(issue.getId());
|
attachmentModuleRelation.setAttachmentId(fileAttachmentMetadata.getId());
|
||||||
issueFile.setFileId(fileAttachmentMetadata.getId());
|
attachmentModuleRelation.setRelationId(issue.getId());
|
||||||
issueFileMapper.insert(issueFile);
|
attachmentModuleRelation.setRelationType(AttachmentType.ISSUE.type());
|
||||||
|
attachmentModuleRelationMapper.insert(attachmentModuleRelation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.track.issue;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.metersphere.base.domain.IssuesDao;
|
import io.metersphere.base.domain.IssuesDao;
|
||||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||||
|
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||||
import io.metersphere.commons.user.SessionUser;
|
import io.metersphere.commons.user.SessionUser;
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
|
@ -14,6 +15,7 @@ import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||||
import io.metersphere.track.request.testcase.TestCaseBatchRequest;
|
import io.metersphere.track.request.testcase.TestCaseBatchRequest;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -78,4 +80,10 @@ public class LocalPlatform extends LocalAbstractPlatform {
|
||||||
public void updateIssue(IssuesUpdateRequest request) {
|
public void updateIssue(IssuesUpdateRequest request) {
|
||||||
handleIssueUpdate(request);
|
handleIssueUpdate(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncIssuesAttachment(IssuesUpdateRequest issuesRequest, File file, AttachmentSyncType syncType) {
|
||||||
|
// 不需要同步
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.base.domain.IssuesDao;
|
||||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||||
import io.metersphere.base.domain.Project;
|
import io.metersphere.base.domain.Project;
|
||||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||||
|
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||||
import io.metersphere.commons.constants.IssuesStatus;
|
import io.metersphere.commons.constants.IssuesStatus;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
@ -31,6 +32,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -306,6 +308,11 @@ public class TapdPlatform extends AbstractIssuePlatform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncIssuesAttachment(IssuesUpdateRequest issuesRequest, File file, AttachmentSyncType syncType) {
|
||||||
|
// TODO: 同步缺陷MS附件到TAPD
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PlatformStatusDTO> getTransitions(String issueKey) {
|
public List<PlatformStatusDTO> getTransitions(String issueKey) {
|
||||||
List<PlatformStatusDTO> platformStatusDTOS = new ArrayList<>();
|
List<PlatformStatusDTO> platformStatusDTOS = new ArrayList<>();
|
||||||
|
|
|
@ -9,6 +9,7 @@ import io.metersphere.base.domain.IssuesExample;
|
||||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||||
import io.metersphere.base.domain.Project;
|
import io.metersphere.base.domain.Project;
|
||||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||||
|
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||||
import io.metersphere.commons.constants.IssuesStatus;
|
import io.metersphere.commons.constants.IssuesStatus;
|
||||||
import io.metersphere.commons.constants.ZentaoIssuePlatformStatus;
|
import io.metersphere.commons.constants.ZentaoIssuePlatformStatus;
|
||||||
|
@ -38,6 +39,7 @@ import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -537,6 +539,11 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
|
||||||
return zentaoClient.checkProjectExist(relateId);
|
return zentaoClient.checkProjectExist(relateId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncIssuesAttachment(IssuesUpdateRequest issuesRequest, File file, AttachmentSyncType syncType) {
|
||||||
|
// TODO: 同步缺陷MS附件到禅道
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PlatformStatusDTO> getTransitions(String issueKey) {
|
public List<PlatformStatusDTO> getTransitions(String issueKey) {
|
||||||
List<PlatformStatusDTO> platformStatusDTOS = new ArrayList<>();
|
List<PlatformStatusDTO> platformStatusDTOS = new ArrayList<>();
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package io.metersphere.track.request.attachment;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author songcc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AttachmentRequest {
|
||||||
|
|
||||||
|
private String belongType;
|
||||||
|
|
||||||
|
private String belongId;
|
||||||
|
|
||||||
|
private String copyBelongId;
|
||||||
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.*;
|
||||||
|
import io.metersphere.base.mapper.*;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtAttachmentModuleRelationMapper;
|
||||||
|
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||||
|
import io.metersphere.commons.constants.AttachmentType;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
|
import io.metersphere.i18n.Translator;
|
||||||
|
import io.metersphere.service.FileService;
|
||||||
|
import io.metersphere.track.issue.IssueFactory;
|
||||||
|
import io.metersphere.track.request.attachment.AttachmentRequest;
|
||||||
|
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||||
|
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author songcc
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class AttachmentService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
FileService fileService;
|
||||||
|
@Resource
|
||||||
|
private IssuesMapper issuesMapper;
|
||||||
|
@Resource
|
||||||
|
private IssueFileMapper issueFileMapper;
|
||||||
|
@Resource
|
||||||
|
private TestCaseMapper testCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private TestCaseFileMapper testCaseFileMapper;
|
||||||
|
@Resource
|
||||||
|
private FileAttachmentMetadataMapper fileAttachmentMetadataMapper;
|
||||||
|
@Resource
|
||||||
|
private AttachmentModuleRelationMapper attachmentModuleRelationMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtAttachmentModuleRelationMapper extAttachmentModuleRelationMapper;
|
||||||
|
|
||||||
|
public void uploadAttachment(AttachmentRequest request, MultipartFile file) {
|
||||||
|
// 附件上传的前置校验
|
||||||
|
if (AttachmentType.ISSUE.type().equals(request.getBelongType())) {
|
||||||
|
IssuesWithBLOBs issues = issuesMapper.selectByPrimaryKey(request.getBelongId());
|
||||||
|
if (issues == null) {
|
||||||
|
MSException.throwException(Translator.get("issues_attachment_upload_not_found") + request.getBelongId());
|
||||||
|
}
|
||||||
|
} else if (AttachmentType.TEST_CASE.type().equals(request.getBelongType())) {
|
||||||
|
TestCaseWithBLOBs testCase = testCaseMapper.selectByPrimaryKey(request.getBelongId());
|
||||||
|
if (testCase == null) {
|
||||||
|
MSException.throwException(Translator.get("test_case_attachment_upload_not_found") + request.getBelongId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传MS平台
|
||||||
|
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachment(file, request.getBelongType(), request.getBelongId());
|
||||||
|
AttachmentModuleRelation attachmentModuleRelation = new AttachmentModuleRelation();
|
||||||
|
attachmentModuleRelation.setRelationId(request.getBelongId());
|
||||||
|
attachmentModuleRelation.setRelationType(request.getBelongType());
|
||||||
|
attachmentModuleRelation.setAttachmentId(fileAttachmentMetadata.getId());
|
||||||
|
attachmentModuleRelationMapper.insert(attachmentModuleRelation);
|
||||||
|
|
||||||
|
// 附件上传完成后的后置操作
|
||||||
|
// 缺陷类型的附件, 需单独同步第三方平台
|
||||||
|
if (AttachmentType.ISSUE.type().equals(request.getBelongType())) {
|
||||||
|
IssuesWithBLOBs issues = issuesMapper.selectByPrimaryKey(request.getBelongId());
|
||||||
|
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||||
|
updateRequest.setPlatformId(issues.getPlatformId());
|
||||||
|
File uploadFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||||
|
IssuesRequest issuesRequest = new IssuesRequest();
|
||||||
|
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||||
|
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||||
|
.syncIssuesAttachment(updateRequest, uploadFile, AttachmentSyncType.UPLOAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAttachment(String attachmentId, String attachmentType) {
|
||||||
|
FileAttachmentMetadata fileAttachmentMetadata = fileAttachmentMetadataMapper.selectByPrimaryKey(attachmentId);
|
||||||
|
List<String> ids = List.of(attachmentId);
|
||||||
|
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||||
|
example.createCriteria().andAttachmentIdIn(ids).andRelationTypeEqualTo(attachmentType);
|
||||||
|
// 缺陷类型的附件, 需先同步第三方平台
|
||||||
|
if (AttachmentType.ISSUE.type().equals(attachmentType)) {
|
||||||
|
List<AttachmentModuleRelation> moduleRelations = attachmentModuleRelationMapper.selectByExample(example);
|
||||||
|
if (CollectionUtils.isNotEmpty(moduleRelations) && moduleRelations.size() == 1) {
|
||||||
|
IssuesWithBLOBs issues = issuesMapper.selectByPrimaryKey(moduleRelations.get(0).getRelationId());
|
||||||
|
IssuesUpdateRequest updateRequest = new IssuesUpdateRequest();
|
||||||
|
updateRequest.setPlatformId(issues.getPlatformId());
|
||||||
|
File deleteFile = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||||
|
IssuesRequest issuesRequest = new IssuesRequest();
|
||||||
|
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||||
|
Objects.requireNonNull(IssueFactory.createPlatform(issues.getPlatform(), issuesRequest))
|
||||||
|
.syncIssuesAttachment(updateRequest, deleteFile, AttachmentSyncType.DELETE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除MS附件及关联数据
|
||||||
|
fileService.deleteAttachment(ids);
|
||||||
|
fileService.deleteFileAttachmentByIds(ids);
|
||||||
|
attachmentModuleRelationMapper.deleteByExample(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAttachment(AttachmentRequest request) {
|
||||||
|
fileService.deleteAttachment(request.getBelongType(), request.getBelongId());
|
||||||
|
List<String> attachmentIds = getAttachmentIdsByParam(request);
|
||||||
|
if (CollectionUtils.isNotEmpty(attachmentIds)) {
|
||||||
|
FileAttachmentMetadataExample fileAttachmentMetadataExample = new FileAttachmentMetadataExample();
|
||||||
|
fileAttachmentMetadataExample.createCriteria().andIdIn(attachmentIds);
|
||||||
|
fileAttachmentMetadataMapper.deleteByExample(fileAttachmentMetadataExample);
|
||||||
|
}
|
||||||
|
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||||
|
example.createCriteria().andRelationIdEqualTo(request.getBelongId()).andRelationTypeEqualTo(request.getBelongType());
|
||||||
|
attachmentModuleRelationMapper.deleteByExample(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyAttachment(AttachmentRequest request) {
|
||||||
|
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||||
|
example.createCriteria().andRelationIdEqualTo(request.getCopyBelongId()).andRelationTypeEqualTo(request.getBelongType());
|
||||||
|
List<AttachmentModuleRelation> attachmentModuleRelations = attachmentModuleRelationMapper.selectByExample(example);
|
||||||
|
if (CollectionUtils.isNotEmpty(attachmentModuleRelations)) {
|
||||||
|
attachmentModuleRelations.forEach(attachmentModuleRelation -> {
|
||||||
|
FileAttachmentMetadata fileAttachmentMetadata = fileService.copyAttachment(attachmentModuleRelation.getAttachmentId(), request.getBelongType(), request.getBelongId());
|
||||||
|
AttachmentModuleRelation record = new AttachmentModuleRelation();
|
||||||
|
record.setRelationId(request.getBelongId());
|
||||||
|
record.setRelationType(request.getBelongType());
|
||||||
|
record.setAttachmentId(fileAttachmentMetadata.getId());
|
||||||
|
attachmentModuleRelationMapper.insert(record);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FileAttachmentMetadata> listMetadata(AttachmentRequest request) {
|
||||||
|
List<String> attachmentIds = getAttachmentIdsByParam(request);
|
||||||
|
if (CollectionUtils.isEmpty(attachmentIds)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
FileAttachmentMetadataExample fileExample = new FileAttachmentMetadataExample();
|
||||||
|
fileExample.createCriteria().andIdIn(attachmentIds);
|
||||||
|
return fileAttachmentMetadataMapper.selectByExample(fileExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getAttachmentIdsByParam(AttachmentRequest request) {
|
||||||
|
AttachmentModuleRelationExample example = new AttachmentModuleRelationExample();
|
||||||
|
example.createCriteria().andRelationIdEqualTo(request.getBelongId()).andRelationTypeEqualTo(request.getBelongType());
|
||||||
|
List<AttachmentModuleRelation> attachmentModuleRelations = attachmentModuleRelationMapper.selectByExample(example);
|
||||||
|
List<String> attachmentIds = attachmentModuleRelations.stream().map(AttachmentModuleRelation::getAttachmentId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return attachmentIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initAttachment() {
|
||||||
|
List<AttachmentModuleRelation> attachmentModuleRelations = new ArrayList<>();
|
||||||
|
List<IssueFile> issueFiles = issueFileMapper.selectByExample(new IssueFileExample());
|
||||||
|
List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(new TestCaseFileExample());
|
||||||
|
if (CollectionUtils.isNotEmpty(issueFiles)) {
|
||||||
|
issueFiles.forEach(issueFile -> {
|
||||||
|
AttachmentModuleRelation relation = new AttachmentModuleRelation();
|
||||||
|
relation.setAttachmentId(issueFile.getFileId());
|
||||||
|
relation.setRelationId(issueFile.getIssueId());
|
||||||
|
relation.setRelationType(AttachmentType.ISSUE.type());
|
||||||
|
attachmentModuleRelations.add(relation);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(testCaseFiles)) {
|
||||||
|
testCaseFiles.forEach(testCaseFile -> {
|
||||||
|
AttachmentModuleRelation relation = new AttachmentModuleRelation();
|
||||||
|
relation.setAttachmentId(testCaseFile.getFileId());
|
||||||
|
relation.setRelationId(testCaseFile.getCaseId());
|
||||||
|
relation.setRelationType(AttachmentType.TEST_CASE.type());
|
||||||
|
attachmentModuleRelations.add(relation);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
extAttachmentModuleRelationMapper.batchInsert(attachmentModuleRelations);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ import io.metersphere.track.issue.*;
|
||||||
import io.metersphere.track.issue.domain.PlatformUser;
|
import io.metersphere.track.issue.domain.PlatformUser;
|
||||||
import io.metersphere.track.issue.domain.jira.JiraIssueType;
|
import io.metersphere.track.issue.domain.jira.JiraIssueType;
|
||||||
import io.metersphere.track.issue.domain.zentao.ZentaoBuild;
|
import io.metersphere.track.issue.domain.zentao.ZentaoBuild;
|
||||||
|
import io.metersphere.track.request.attachment.AttachmentRequest;
|
||||||
import io.metersphere.track.request.issues.JiraIssueTypeRequest;
|
import io.metersphere.track.request.issues.JiraIssueTypeRequest;
|
||||||
import io.metersphere.track.request.issues.PlatformIssueTypeRequest;
|
import io.metersphere.track.request.issues.PlatformIssueTypeRequest;
|
||||||
import io.metersphere.track.request.testcase.AuthUserIssueRequest;
|
import io.metersphere.track.request.testcase.AuthUserIssueRequest;
|
||||||
|
@ -40,7 +41,6 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -91,6 +91,8 @@ public class IssuesService {
|
||||||
IssueFileMapper issueFileMapper;
|
IssueFileMapper issueFileMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private FileAttachmentMetadataMapper fileAttachmentMetadataMapper;
|
private FileAttachmentMetadataMapper fileAttachmentMetadataMapper;
|
||||||
|
@Resource
|
||||||
|
private AttachmentService attachmentService;
|
||||||
|
|
||||||
private static final String SYNC_THIRD_PARTY_ISSUES_KEY = "ISSUE:SYNC";
|
private static final String SYNC_THIRD_PARTY_ISSUES_KEY = "ISSUE:SYNC";
|
||||||
|
|
||||||
|
@ -116,22 +118,13 @@ public class IssuesService {
|
||||||
saveFollows(issuesRequest.getId(), issuesRequest.getFollows());
|
saveFollows(issuesRequest.getId(), issuesRequest.getFollows());
|
||||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
||||||
customFieldIssuesService.editFields(issuesRequest.getId(), issuesRequest.getEditFields());
|
customFieldIssuesService.editFields(issuesRequest.getId(), issuesRequest.getEditFields());
|
||||||
// copy附件
|
// 复制新增, 同步缺陷的MS附件
|
||||||
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
||||||
final String addIssueId = issues.getId();
|
AttachmentRequest attachmentRequest = new AttachmentRequest();
|
||||||
IssueFileExample example = new IssueFileExample();
|
attachmentRequest.setCopyBelongId(issuesRequest.getCopyIssueId());
|
||||||
example.createCriteria().andIssueIdEqualTo(issuesRequest.getCopyIssueId());
|
attachmentRequest.setBelongId(issues.getId());
|
||||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(example);
|
attachmentRequest.setBelongType(AttachmentType.ISSUE.type());
|
||||||
if (issueFiles != null) {
|
attachmentService.copyAttachment(attachmentRequest);
|
||||||
issueFiles.forEach(issueFile -> {
|
|
||||||
// 同步MS附件
|
|
||||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.copyAttachment(issueFile.getFileId(), AttachmentType.ISSUE.type(), addIssueId);
|
|
||||||
IssueFile newIssueFile = new IssueFile();
|
|
||||||
newIssueFile.setIssueId(addIssueId);
|
|
||||||
newIssueFile.setFileId(fileAttachmentMetadata.getId());
|
|
||||||
issueFileMapper.insert(newIssueFile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return issues;
|
return issues;
|
||||||
}
|
}
|
||||||
|
@ -145,31 +138,6 @@ public class IssuesService {
|
||||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uploadAttachment(IssuesUpdateRequest request, MultipartFile file) {
|
|
||||||
IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(request.getId());
|
|
||||||
if (issuesWithBLOBs == null) {
|
|
||||||
MSException.throwException(Translator.get("issues_attachment_upload_not_found") + request.getId());
|
|
||||||
}
|
|
||||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachment(file, AttachmentType.ISSUE.type(), request.getId());
|
|
||||||
IssueFile issueFile = new IssueFile();
|
|
||||||
issueFile.setIssueId(request.getId());
|
|
||||||
issueFile.setFileId(fileAttachmentMetadata.getId());
|
|
||||||
issueFileMapper.insert(issueFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteAttachment(String id) {
|
|
||||||
// 删除附件记录, 目录下附件文件
|
|
||||||
if (StringUtils.isNotEmpty(id)) {
|
|
||||||
List<String> ids = Arrays.asList(id);
|
|
||||||
fileService.deleteAttachment(ids);
|
|
||||||
fileService.deleteFileAttachmentByIds(ids);
|
|
||||||
//删除缺陷文件关联记录
|
|
||||||
IssueFileExample issueFileExample = new IssueFileExample();
|
|
||||||
issueFileExample.createCriteria().andFileIdIn(ids);
|
|
||||||
issueFileMapper.deleteByExample(issueFileExample);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveFollows(String issueId, List<String> follows) {
|
public void saveFollows(String issueId, List<String> follows) {
|
||||||
IssueFollowExample example = new IssueFollowExample();
|
IssueFollowExample example = new IssueFollowExample();
|
||||||
example.createCriteria().andIssueIdEqualTo(issueId);
|
example.createCriteria().andIssueIdEqualTo(issueId);
|
||||||
|
@ -369,17 +337,10 @@ public class IssuesService {
|
||||||
AbstractIssuePlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
|
AbstractIssuePlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
|
||||||
platform.deleteIssue(id);
|
platform.deleteIssue(id);
|
||||||
// 删除缺陷对应的附件
|
// 删除缺陷对应的附件
|
||||||
fileService.deleteAttachment(AttachmentType.ISSUE.type(), id);
|
AttachmentRequest request = new AttachmentRequest();
|
||||||
IssueFileExample issueFileExample = new IssueFileExample();
|
request.setBelongId(id);
|
||||||
issueFileExample.createCriteria().andIssueIdEqualTo(id);
|
request.setBelongType(AttachmentType.ISSUE.type());
|
||||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(issueFileExample);
|
attachmentService.deleteAttachment(request);
|
||||||
List<String> fileIds = issueFiles.stream().map(IssueFile::getFileId).collect(Collectors.toList());
|
|
||||||
if (CollectionUtils.isNotEmpty(fileIds)) {
|
|
||||||
FileAttachmentMetadataExample fileAttachmentMetadataExample = new FileAttachmentMetadataExample();
|
|
||||||
fileAttachmentMetadataExample.createCriteria().andIdIn(fileIds);
|
|
||||||
fileAttachmentMetadataMapper.deleteByExample(fileAttachmentMetadataExample);
|
|
||||||
}
|
|
||||||
issueFileMapper.deleteByExample(issueFileExample);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IssuesWithBLOBs get(String id) {
|
public IssuesWithBLOBs get(String id) {
|
||||||
|
|
|
@ -50,6 +50,7 @@ import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||||
import io.metersphere.track.issue.AbstractIssuePlatform;
|
import io.metersphere.track.issue.AbstractIssuePlatform;
|
||||||
import io.metersphere.track.issue.IssueFactory;
|
import io.metersphere.track.issue.IssueFactory;
|
||||||
import io.metersphere.track.issue.service.XpackIssueService;
|
import io.metersphere.track.issue.service.XpackIssueService;
|
||||||
|
import io.metersphere.track.request.attachment.AttachmentRequest;
|
||||||
import io.metersphere.track.request.testcase.*;
|
import io.metersphere.track.request.testcase.*;
|
||||||
import io.metersphere.track.request.testplan.LoadCaseRequest;
|
import io.metersphere.track.request.testplan.LoadCaseRequest;
|
||||||
import io.metersphere.xmind.XmindCaseParser;
|
import io.metersphere.xmind.XmindCaseParser;
|
||||||
|
@ -182,6 +183,8 @@ public class TestCaseService {
|
||||||
private FileMetadataMapper fileMetadataMapper;
|
private FileMetadataMapper fileMetadataMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private FileContentMapper fileContentMapper;
|
private FileContentMapper fileContentMapper;
|
||||||
|
@Resource
|
||||||
|
private AttachmentService attachmentService;
|
||||||
|
|
||||||
private ThreadLocal<Integer> importCreateNum = new ThreadLocal<>();
|
private ThreadLocal<Integer> importCreateNum = new ThreadLocal<>();
|
||||||
private ThreadLocal<Integer> beforeImportCreateNum = new ThreadLocal<>();
|
private ThreadLocal<Integer> beforeImportCreateNum = new ThreadLocal<>();
|
||||||
|
@ -614,17 +617,10 @@ public class TestCaseService {
|
||||||
customFieldTestCaseService.deleteByResourceId(testCaseId); // 删除自定义字段关联关系
|
customFieldTestCaseService.deleteByResourceId(testCaseId); // 删除自定义字段关联关系
|
||||||
functionCaseExecutionInfoService.deleteBySourceId(testCaseId);
|
functionCaseExecutionInfoService.deleteBySourceId(testCaseId);
|
||||||
// 删除用例附件关联数据, 附件内容
|
// 删除用例附件关联数据, 附件内容
|
||||||
TestCaseFileExample testCaseFileExample = new TestCaseFileExample();
|
AttachmentRequest request = new AttachmentRequest();
|
||||||
testCaseFileExample.createCriteria().andCaseIdEqualTo(testCaseId);
|
request.setBelongId(testCaseId);
|
||||||
List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(testCaseFileExample);
|
request.setBelongType(AttachmentType.TEST_CASE.type());
|
||||||
List<String> fileIds = testCaseFiles.stream().map(TestCaseFile::getFileId).collect(Collectors.toList());
|
attachmentService.deleteAttachment(request);
|
||||||
if (CollectionUtils.isNotEmpty(fileIds)) {
|
|
||||||
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);
|
return testCaseMapper.deleteByPrimaryKey(testCaseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1987,18 +1983,11 @@ public class TestCaseService {
|
||||||
final TestCaseWithBLOBs testCaseWithBLOBs = addTestCase(request);
|
final TestCaseWithBLOBs testCaseWithBLOBs = addTestCase(request);
|
||||||
// 复制用例时复制对应附件数据
|
// 复制用例时复制对应附件数据
|
||||||
if (StringUtils.isNotEmpty(request.getCopyCaseId())) {
|
if (StringUtils.isNotEmpty(request.getCopyCaseId())) {
|
||||||
TestCaseFileExample example = new TestCaseFileExample();
|
AttachmentRequest attachmentRequest = new AttachmentRequest();
|
||||||
example.createCriteria().andCaseIdEqualTo(request.getCopyCaseId());
|
attachmentRequest.setCopyBelongId(request.getCopyCaseId());
|
||||||
List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(example);
|
attachmentRequest.setBelongId(testCaseWithBLOBs.getId());
|
||||||
if (testCaseFiles != null) {
|
attachmentRequest.setBelongType(AttachmentType.TEST_CASE.type());
|
||||||
testCaseFiles.forEach(testCaseFile -> {
|
attachmentService.copyAttachment(attachmentRequest);
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return testCaseWithBLOBs;
|
return testCaseWithBLOBs;
|
||||||
}
|
}
|
||||||
|
@ -2051,32 +2040,6 @@ public class TestCaseService {
|
||||||
return editTestCase(request);
|
return editTestCase(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uploadAttachment(EditTestCaseRequest request, MultipartFile file) {
|
|
||||||
TestCaseWithBLOBs testCaseWithBLOBs = testCaseMapper.selectByPrimaryKey(request.getId());
|
|
||||||
if (testCaseWithBLOBs == null) {
|
|
||||||
MSException.throwException(Translator.get("test_case_attachment_upload_not_found") + request.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteAttachment(String id) {
|
|
||||||
// 删除附件记录, 目录下附件文件
|
|
||||||
if (StringUtils.isNotEmpty(id)) {
|
|
||||||
List<String> ids = Arrays.asList(id);
|
|
||||||
fileService.deleteAttachment(ids);
|
|
||||||
fileService.deleteFileAttachmentByIds(ids);
|
|
||||||
//删除用例文件关联记录
|
|
||||||
TestCaseFileExample testCaseFileExample = new TestCaseFileExample();
|
|
||||||
testCaseFileExample.createCriteria().andFileIdIn(ids);
|
|
||||||
testCaseFileMapper.deleteByExample(testCaseFileExample);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String editTestCase(EditTestCaseRequest request, List<MultipartFile> files) {
|
public String editTestCase(EditTestCaseRequest request, List<MultipartFile> files) {
|
||||||
String testCaseId = testPlanTestCaseMapper.selectByPrimaryKey(request.getId()).getCaseId();
|
String testCaseId = testPlanTestCaseMapper.selectByPrimaryKey(request.getId()).getCaseId();
|
||||||
request.setId(testCaseId);
|
request.setId(testCaseId);
|
||||||
|
|
|
@ -121,7 +121,7 @@ export default {
|
||||||
id: file.id,
|
id: file.id,
|
||||||
};
|
};
|
||||||
let config = {
|
let config = {
|
||||||
url: '/test/case/attachment/download',
|
url: '/attachment/download',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data,
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
|
|
|
@ -267,7 +267,7 @@ export default {
|
||||||
let file = param.file;
|
let file = param.file;
|
||||||
let progress = 0;
|
let progress = 0;
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
let requestJson = JSON.stringify({"id": this.caseId});
|
let requestJson = JSON.stringify({"belongId": this.caseId, "belongType": "testcase"});
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
formData.append('request', new Blob([requestJson], {
|
formData.append('request', new Blob([requestJson], {
|
||||||
type: "application/json"
|
type: "application/json"
|
||||||
|
@ -278,7 +278,7 @@ export default {
|
||||||
axios({
|
axios({
|
||||||
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
|
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: '/test/case/attachment/upload',
|
url: '/attachment/upload',
|
||||||
data: formData,
|
data: formData,
|
||||||
cancelToken: new CancelToken(function executor(c) {
|
cancelToken: new CancelToken(function executor(c) {
|
||||||
self.cancelFileToken.push({"name": file.name, "cancelFunc": c});
|
self.cancelFileToken.push({"name": file.name, "cancelFunc": c});
|
||||||
|
@ -322,36 +322,6 @@ export default {
|
||||||
this.getFileMetaData();
|
this.getFileMetaData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
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) {
|
handleDelete(file, index) {
|
||||||
this.$alert(this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
this.$alert(this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
||||||
confirmButtonText: this.$t('commons.confirm'),
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
@ -365,7 +335,7 @@ export default {
|
||||||
_handleDelete(file, index) {
|
_handleDelete(file, index) {
|
||||||
this.fileList.splice(index, 1);
|
this.fileList.splice(index, 1);
|
||||||
this.tableData.splice(index, 1);
|
this.tableData.splice(index, 1);
|
||||||
this.$get('/test/case/attachment/delete/' + file.id, () => {
|
this.$get('/attachment/delete/testcase/' + file.id , response => {
|
||||||
this.$success(this.$t('commons.delete_success'));
|
this.$success(this.$t('commons.delete_success'));
|
||||||
this.getFileMetaData();
|
this.getFileMetaData();
|
||||||
});
|
});
|
||||||
|
@ -390,9 +360,9 @@ export default {
|
||||||
testCaseId = id ? id : this.caseId;
|
testCaseId = id ? id : this.caseId;
|
||||||
}
|
}
|
||||||
if (testCaseId) {
|
if (testCaseId) {
|
||||||
this.result = this.$get("test/case/file/attachmentMetadata/" + testCaseId, response => {
|
let data = {'belongType': 'testcase', 'belongId': testCaseId};
|
||||||
|
this.result = this.$post("/attachment/metadata/list", data, response => {
|
||||||
let files = response.data;
|
let files = response.data;
|
||||||
|
|
||||||
if (!files) {
|
if (!files) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog :visible.sync="dialogVisible" width="80%" :destroy-on-close="true" :before-close="close" :append-to-body="true">
|
<el-dialog :visible.sync="dialogVisible" width="80%" :destroy-on-close="true" :before-close="close" :append-to-body="true">
|
||||||
<div>
|
<div>
|
||||||
<img :src="'/test/case/attachment/preview/' + file.id" :alt="$t('test_track.case.img_loading_fail')" style="width: 100%;height: 100%;"
|
<img :src="'/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'">
|
v-if="file.type === 'JPG' || file.type === 'JPEG' || file.type === 'PNG'">
|
||||||
<div v-if="file.type === 'PDF'">
|
<div v-if="file.type === 'PDF'">
|
||||||
<test-case-pdf :file-id="file.id"/>
|
<test-case-pdf :file-id="file.id"/>
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.loadingTask = pdf.createLoadingTask("/test/case/attachment/preview/" + this.fileId);
|
this.loadingTask = pdf.createLoadingTask("/attachment/preview/" + this.fileId);
|
||||||
this.loadingTask.promise.then(pdf => {
|
this.loadingTask.promise.then(pdf => {
|
||||||
this.numPages = pdf.numPages
|
this.numPages = pdf.numPages
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
|
@ -659,7 +659,7 @@ export default {
|
||||||
let file = param.file;
|
let file = param.file;
|
||||||
let progress = 0;
|
let progress = 0;
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
let requestJson = JSON.stringify({"id": this.issueId});
|
let requestJson = JSON.stringify({"belongId": this.issueId, "belongType": "issue"});
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
formData.append('request', new Blob([requestJson], {
|
formData.append('request', new Blob([requestJson], {
|
||||||
type: "application/json"
|
type: "application/json"
|
||||||
|
@ -670,7 +670,7 @@ export default {
|
||||||
axios({
|
axios({
|
||||||
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
|
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: '/issues/attachment/upload',
|
url: '/attachment/upload',
|
||||||
data: formData,
|
data: formData,
|
||||||
cancelToken: new CancelToken(function executor(c) {
|
cancelToken: new CancelToken(function executor(c) {
|
||||||
self.cancelFileToken.push({"name": file.name, "cancelFunc": c});
|
self.cancelFileToken.push({"name": file.name, "cancelFunc": c});
|
||||||
|
@ -714,36 +714,6 @@ export default {
|
||||||
this.getFileMetaData(this.issueId);
|
this.getFileMetaData(this.issueId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
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) {
|
handleDelete(file, index) {
|
||||||
this.$alert(this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
this.$alert(this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
||||||
confirmButtonText: this.$t('commons.confirm'),
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
@ -757,7 +727,8 @@ export default {
|
||||||
_handleDelete(file, index) {
|
_handleDelete(file, index) {
|
||||||
this.fileList.splice(index, 1);
|
this.fileList.splice(index, 1);
|
||||||
this.tableData.splice(index, 1);
|
this.tableData.splice(index, 1);
|
||||||
this.$get('/issues/attachment/delete/' + file.id, () => {
|
let data = {"belongId": this.issueId, "belongType": "issue"}
|
||||||
|
this.$get('/attachment/delete/issue/' + file.id , response => {
|
||||||
this.$success(this.$t('commons.delete_success'));
|
this.$success(this.$t('commons.delete_success'));
|
||||||
this.getFileMetaData(this.issueId);
|
this.getFileMetaData(this.issueId);
|
||||||
});
|
});
|
||||||
|
@ -775,7 +746,8 @@ export default {
|
||||||
this.fileList = [];
|
this.fileList = [];
|
||||||
this.tableData = [];
|
this.tableData = [];
|
||||||
if (id) {
|
if (id) {
|
||||||
this.result = this.$get("issues/file/attachmentMetadata/" + id, response => {
|
let data = {'belongType': 'issue', 'belongId': id};
|
||||||
|
this.result = this.$post("/attachment/metadata/list", data, response => {
|
||||||
let files = response.data;
|
let files = response.data;
|
||||||
if (!files) {
|
if (!files) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue