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;
|
||||
|
||||
/**
|
||||
* @author songcc
|
||||
*/
|
||||
|
||||
public enum AttachmentType {
|
||||
|
||||
TEST_CASE("testcase"), ISSUE("issue");
|
||||
/**
|
||||
* 测试用例类型
|
||||
*/
|
||||
TEST_CASE("testcase"),
|
||||
|
||||
/**
|
||||
* 缺陷类型
|
||||
*/
|
||||
ISSUE("issue");
|
||||
|
||||
// 附件类型名称
|
||||
private String type;
|
||||
|
||||
AttachmentType(String type) {
|
||||
|
|
|
@ -79,8 +79,7 @@ public class ShiroUtils {
|
|||
public static void ignoreCsrfFilter(Map<String, String> filterChainDefinitionMap) {
|
||||
filterChainDefinitionMap.put("/", "apikey, authc"); // 跳转到 / 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/language", "apikey, authc");// 跳转到 /language 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/test/case/file/preview/**", "apikey, authc"); // 预览测试用例附件 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/test/case/attachment/preview/**", "apikey, authc"); // 预览测试用例附件 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/attachment/preview/**", "apikey, authc"); // 预览测试用例附件 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/mock", "apikey, authc"); // 跳转到 /mock接口 不用校验 csrf
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
|
|||
@Resource
|
||||
private TestCaseService testCaseService;
|
||||
@Resource
|
||||
private AttachmentService attachmentService;
|
||||
@Resource
|
||||
private ApiTestCaseService apiTestCaseService;
|
||||
@Resource
|
||||
private TestPlanTestCaseService testPlanTestCaseService;
|
||||
|
@ -158,6 +160,7 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
|
|||
initOnceOperate(customFieldResourceService::compatibleData, "init.custom.field.resource");
|
||||
initOnceOperate(jarConfigService::initJarPath, "init.jar.path");
|
||||
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.PageHelper;
|
||||
import io.metersphere.base.domain.FileAttachmentMetadata;
|
||||
import io.metersphere.base.domain.Issues;
|
||||
import io.metersphere.base.domain.IssuesDao;
|
||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||
|
@ -27,10 +26,8 @@ import io.metersphere.track.request.testcase.AuthUserIssueRequest;
|
|||
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||
import io.metersphere.track.service.IssuesService;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
@ -83,22 +80,6 @@ public class IssuesController {
|
|||
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}")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_ISSUE_READ)
|
||||
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.definition.ApiTestCaseDTO;
|
||||
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.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
|
@ -371,11 +374,6 @@ public class TestCaseController {
|
|||
return fileService.getFileMetadataByCaseId(caseId);
|
||||
}
|
||||
|
||||
@GetMapping("/file/attachmentMetadata/{caseId}")
|
||||
public List<FileAttachmentMetadata> getFileAttachmentMetadataByCaseId(@PathVariable String caseId) {
|
||||
return fileService.getFileAttachmentMetadataByCaseId(caseId);
|
||||
}
|
||||
|
||||
@PostMapping("/file/download")
|
||||
public ResponseEntity<byte[]> download(@RequestBody FileOperationRequest fileOperationRequest) {
|
||||
byte[] bytes = fileService.loadFileAsBytes(fileOperationRequest.getId());
|
||||
|
@ -394,35 +392,6 @@ public class TestCaseController {
|
|||
.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")
|
||||
@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) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
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.ProjectMapper;
|
||||
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.IssuesRequest;
|
||||
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
|
||||
import io.metersphere.track.service.AttachmentService;
|
||||
import io.metersphere.track.service.IssuesService;
|
||||
import io.metersphere.track.service.TestCaseIssueService;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
|
@ -67,7 +68,8 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
|||
protected CustomFieldService customFieldService;
|
||||
protected IssuesService issuesService;
|
||||
protected FileService fileService;
|
||||
protected IssueFileMapper issueFileMapper;
|
||||
protected AttachmentService attachmentService;
|
||||
protected AttachmentModuleRelationMapper attachmentModuleRelationMapper;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
|
@ -96,7 +98,8 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
|||
this.customFieldService = CommonBeanFactory.getBean(CustomFieldService.class);
|
||||
this.issuesService = CommonBeanFactory.getBean(IssuesService.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) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.track.issue;
|
|||
import io.metersphere.base.domain.IssuesDao;
|
||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||
import io.metersphere.dto.IssueTemplateDao;
|
||||
import io.metersphere.dto.UserDTO;
|
||||
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 org.springframework.http.ResponseEntity;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public interface IssuesPlatform {
|
||||
|
@ -113,4 +115,12 @@ public interface IssuesPlatform {
|
|||
* @return
|
||||
*/
|
||||
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 io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||
import io.metersphere.commons.constants.AttachmentType;
|
||||
import io.metersphere.commons.constants.CustomFieldType;
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.constants.IssuesStatus;
|
||||
import io.metersphere.commons.constants.*;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
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.ProjectIssueConfig;
|
||||
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.IssuesUpdateRequest;
|
||||
import io.metersphere.track.service.IssuesService;
|
||||
|
@ -243,15 +241,15 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
// 用例与第三方缺陷平台中的缺陷关联
|
||||
handleTestCaseIssues(issuesRequest);
|
||||
|
||||
// 如果是复制新增, 同步附件到第三方平台
|
||||
// 如果是复制新增, 同步MS附件到Jira
|
||||
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
||||
IssueFileExample example = new IssueFileExample();
|
||||
example.createCriteria().andIssueIdEqualTo(issuesRequest.getCopyIssueId());
|
||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(example);
|
||||
if (issueFiles != null) {
|
||||
issueFiles.forEach(issueFile -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.getFileAttachmentMetadataByFileId(issueFile.getFileId());
|
||||
// 同步第三方平台附件
|
||||
AttachmentRequest request = new AttachmentRequest();
|
||||
request.setBelongId(issuesRequest.getCopyIssueId());
|
||||
request.setBelongType(AttachmentType.ISSUE.type());
|
||||
List<String> attachmentIds = attachmentService.getAttachmentIdsByParam(request);
|
||||
if (CollectionUtils.isNotEmpty(attachmentIds)) {
|
||||
attachmentIds.forEach(attachmentId -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.getFileAttachmentMetadataByFileId(attachmentId);
|
||||
File file = new File(fileAttachmentMetadata.getFilePath() + "/" + fileAttachmentMetadata.getName());
|
||||
jiraClientV2.uploadAttachment(result.getKey(), file);
|
||||
});
|
||||
|
@ -474,46 +472,9 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
public void updateIssue(IssuesUpdateRequest request) {
|
||||
setUserConfig();
|
||||
Project project = getProject();
|
||||
List<File> imageFiles = getImageFiles(request);
|
||||
|
||||
JSONObject param = buildUpdateParam(request, getIssueType(project.getIssueConfig()), project.getJiraKey());
|
||||
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) {
|
||||
try {
|
||||
List<JiraTransitionsResponse.Transitions> transitions = jiraClientV2.getTransitions(request.getPlatformId());
|
||||
|
@ -873,8 +834,35 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
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) {
|
||||
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");
|
||||
if (CollectionUtils.isEmpty(attachments)) {
|
||||
return;
|
||||
|
@ -882,14 +870,16 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
for (int i = 0; i < attachments.size(); i++) {
|
||||
JSONObject attachment = attachments.getJSONObject(i);
|
||||
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");
|
||||
byte[] content = jiraClientV2.getAttachmentContent(id);
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.saveAttachmentByBytes(content, AttachmentType.ISSUE.type(), issue.getId(), filename);
|
||||
IssueFile issueFile = new IssueFile();
|
||||
issueFile.setIssueId(issue.getId());
|
||||
issueFile.setFileId(fileAttachmentMetadata.getId());
|
||||
issueFileMapper.insert(issueFile);
|
||||
AttachmentModuleRelation attachmentModuleRelation = new AttachmentModuleRelation();
|
||||
attachmentModuleRelation.setAttachmentId(fileAttachmentMetadata.getId());
|
||||
attachmentModuleRelation.setRelationId(issue.getId());
|
||||
attachmentModuleRelation.setRelationType(AttachmentType.ISSUE.type());
|
||||
attachmentModuleRelationMapper.insert(attachmentModuleRelation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.track.issue;
|
|||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.base.domain.IssuesDao;
|
||||
import io.metersphere.base.domain.IssuesWithBLOBs;
|
||||
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.user.SessionUser;
|
||||
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 org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -78,4 +80,10 @@ public class LocalPlatform extends LocalAbstractPlatform {
|
|||
public void updateIssue(IssuesUpdateRequest 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.Project;
|
||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.constants.IssuesStatus;
|
||||
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.MultiValueMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
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
|
||||
public List<PlatformStatusDTO> getTransitions(String issueKey) {
|
||||
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.Project;
|
||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||
import io.metersphere.commons.constants.AttachmentSyncType;
|
||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||
import io.metersphere.commons.constants.IssuesStatus;
|
||||
import io.metersphere.commons.constants.ZentaoIssuePlatformStatus;
|
||||
|
@ -38,6 +39,7 @@ import org.springframework.util.LinkedMultiValueMap;
|
|||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -537,6 +539,11 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
|
|||
return zentaoClient.checkProjectExist(relateId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncIssuesAttachment(IssuesUpdateRequest issuesRequest, File file, AttachmentSyncType syncType) {
|
||||
// TODO: 同步缺陷MS附件到禅道
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlatformStatusDTO> getTransitions(String issueKey) {
|
||||
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.jira.JiraIssueType;
|
||||
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.PlatformIssueTypeRequest;
|
||||
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.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
@ -91,6 +91,8 @@ public class IssuesService {
|
|||
IssueFileMapper issueFileMapper;
|
||||
@Resource
|
||||
private FileAttachmentMetadataMapper fileAttachmentMetadataMapper;
|
||||
@Resource
|
||||
private AttachmentService attachmentService;
|
||||
|
||||
private static final String SYNC_THIRD_PARTY_ISSUES_KEY = "ISSUE:SYNC";
|
||||
|
||||
|
@ -116,22 +118,13 @@ public class IssuesService {
|
|||
saveFollows(issuesRequest.getId(), issuesRequest.getFollows());
|
||||
customFieldIssuesService.addFields(issuesRequest.getId(), issuesRequest.getAddFields());
|
||||
customFieldIssuesService.editFields(issuesRequest.getId(), issuesRequest.getEditFields());
|
||||
// copy附件
|
||||
// 复制新增, 同步缺陷的MS附件
|
||||
if (StringUtils.isNotEmpty(issuesRequest.getCopyIssueId())) {
|
||||
final String addIssueId = issues.getId();
|
||||
IssueFileExample example = new IssueFileExample();
|
||||
example.createCriteria().andIssueIdEqualTo(issuesRequest.getCopyIssueId());
|
||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(example);
|
||||
if (issueFiles != null) {
|
||||
issueFiles.forEach(issueFile -> {
|
||||
// 同步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);
|
||||
});
|
||||
}
|
||||
AttachmentRequest attachmentRequest = new AttachmentRequest();
|
||||
attachmentRequest.setCopyBelongId(issuesRequest.getCopyIssueId());
|
||||
attachmentRequest.setBelongId(issues.getId());
|
||||
attachmentRequest.setBelongType(AttachmentType.ISSUE.type());
|
||||
attachmentService.copyAttachment(attachmentRequest);
|
||||
}
|
||||
return issues;
|
||||
}
|
||||
|
@ -145,31 +138,6 @@ public class IssuesService {
|
|||
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) {
|
||||
IssueFollowExample example = new IssueFollowExample();
|
||||
example.createCriteria().andIssueIdEqualTo(issueId);
|
||||
|
@ -369,17 +337,10 @@ public class IssuesService {
|
|||
AbstractIssuePlatform platform = IssueFactory.createPlatform(issuesWithBLOBs.getPlatform(), issuesRequest);
|
||||
platform.deleteIssue(id);
|
||||
// 删除缺陷对应的附件
|
||||
fileService.deleteAttachment(AttachmentType.ISSUE.type(), id);
|
||||
IssueFileExample issueFileExample = new IssueFileExample();
|
||||
issueFileExample.createCriteria().andIssueIdEqualTo(id);
|
||||
List<IssueFile> issueFiles = issueFileMapper.selectByExample(issueFileExample);
|
||||
List<String> fileIds = issueFiles.stream().map(IssueFile::getFileId).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(fileIds)) {
|
||||
FileAttachmentMetadataExample fileAttachmentMetadataExample = new FileAttachmentMetadataExample();
|
||||
fileAttachmentMetadataExample.createCriteria().andIdIn(fileIds);
|
||||
fileAttachmentMetadataMapper.deleteByExample(fileAttachmentMetadataExample);
|
||||
}
|
||||
issueFileMapper.deleteByExample(issueFileExample);
|
||||
AttachmentRequest request = new AttachmentRequest();
|
||||
request.setBelongId(id);
|
||||
request.setBelongType(AttachmentType.ISSUE.type());
|
||||
attachmentService.deleteAttachment(request);
|
||||
}
|
||||
|
||||
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.IssueFactory;
|
||||
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.testplan.LoadCaseRequest;
|
||||
import io.metersphere.xmind.XmindCaseParser;
|
||||
|
@ -182,6 +183,8 @@ public class TestCaseService {
|
|||
private FileMetadataMapper fileMetadataMapper;
|
||||
@Resource
|
||||
private FileContentMapper fileContentMapper;
|
||||
@Resource
|
||||
private AttachmentService attachmentService;
|
||||
|
||||
private ThreadLocal<Integer> importCreateNum = new ThreadLocal<>();
|
||||
private ThreadLocal<Integer> beforeImportCreateNum = new ThreadLocal<>();
|
||||
|
@ -614,17 +617,10 @@ public class TestCaseService {
|
|||
customFieldTestCaseService.deleteByResourceId(testCaseId); // 删除自定义字段关联关系
|
||||
functionCaseExecutionInfoService.deleteBySourceId(testCaseId);
|
||||
// 删除用例附件关联数据, 附件内容
|
||||
TestCaseFileExample testCaseFileExample = new TestCaseFileExample();
|
||||
testCaseFileExample.createCriteria().andCaseIdEqualTo(testCaseId);
|
||||
List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(testCaseFileExample);
|
||||
List<String> fileIds = testCaseFiles.stream().map(TestCaseFile::getFileId).collect(Collectors.toList());
|
||||
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);
|
||||
AttachmentRequest request = new AttachmentRequest();
|
||||
request.setBelongId(testCaseId);
|
||||
request.setBelongType(AttachmentType.TEST_CASE.type());
|
||||
attachmentService.deleteAttachment(request);
|
||||
return testCaseMapper.deleteByPrimaryKey(testCaseId);
|
||||
}
|
||||
|
||||
|
@ -1987,18 +1983,11 @@ public class TestCaseService {
|
|||
final TestCaseWithBLOBs testCaseWithBLOBs = addTestCase(request);
|
||||
// 复制用例时复制对应附件数据
|
||||
if (StringUtils.isNotEmpty(request.getCopyCaseId())) {
|
||||
TestCaseFileExample example = new TestCaseFileExample();
|
||||
example.createCriteria().andCaseIdEqualTo(request.getCopyCaseId());
|
||||
List<TestCaseFile> testCaseFiles = testCaseFileMapper.selectByExample(example);
|
||||
if (testCaseFiles != null) {
|
||||
testCaseFiles.forEach(testCaseFile -> {
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileService.copyAttachment(testCaseFile.getFileId(), AttachmentType.TEST_CASE.type(), testCaseWithBLOBs.getId());
|
||||
TestCaseFile newTestCaseFile = new TestCaseFile();
|
||||
newTestCaseFile.setCaseId(testCaseWithBLOBs.getId());
|
||||
newTestCaseFile.setFileId(fileAttachmentMetadata.getId());
|
||||
testCaseFileMapper.insert(newTestCaseFile);
|
||||
});
|
||||
}
|
||||
AttachmentRequest attachmentRequest = new AttachmentRequest();
|
||||
attachmentRequest.setCopyBelongId(request.getCopyCaseId());
|
||||
attachmentRequest.setBelongId(testCaseWithBLOBs.getId());
|
||||
attachmentRequest.setBelongType(AttachmentType.TEST_CASE.type());
|
||||
attachmentService.copyAttachment(attachmentRequest);
|
||||
}
|
||||
return testCaseWithBLOBs;
|
||||
}
|
||||
|
@ -2051,32 +2040,6 @@ public class TestCaseService {
|
|||
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) {
|
||||
String testCaseId = testPlanTestCaseMapper.selectByPrimaryKey(request.getId()).getCaseId();
|
||||
request.setId(testCaseId);
|
||||
|
|
|
@ -121,7 +121,7 @@ export default {
|
|||
id: file.id,
|
||||
};
|
||||
let config = {
|
||||
url: '/test/case/attachment/download',
|
||||
url: '/attachment/download',
|
||||
method: 'post',
|
||||
data: data,
|
||||
responseType: 'blob'
|
||||
|
|
|
@ -267,7 +267,7 @@ export default {
|
|||
let file = param.file;
|
||||
let progress = 0;
|
||||
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('request', new Blob([requestJson], {
|
||||
type: "application/json"
|
||||
|
@ -278,7 +278,7 @@ export default {
|
|||
axios({
|
||||
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
|
||||
method: 'post',
|
||||
url: '/test/case/attachment/upload',
|
||||
url: '/attachment/upload',
|
||||
data: formData,
|
||||
cancelToken: new CancelToken(function executor(c) {
|
||||
self.cancelFileToken.push({"name": file.name, "cancelFunc": c});
|
||||
|
@ -322,36 +322,6 @@ export default {
|
|||
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) {
|
||||
this.$alert(this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
|
@ -365,7 +335,7 @@ export default {
|
|||
_handleDelete(file, index) {
|
||||
this.fileList.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.getFileMetaData();
|
||||
});
|
||||
|
@ -390,9 +360,9 @@ export default {
|
|||
testCaseId = id ? id : this.caseId;
|
||||
}
|
||||
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;
|
||||
|
||||
if (!files) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogVisible" width="80%" :destroy-on-close="true" :before-close="close" :append-to-body="true">
|
||||
<div>
|
||||
<img :src="'/test/case/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'">
|
||||
<div v-if="file.type === 'PDF'">
|
||||
<test-case-pdf :file-id="file.id"/>
|
||||
|
|
|
@ -21,7 +21,7 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
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.numPages = pdf.numPages
|
||||
this.loading = false;
|
||||
|
|
|
@ -659,7 +659,7 @@ export default {
|
|||
let file = param.file;
|
||||
let progress = 0;
|
||||
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('request', new Blob([requestJson], {
|
||||
type: "application/json"
|
||||
|
@ -670,7 +670,7 @@ export default {
|
|||
axios({
|
||||
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
|
||||
method: 'post',
|
||||
url: '/issues/attachment/upload',
|
||||
url: '/attachment/upload',
|
||||
data: formData,
|
||||
cancelToken: new CancelToken(function executor(c) {
|
||||
self.cancelFileToken.push({"name": file.name, "cancelFunc": c});
|
||||
|
@ -714,36 +714,6 @@ export default {
|
|||
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) {
|
||||
this.$alert(this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
|
@ -757,7 +727,8 @@ export default {
|
|||
_handleDelete(file, index) {
|
||||
this.fileList.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.getFileMetaData(this.issueId);
|
||||
});
|
||||
|
@ -775,7 +746,8 @@ export default {
|
|||
this.fileList = [];
|
||||
this.tableData = [];
|
||||
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;
|
||||
if (!files) {
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue