refactor(项目设置): 补充模板相关接口
This commit is contained in:
parent
0c97f714a8
commit
d4d7307819
|
@ -37,9 +37,7 @@ public class StatusItem implements Serializable {
|
|||
@Size(min = 1, max = 50, message = "{status_item.scope_type.length_range}", groups = {Created.class, Updated.class})
|
||||
private String scopeType;
|
||||
|
||||
@Schema(description = "项目状态所关联的组织状态ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{status_item.ref_id.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 50, message = "{status_item.ref_id.length_range}", groups = {Created.class, Updated.class})
|
||||
@Schema(description = "项目状态所关联的组织状态ID")
|
||||
private String refId;
|
||||
|
||||
@Schema(description = "组织或项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
|
|
|
@ -50,10 +50,6 @@ public class Template implements Serializable {
|
|||
@NotNull(message = "{template.enable_third_part.not_blank}", groups = {Created.class})
|
||||
private Boolean enableThirdPart;
|
||||
|
||||
@Schema(description = "是否是默认模板", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "{template.enable_default.not_blank}", groups = {Created.class})
|
||||
private Boolean enableDefault;
|
||||
|
||||
@Schema(description = "项目模板所关联的组织模板ID")
|
||||
private String refId;
|
||||
|
||||
|
@ -75,7 +71,6 @@ public class Template implements Serializable {
|
|||
scopeType("scope_type", "scopeType", "VARCHAR", false),
|
||||
scopeId("scope_id", "scopeId", "VARCHAR", false),
|
||||
enableThirdPart("enable_third_part", "enableThirdPart", "BIT", false),
|
||||
enableDefault("enable_default", "enableDefault", "BIT", false),
|
||||
refId("ref_id", "refId", "VARCHAR", false),
|
||||
scene("scene", "scene", "VARCHAR", false);
|
||||
|
||||
|
|
|
@ -764,66 +764,6 @@ public class TemplateExample {
|
|||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultIsNull() {
|
||||
addCriterion("enable_default is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultIsNotNull() {
|
||||
addCriterion("enable_default is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultEqualTo(Boolean value) {
|
||||
addCriterion("enable_default =", value, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultNotEqualTo(Boolean value) {
|
||||
addCriterion("enable_default <>", value, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultGreaterThan(Boolean value) {
|
||||
addCriterion("enable_default >", value, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultGreaterThanOrEqualTo(Boolean value) {
|
||||
addCriterion("enable_default >=", value, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultLessThan(Boolean value) {
|
||||
addCriterion("enable_default <", value, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultLessThanOrEqualTo(Boolean value) {
|
||||
addCriterion("enable_default <=", value, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultIn(List<Boolean> values) {
|
||||
addCriterion("enable_default in", values, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultNotIn(List<Boolean> values) {
|
||||
addCriterion("enable_default not in", values, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultBetween(Boolean value1, Boolean value2) {
|
||||
addCriterion("enable_default between", value1, value2, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnableDefaultNotBetween(Boolean value1, Boolean value2) {
|
||||
addCriterion("enable_default not between", value1, value2, "enableDefault");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdIsNull() {
|
||||
addCriterion("ref_id is null");
|
||||
return (Criteria) this;
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
<result column="scope_type" jdbcType="VARCHAR" property="scopeType" />
|
||||
<result column="scope_id" jdbcType="VARCHAR" property="scopeId" />
|
||||
<result column="enable_third_part" jdbcType="BIT" property="enableThirdPart" />
|
||||
<result column="enable_default" jdbcType="BIT" property="enableDefault" />
|
||||
<result column="ref_id" jdbcType="VARCHAR" property="refId" />
|
||||
<result column="scene" jdbcType="VARCHAR" property="scene" />
|
||||
</resultMap>
|
||||
|
@ -76,7 +75,7 @@
|
|||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, `name`, remark, internal, update_time, create_time, create_user, scope_type,
|
||||
scope_id, enable_third_part, enable_default, ref_id, scene
|
||||
scope_id, enable_third_part, ref_id, scene
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.system.domain.TemplateExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -112,13 +111,13 @@
|
|||
insert into template (id, `name`, remark,
|
||||
internal, update_time, create_time,
|
||||
create_user, scope_type, scope_id,
|
||||
enable_third_part, enable_default, ref_id,
|
||||
scene)
|
||||
enable_third_part, ref_id, scene
|
||||
)
|
||||
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR},
|
||||
#{internal,jdbcType=BIT}, #{updateTime,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT},
|
||||
#{createUser,jdbcType=VARCHAR}, #{scopeType,jdbcType=VARCHAR}, #{scopeId,jdbcType=VARCHAR},
|
||||
#{enableThirdPart,jdbcType=BIT}, #{enableDefault,jdbcType=BIT}, #{refId,jdbcType=VARCHAR},
|
||||
#{scene,jdbcType=VARCHAR})
|
||||
#{enableThirdPart,jdbcType=BIT}, #{refId,jdbcType=VARCHAR}, #{scene,jdbcType=VARCHAR}
|
||||
)
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.system.domain.Template">
|
||||
insert into template
|
||||
|
@ -153,9 +152,6 @@
|
|||
<if test="enableThirdPart != null">
|
||||
enable_third_part,
|
||||
</if>
|
||||
<if test="enableDefault != null">
|
||||
enable_default,
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
ref_id,
|
||||
</if>
|
||||
|
@ -194,9 +190,6 @@
|
|||
<if test="enableThirdPart != null">
|
||||
#{enableThirdPart,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="enableDefault != null">
|
||||
#{enableDefault,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
#{refId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
|
@ -244,9 +237,6 @@
|
|||
<if test="record.enableThirdPart != null">
|
||||
enable_third_part = #{record.enableThirdPart,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="record.enableDefault != null">
|
||||
enable_default = #{record.enableDefault,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="record.refId != null">
|
||||
ref_id = #{record.refId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
|
@ -270,7 +260,6 @@
|
|||
scope_type = #{record.scopeType,jdbcType=VARCHAR},
|
||||
scope_id = #{record.scopeId,jdbcType=VARCHAR},
|
||||
enable_third_part = #{record.enableThirdPart,jdbcType=BIT},
|
||||
enable_default = #{record.enableDefault,jdbcType=BIT},
|
||||
ref_id = #{record.refId,jdbcType=VARCHAR},
|
||||
scene = #{record.scene,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
|
@ -307,9 +296,6 @@
|
|||
<if test="enableThirdPart != null">
|
||||
enable_third_part = #{enableThirdPart,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="enableDefault != null">
|
||||
enable_default = #{enableDefault,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
ref_id = #{refId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
|
@ -330,7 +316,6 @@
|
|||
scope_type = #{scopeType,jdbcType=VARCHAR},
|
||||
scope_id = #{scopeId,jdbcType=VARCHAR},
|
||||
enable_third_part = #{enableThirdPart,jdbcType=BIT},
|
||||
enable_default = #{enableDefault,jdbcType=BIT},
|
||||
ref_id = #{refId,jdbcType=VARCHAR},
|
||||
scene = #{scene,jdbcType=VARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
|
@ -338,14 +323,14 @@
|
|||
<insert id="batchInsert" parameterType="map">
|
||||
insert into template
|
||||
(id, `name`, remark, internal, update_time, create_time, create_user, scope_type,
|
||||
scope_id, enable_third_part, enable_default, ref_id, scene)
|
||||
scope_id, enable_third_part, ref_id, scene)
|
||||
values
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(#{item.id,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, #{item.remark,jdbcType=VARCHAR},
|
||||
#{item.internal,jdbcType=BIT}, #{item.updateTime,jdbcType=BIGINT}, #{item.createTime,jdbcType=BIGINT},
|
||||
#{item.createUser,jdbcType=VARCHAR}, #{item.scopeType,jdbcType=VARCHAR}, #{item.scopeId,jdbcType=VARCHAR},
|
||||
#{item.enableThirdPart,jdbcType=BIT}, #{item.enableDefault,jdbcType=BIT}, #{item.refId,jdbcType=VARCHAR},
|
||||
#{item.scene,jdbcType=VARCHAR})
|
||||
#{item.enableThirdPart,jdbcType=BIT}, #{item.refId,jdbcType=VARCHAR}, #{item.scene,jdbcType=VARCHAR}
|
||||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
<insert id="batchInsertSelective" parameterType="map">
|
||||
|
@ -388,9 +373,6 @@
|
|||
<if test="'enable_third_part'.toString() == column.value">
|
||||
#{item.enableThirdPart,jdbcType=BIT}
|
||||
</if>
|
||||
<if test="'enable_default'.toString() == column.value">
|
||||
#{item.enableDefault,jdbcType=BIT}
|
||||
</if>
|
||||
<if test="'ref_id'.toString() == column.value">
|
||||
#{item.refId,jdbcType=VARCHAR}
|
||||
</if>
|
||||
|
|
|
@ -383,16 +383,14 @@ CREATE TABLE IF NOT EXISTS template(
|
|||
`scope_type` VARCHAR(50) NOT NULL COMMENT '组织或项目级别字段(PROJECT, ORGANIZATION)' ,
|
||||
`scope_id` VARCHAR(50) NOT NULL COMMENT '组织或项目ID' ,
|
||||
`enable_third_part` BIT NOT NULL DEFAULT 0 COMMENT '是否开启api字段名配置' ,
|
||||
`enable_default` BIT NOT NULL DEFAULT 0 COMMENT '是否是默认模板' ,
|
||||
`ref_id` VARCHAR(50) COMMENT '项目模板所关联的组织模板ID' ,
|
||||
`scene` VARCHAR(30) NOT NULL COMMENT '使用场景' ,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci
|
||||
COMMENT = '模版';
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '模版';
|
||||
|
||||
CREATE INDEX idx_scope_id ON template(scope_id);
|
||||
CREATE INDEX idx_scope_id_scene ON template(`scope_id`,`scene`);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS template_custom_field(
|
||||
`id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
|
||||
|
|
|
@ -145,8 +145,8 @@ INSERT INTO custom_field_option (field_id,value,`text`,internal)
|
|||
VALUES ((select id from custom_field where name = 'functional_priority'), 'P3', 'P3', 1);
|
||||
|
||||
-- 初始化组织功能用例模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,enable_default, scene)
|
||||
VALUES (UUID_SHORT(), 'functional_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 1, 'FUNCTIONAL');
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, scene)
|
||||
VALUES (UUID_SHORT(), 'functional_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 'FUNCTIONAL');
|
||||
INSERT INTO template_custom_field(id, field_id, template_id, required, pos, api_field_id, default_value)
|
||||
VALUES(UUID_SHORT(), (select id from custom_field where name = 'functional_priority'), (select id from template where name = 'functional_default'), 1, 0, NULL, NULL);
|
||||
|
||||
|
@ -167,8 +167,8 @@ INSERT INTO custom_field_option (field_id,value,`text`,internal)
|
|||
VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P3', 'P3', 1);
|
||||
|
||||
-- 初始化项目功能用例模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, enable_default, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'functional_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 1, 'FUNCTIONAL',
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'functional_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 'FUNCTIONAL',
|
||||
(SELECT id FROM (SELECT * FROM template) t where name = 'functional_default'));
|
||||
INSERT INTO template_custom_field(id, field_id, template_id, required, pos, api_field_id, default_value)
|
||||
VALUES(
|
||||
|
@ -179,39 +179,39 @@ VALUES(
|
|||
);
|
||||
|
||||
-- 初始化组织缺陷模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,enable_default,scene)
|
||||
VALUES (UUID_SHORT(), 'bug_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 1, 'BUG');
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,scene)
|
||||
VALUES (UUID_SHORT(), 'bug_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 'BUG');
|
||||
|
||||
-- 初始化项目缺陷模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, enable_default, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'bug_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 1, 'BUG',
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'bug_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 'BUG',
|
||||
(SELECT id FROM (SELECT * FROM template) t where name = 'bug_default'));
|
||||
|
||||
-- 初始化组织接口模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,enable_default,scene)
|
||||
VALUES (UUID_SHORT(), 'api_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 1, 'API');
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,scene)
|
||||
VALUES (UUID_SHORT(), 'api_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 'API');
|
||||
|
||||
-- 初始化项目接口模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, enable_default, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'api_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 1, 'API',
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'api_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 'API',
|
||||
(SELECT id FROM (SELECT * FROM template) t where name = 'api_default'));
|
||||
|
||||
-- 初始化组织UI模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,enable_default,scene)
|
||||
VALUES (UUID_SHORT(), 'ui_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 1, 'UI');
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,scene)
|
||||
VALUES (UUID_SHORT(), 'ui_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 'UI');
|
||||
|
||||
-- 初始化项目UI模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, enable_default, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'ui_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 1, 'UI',
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'ui_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 'UI',
|
||||
(SELECT id FROM (SELECT * FROM template) t where name = 'ui_default'));
|
||||
|
||||
-- 初始化组织测试计划模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,enable_default,scene)
|
||||
VALUES (UUID_SHORT(), 'test_plan_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 1, 'TEST_PLAN');
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part,scene)
|
||||
VALUES (UUID_SHORT(), 'test_plan_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 'TEST_PLAN');
|
||||
|
||||
-- 初始化项目测试计划模板
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, enable_default, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'test_plan_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 1, 'TEST_PLAN',
|
||||
INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, scene, ref_id)
|
||||
VALUES (UUID_SHORT(), 'test_plan_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 'TEST_PLAN',
|
||||
(SELECT id FROM (SELECT * FROM template) t where name = 'test_plan_default'));
|
||||
|
||||
-- 初始化组织缺陷状态项
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package io.metersphere.plugin.platform.spi;
|
||||
|
||||
import io.metersphere.plugin.platform.dto.PlatformCustomFieldItemDTO;
|
||||
import org.pf4j.ExtensionPoint;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 平台对接相关业务接口
|
||||
* @author jianxing.chen
|
||||
|
@ -19,4 +22,17 @@ public interface Platform extends ExtensionPoint {
|
|||
* 项目设置成点击校验项目 key 时调用
|
||||
*/
|
||||
void validateProjectConfig(String projectConfig);
|
||||
|
||||
/**
|
||||
* 插件是否支持第三方模板
|
||||
* @return
|
||||
*/
|
||||
boolean isThirdPartTemplateSupport();
|
||||
|
||||
/**
|
||||
* 获取第三方平台缺陷的自定义字段
|
||||
* 需要 PluginMetaInfo 的 isThirdPartTemplateSupport 返回 true
|
||||
* @return
|
||||
*/
|
||||
List<PlatformCustomFieldItemDTO> getThirdPartCustomField(String projectConfig);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.sdk.constants;
|
||||
|
||||
/**
|
||||
* 系统内置用户ID
|
||||
* @author jianxing
|
||||
*/
|
||||
public enum InternalUser {
|
||||
|
||||
ADMIN("admin");
|
||||
|
||||
private String value;
|
||||
|
||||
InternalUser(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package io.metersphere.sdk.constants;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 应用设置 -相关配置
|
||||
*/
|
||||
|
@ -81,4 +83,22 @@ public class ProjectApplicationType {
|
|||
VERSION_ENABLE
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录项目中配置的默认模板
|
||||
*/
|
||||
public enum DEFAULT_TEMPLATE{
|
||||
FUNCTIONAL_DEFAULT_TEMPLATE,
|
||||
BUG_DEFAULT_TEMPLATE,
|
||||
API_DEFAULT_TEMPLATE,
|
||||
UI_DEFAULT_TEMPLATE,
|
||||
TEST_PLAN_DEFAULT_TEMPLATE;
|
||||
|
||||
public static DEFAULT_TEMPLATE getByTemplateScene(String scene) {
|
||||
return Arrays.stream(DEFAULT_TEMPLATE.values())
|
||||
.filter(e -> e.name().startsWith(scene))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package io.metersphere.sdk.dto;
|
||||
|
||||
import io.metersphere.system.domain.Template;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class TemplateDTO extends Template {
|
||||
@Schema(description = "相关的自定义字段")
|
||||
List<TemplateCustomFieldDTO> customFields;
|
||||
}
|
||||
|
|
|
@ -445,7 +445,7 @@ template_scene_illegal_error=使用场景不合法
|
|||
|
||||
# 内置的模板或字段
|
||||
custom_field.functional_priority=优先级
|
||||
template.functional_default=默认模板
|
||||
template.default=默认模板
|
||||
|
||||
parent.node.not_blank=父节点不能为空
|
||||
node.not_blank=节点不能为空
|
||||
|
|
|
@ -448,7 +448,7 @@ scheduled_tasks=Scheduled Tasks
|
|||
template_scene_illegal_error=Scene is illegal
|
||||
# 内置的模板或字段
|
||||
custom_field.functional_priority=Priority
|
||||
template.functional_default=Default
|
||||
template.default=Default
|
||||
|
||||
set_default_template=Set the default template
|
||||
project_template_enable=Enable the project template
|
||||
|
|
|
@ -446,7 +446,7 @@ scheduled_tasks=定时任务
|
|||
template_scene_illegal_error=使用场景不合法
|
||||
# 内置的模板或字段
|
||||
custom_field.functional_priority=优先级
|
||||
template.functional_default=默认模板
|
||||
template.default=默认模板
|
||||
|
||||
set_default_template=设置默认模板
|
||||
project_template_enable=开启项目模板
|
||||
|
|
|
@ -445,7 +445,7 @@ template_scene_illegal_error=使用場景不合法
|
|||
|
||||
# 内置的模板或字段
|
||||
custom_field.functional_priority=優先級
|
||||
template.functional_default=默認模板
|
||||
template.default=默認模板
|
||||
|
||||
set_default_template=設置默認模板
|
||||
project_template_enable=開啟項目模板
|
||||
|
|
|
@ -310,4 +310,6 @@ file.name.cannot.be.empty=文件名称不能为空
|
|||
|
||||
# template
|
||||
project_template_permission_error=未开启项目模板
|
||||
plugin_bug_template_remark=模板为系统自动获取,不支持编辑和查看
|
||||
|
||||
|
||||
|
|
|
@ -344,3 +344,4 @@ file.name.cannot.be.empty=File name cannot be empty
|
|||
# template
|
||||
project_template_permission_error=The project template is not turned on
|
||||
third_part_config_is_null=Third party configuration cannot be empty
|
||||
plugin_bug_template_remark=Templates are automatically obtained by the system and do not support editing and viewing
|
||||
|
|
|
@ -344,3 +344,4 @@ file.name.cannot.be.empty=文件名称不能为空
|
|||
project_template_permission_error=未开启项目模板
|
||||
|
||||
third_part_config_is_null=第三方平台配置信息不能为空
|
||||
plugin_bug_template_remark=模板为系统自动获取,不支持编辑和查看
|
||||
|
|
|
@ -343,3 +343,4 @@ file.name.cannot.be.empty=文件名稱不能為空
|
|||
# template
|
||||
project_template_permission_error=未開啟項目模板
|
||||
third_part_config_is_null=第三方平臺配置信息不能爲空
|
||||
plugin_bug_template_remark=模板為系統自動獲取,不支持編輯和查看
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.project.controller;
|
||||
|
||||
import io.metersphere.project.dto.ProjectTemplateDTO;
|
||||
import io.metersphere.project.service.ProjectTemplateLogService;
|
||||
import io.metersphere.project.service.ProjectTemplateService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
|
@ -37,7 +38,7 @@ public class ProjectTemplateController {
|
|||
@GetMapping("/list/{projectId}/{scene}")
|
||||
@Operation(summary = "获取模版列表")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TEMPLATE_READ)
|
||||
public List<Template> list(@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
public List<ProjectTemplateDTO> list(@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@PathVariable String projectId,
|
||||
@Schema(description = "模板的使用场景(FUNCTIONAL,BUG,API,UI,TEST_PLAN)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@PathVariable String scene) {
|
||||
|
@ -48,7 +49,7 @@ public class ProjectTemplateController {
|
|||
@Operation(summary = "获取模版详情")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TEMPLATE_READ)
|
||||
public TemplateDTO get(@PathVariable String id) {
|
||||
return projectTemplateservice.geDTOWithCheck(id);
|
||||
return projectTemplateservice.geTemplateDTOWithCheck(id);
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
|
@ -80,11 +81,11 @@ public class ProjectTemplateController {
|
|||
projectTemplateservice.delete(id);
|
||||
}
|
||||
|
||||
@GetMapping("/set-default/{id}")
|
||||
@GetMapping("/set-default/{projectId}/{id}")
|
||||
@Operation(summary = "设置模板模板")
|
||||
@RequiresPermissions(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE)
|
||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.setDefaultTemplateLog(#id)", msClass = ProjectTemplateLogService.class)
|
||||
public void setDefaultTemplate(@PathVariable String id) {
|
||||
projectTemplateservice.setDefaultTemplate(id);
|
||||
public void setDefaultTemplate(@PathVariable String projectId, @PathVariable String id) {
|
||||
projectTemplateservice.setDefaultTemplate(projectId, id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.project.dto;
|
||||
|
||||
import io.metersphere.system.domain.Template;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-10-19 16:46
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ProjectTemplateDTO extends Template implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "是否是默认模板")
|
||||
private Boolean enableDefault = false;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.project.dto;
|
||||
|
||||
import io.metersphere.sdk.dto.OptionDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-10-19 16:46
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ProjectTemplateOptionDTO extends OptionDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "是否是默认模板")
|
||||
private Boolean enableDefault;
|
||||
}
|
|
@ -87,7 +87,7 @@ public class ProjectApplicationService {
|
|||
this.createOrUpdateConfig(application);
|
||||
}
|
||||
|
||||
private void createOrUpdateConfig(ProjectApplication application) {
|
||||
public void createOrUpdateConfig(ProjectApplication application) {
|
||||
String type = application.getType();
|
||||
String projectId = application.getProjectId();
|
||||
ProjectApplicationExample example = new ProjectApplicationExample();
|
||||
|
@ -546,4 +546,10 @@ public class ProjectApplicationService {
|
|||
return null;
|
||||
}
|
||||
|
||||
public ProjectApplication getByType(String projectId, String type) {
|
||||
ProjectApplicationExample example = new ProjectApplicationExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andTypeEqualTo(type);
|
||||
List<ProjectApplication> projectApplications = projectApplicationMapper.selectByExample(example);
|
||||
return CollectionUtils.isEmpty(projectApplications) ? null : projectApplications.get(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,41 @@
|
|||
package io.metersphere.project.service;
|
||||
|
||||
import io.metersphere.plugin.platform.spi.Platform;
|
||||
import io.metersphere.plugin.sdk.spi.MsPlugin;
|
||||
import io.metersphere.project.domain.ProjectApplication;
|
||||
import io.metersphere.project.dto.ProjectTemplateDTO;
|
||||
import io.metersphere.project.dto.ProjectTemplateOptionDTO;
|
||||
import io.metersphere.sdk.constants.InternalUser;
|
||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||
import io.metersphere.sdk.constants.TemplateScene;
|
||||
import io.metersphere.sdk.constants.TemplateScopeType;
|
||||
import io.metersphere.sdk.dto.TemplateDTO;
|
||||
import io.metersphere.sdk.dto.request.TemplateCustomFieldRequest;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.Plugin;
|
||||
import io.metersphere.system.domain.ServiceIntegration;
|
||||
import io.metersphere.system.domain.Template;
|
||||
import io.metersphere.system.domain.TemplateExample;
|
||||
import io.metersphere.system.dto.ProjectDTO;
|
||||
import io.metersphere.system.service.BaseTemplateService;
|
||||
import io.metersphere.system.service.PlatformPluginService;
|
||||
import io.metersphere.system.service.PluginLoadService;
|
||||
import io.metersphere.system.service.ServiceIntegrationService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.metersphere.project.enums.result.ProjectResultCode.PROJECT_TEMPLATE_PERMISSION;
|
||||
import static io.metersphere.system.controller.handler.result.CommonResultCode.DEFAULT_TEMPLATE_PERMISSION;
|
||||
|
||||
/**
|
||||
* @author jianxing
|
||||
|
@ -25,17 +47,231 @@ public class ProjectTemplateService extends BaseTemplateService {
|
|||
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
@Resource
|
||||
private ServiceIntegrationService serviceIntegrationService;
|
||||
@Resource
|
||||
private PluginLoadService pluginLoadService;
|
||||
@Resource
|
||||
private PlatformPluginService platformPluginService;
|
||||
@Resource
|
||||
private ProjectApplicationService projectApplicationService;
|
||||
|
||||
@Override
|
||||
public List<Template> list(String projectId, String scene) {
|
||||
public List list(String projectId, String scene) {
|
||||
projectService.checkResourceExist(projectId);
|
||||
return super.list(projectId, scene);
|
||||
List<Template> templates = super.list(projectId, scene);
|
||||
// 缺陷模板需要获取第三方平台模板
|
||||
templates = addPluginBugTemplate(projectId, scene, templates);
|
||||
// 标记默认模板
|
||||
return tagDefaultTemplate(projectId, scene, templates);
|
||||
}
|
||||
|
||||
public TemplateDTO geDTOWithCheck(String id) {
|
||||
/**
|
||||
* 如果是缺陷模板,并且配置了服务集成和项目信息,则添加第三方平台模板
|
||||
* @param projectId
|
||||
* @param scene
|
||||
* @param templates
|
||||
* @return
|
||||
*/
|
||||
private List<Template> addPluginBugTemplate(String projectId, String scene, List<Template> templates) {
|
||||
if (StringUtils.equals(scene, TemplateScene.BUG.name())) {
|
||||
Template pluginBugTemplate = getPluginBugTemplate(projectId);
|
||||
if (pluginBugTemplate != null) {
|
||||
templates.add(pluginBugTemplate);
|
||||
}
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前项目中可用的模板选项
|
||||
* 默认模板排前面
|
||||
* !提供给其他模块调用
|
||||
* @param projectId
|
||||
* @param scene
|
||||
* @return
|
||||
*/
|
||||
public List<ProjectTemplateOptionDTO> getOption(String projectId, String scene) {
|
||||
projectService.checkResourceExist(projectId);
|
||||
List<Template> templates = getTemplates(projectId, scene);
|
||||
translateInternalTemplate(templates);
|
||||
|
||||
// 缺陷模板需要获取第三方平台模板
|
||||
templates = addPluginBugTemplate(projectId, scene, templates);
|
||||
|
||||
List<ProjectTemplateDTO> projectTemplateDTOS = tagDefaultTemplate(projectId, scene, templates);
|
||||
return sortByDefaultTemplate(projectTemplateDTOS).stream()
|
||||
.map(item -> BeanUtils.copyBean(new ProjectTemplateOptionDTO(), item))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将默认模板排最前面
|
||||
* @param projectTemplateDTOS
|
||||
* @return
|
||||
*/
|
||||
private static List<ProjectTemplateDTO> sortByDefaultTemplate(List<ProjectTemplateDTO> projectTemplateDTOS) {
|
||||
return projectTemplateDTOS.stream()
|
||||
.sorted(Comparator.comparing(ProjectTemplateDTO::getEnableDefault)) // 默认模板排在前面
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认的模板以及字段
|
||||
* !提供给其他模块调用
|
||||
* @param projectId
|
||||
* @param scene
|
||||
* @return
|
||||
*/
|
||||
public TemplateDTO getDefaultTemplateDTO(String projectId, String scene) {
|
||||
String defaultTemplateId = getDefaultTemplateId(projectId, scene);
|
||||
Template template;
|
||||
if (StringUtils.isBlank(defaultTemplateId)) {
|
||||
// 如果没有默认模板,则获取内置模板
|
||||
template = getInternalTemplate(projectId, scene);
|
||||
} else {
|
||||
template = templateMapper.selectByPrimaryKey(defaultTemplateId);
|
||||
if (template == null) {
|
||||
// 如果默认模板查不到,则获取内置模板
|
||||
template = getInternalTemplate(projectId, scene);
|
||||
}
|
||||
}
|
||||
return geTemplateDTO(template);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内置模板
|
||||
* @param projectId
|
||||
* @param scene
|
||||
* @return
|
||||
*/
|
||||
public Template getInternalTemplate(String projectId, String scene) {
|
||||
// 获取内置模板
|
||||
TemplateExample example = new TemplateExample();
|
||||
example.createCriteria()
|
||||
.andScopeIdEqualTo(projectId)
|
||||
.andSceneEqualTo(scene)
|
||||
.andInternalEqualTo(true);
|
||||
return templateMapper.selectByExample(example).get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设置的默认模板ID
|
||||
*
|
||||
* @param projectId
|
||||
* @param scene
|
||||
* @return
|
||||
*/
|
||||
public String getDefaultTemplateId(String projectId, String scene) {
|
||||
ProjectApplicationType.DEFAULT_TEMPLATE defaultTemplateParam = ProjectApplicationType.DEFAULT_TEMPLATE.getByTemplateScene(scene);
|
||||
ProjectApplication projectApplication = projectApplicationService.getByType(projectId, defaultTemplateParam.name());
|
||||
return projectApplication == null ? null : projectApplication.getTypeValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记默认模板
|
||||
*
|
||||
* @param projectId
|
||||
* @param scene
|
||||
* @param templates
|
||||
* @return
|
||||
*/
|
||||
private List<ProjectTemplateDTO> tagDefaultTemplate(String projectId, String scene, List<Template> templates) {
|
||||
// 查询项目下设置中配置的默认模板
|
||||
String defaultProjectId = getDefaultTemplateId(projectId, scene);
|
||||
List<ProjectTemplateDTO> templateDTOS = templates.stream().map(item -> BeanUtils.copyBean(new ProjectTemplateDTO(), item)).toList();
|
||||
|
||||
ProjectTemplateDTO defaultTemplate = templateDTOS.stream()
|
||||
.filter(t -> StringUtils.equals(defaultProjectId, t.getId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
// 如果查询不到默认模板,设置内置模板为默认模板
|
||||
if (defaultTemplate == null) {
|
||||
defaultTemplate = templateDTOS.stream()
|
||||
.filter(ProjectTemplateDTO::getInternal)
|
||||
.findFirst()
|
||||
.get();
|
||||
}
|
||||
defaultTemplate.setEnableDefault(true);
|
||||
return templateDTOS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第三方平台模板
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
private Template getPluginBugTemplate(String projectId) {
|
||||
ServiceIntegration serviceIntegration = getServiceIntegration(projectId);
|
||||
if (serviceIntegration == null) {
|
||||
return null;
|
||||
}
|
||||
Platform platform = platformPluginService.getPlatform(serviceIntegration.getPluginId(),
|
||||
serviceIntegration.getOrganizationId(), new String(serviceIntegration.getConfiguration()));
|
||||
if (platform != null && platform.isThirdPartTemplateSupport()) {
|
||||
return getPluginBugTemplate(projectId, serviceIntegration.getPluginId()); // 该插件支持第三方平台模板
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Template getPluginBugTemplate(String projectId, String pluginId) {
|
||||
PluginWrapper pluginWrapper = pluginLoadService.getPluginWrapper(pluginId);
|
||||
Template template = new Template();
|
||||
template.setId(pluginWrapper.getPluginId());
|
||||
template.setCreateUser(InternalUser.ADMIN.getValue());
|
||||
template.setScene(TemplateScene.BUG.name());
|
||||
template.setEnableThirdPart(true);
|
||||
template.setScopeId(projectId);
|
||||
template.setScopeType(TemplateScopeType.PROJECT.name());
|
||||
template.setInternal(false);
|
||||
template.setRemark(((MsPlugin) pluginWrapper.getPlugin()).getName() + Translator.get("plugin_bug_template_remark"));
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果项目下配置了第三方平台信息
|
||||
* 获取对应的服务集成信息
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
private ServiceIntegration getServiceIntegration(String projectId) {
|
||||
// 判断项目是否开启集成缺陷
|
||||
ProjectApplication syncEnableConfig = projectApplicationService.getByType(projectId, ProjectApplicationType.BUG_SYNC_CONFIG.SYNC_ENABLE.name());
|
||||
boolean isSyncEnable = syncEnableConfig != null && Boolean.parseBoolean(syncEnableConfig.getTypeValue());
|
||||
if (!isSyncEnable) {
|
||||
return null;
|
||||
}
|
||||
ProjectDTO project = projectService.getProjectById(projectId);
|
||||
// 查询组织下有权限的插件
|
||||
Set<String> orgPluginIds = platformPluginService.getOrgEnabledPlatformPlugins(project.getOrganizationId())
|
||||
.stream()
|
||||
.map(Plugin::getId)
|
||||
.collect(Collectors.toSet());
|
||||
// 查询服务集成中启用并且支持第三方模板的插件
|
||||
return serviceIntegrationService.getServiceIntegrationByOrgId(project.getOrganizationId())
|
||||
.stream()
|
||||
.filter(serviceIntegration -> {
|
||||
return serviceIntegration.getEnable() // 服务集成开启
|
||||
&& orgPluginIds.contains(serviceIntegration.getPluginId()); // 该服务集成对应的插件有权限
|
||||
})
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板以及字段
|
||||
* !提供给其他模块调用
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public TemplateDTO geTemplateDTOWithCheck(String id) {
|
||||
Template template = super.getWithCheck(id);
|
||||
checkProjectResourceExist(template);
|
||||
return super.geDTOWithCheck(template);
|
||||
return super.geTemplateDTO(template);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,20 +300,45 @@ public class ProjectTemplateService extends BaseTemplateService {
|
|||
public void delete(String id) {
|
||||
Template template = getWithCheck(id);
|
||||
checkProjectTemplateEnable(template.getScopeId(), template.getScene());
|
||||
checkDefault(template);
|
||||
super.delete(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置成默认模板后不能删除
|
||||
*
|
||||
* @param template
|
||||
*/
|
||||
protected void checkDefault(Template template) {
|
||||
String defaultTemplateId = getDefaultTemplateId(template.getScopeId(), template.getScene());
|
||||
if (StringUtils.equals(template.getId(), defaultTemplateId)) {
|
||||
throw new MSException(DEFAULT_TEMPLATE_PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将模板设置成默认模板
|
||||
* 同时将其他没模板设置成非默认模板
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public void setDefaultTemplate(String id) {
|
||||
Template template = getWithCheck(id);
|
||||
checkProjectTemplateEnable(template.getScopeId(), template.getScene());
|
||||
super.setDefaultTemplate(id);
|
||||
public void setDefaultTemplate(String projectId, String id) {
|
||||
Template template = get(id);
|
||||
if (template == null) {
|
||||
Template pluginBugTemplate = getPluginBugTemplate(projectId);
|
||||
if (pluginBugTemplate != null && StringUtils.equals(pluginBugTemplate.getId(), id)) {
|
||||
template = pluginBugTemplate;
|
||||
}
|
||||
}
|
||||
if (template == null) {
|
||||
// 为空check抛出异常
|
||||
template = getWithCheck(id);
|
||||
}
|
||||
String paramType = ProjectApplicationType.DEFAULT_TEMPLATE.getByTemplateScene(template.getScene()).name();
|
||||
ProjectApplication projectApplication = new ProjectApplication();
|
||||
projectApplication.setProjectId(projectId);
|
||||
projectApplication.setTypeValue(id);
|
||||
projectApplication.setType(paramType);
|
||||
projectApplicationService.createOrUpdateConfig(projectApplication);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package io.metersphere.project.controller;
|
||||
|
||||
import io.metersphere.project.dto.ProjectTemplateDTO;
|
||||
import io.metersphere.project.dto.ProjectTemplateOptionDTO;
|
||||
import io.metersphere.project.service.ProjectTemplateService;
|
||||
import io.metersphere.sdk.constants.OrganizationParameterConstants;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.constants.TemplateScene;
|
||||
|
@ -9,6 +12,7 @@ import io.metersphere.sdk.dto.TemplateDTO;
|
|||
import io.metersphere.sdk.dto.request.TemplateCustomFieldRequest;
|
||||
import io.metersphere.sdk.dto.request.TemplateUpdateRequest;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.system.base.BasePluginTestService;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.param.TemplateUpdateRequestDefinition;
|
||||
import io.metersphere.system.domain.*;
|
||||
|
@ -22,6 +26,7 @@ import io.metersphere.system.service.UserLoginService;
|
|||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
@ -30,6 +35,8 @@ import org.springframework.test.web.servlet.MvcResult;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.metersphere.project.enums.result.ProjectResultCode.PROJECT_TEMPLATE_PERMISSION;
|
||||
import static io.metersphere.sdk.constants.InternalUserRole.ADMIN;
|
||||
|
@ -46,7 +53,7 @@ import static io.metersphere.system.controller.handler.result.MsHttpResultCode.N
|
|||
public class ProjectTemplateControllerTests extends BaseTest {
|
||||
private static final String BASE_PATH = "/project/template/";
|
||||
private static final String LIST = "list/{0}/{1}";
|
||||
private static final String SET_DEFAULT = "set-default/{0}";
|
||||
private static final String SET_DEFAULT = "set-default/{0}/{1}";
|
||||
|
||||
@Resource
|
||||
private TemplateMapper templateMapper;
|
||||
|
@ -60,6 +67,10 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
private BaseTemplateCustomFieldService baseTemplateCustomFieldService;
|
||||
@Resource
|
||||
private OrganizationParameterMapper organizationParameterMapper;
|
||||
@Resource
|
||||
private ProjectTemplateService projectTemplateService;
|
||||
@Resource
|
||||
private BasePluginTestService basePluginTestService;
|
||||
|
||||
private static Template addTemplate;
|
||||
private static Template anotherTemplateField;
|
||||
|
@ -77,6 +88,7 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
MvcResult mvcResult = this.requestGetWithOkAndReturn(LIST, DEFAULT_PROJECT_ID, TemplateScene.FUNCTIONAL.name());
|
||||
List<Template> templates = getResultDataArray(mvcResult, Template.class);
|
||||
this.defaultTemplate = templates.get(0);
|
||||
this.requestGetWithOkAndReturn(LIST, DEFAULT_PROJECT_ID, TemplateScene.BUG.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -228,26 +240,58 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(3)
|
||||
public void list() throws Exception {
|
||||
|
||||
String scene = TemplateScene.FUNCTIONAL.name();
|
||||
// @@请求成功
|
||||
MvcResult mvcResult = this.requestGetWithOk(LIST, DEFAULT_PROJECT_ID, scene)
|
||||
.andReturn();
|
||||
// 校验数据是否正确
|
||||
List<Template> resultList = getResultDataArray(mvcResult, Template.class);
|
||||
List<Template> templates = baseTemplateService.getTemplates(DEFAULT_PROJECT_ID, scene);
|
||||
List<String> userIds = templates.stream().map(Template::getCreateUser).toList();
|
||||
Map<String, String> userNameMap = userLoginService.getUserNameMap(userIds);
|
||||
for (int i = 0; i < resultList.size(); i++) {
|
||||
Template resultItem = resultList.get(i);
|
||||
Template template = templates.get(i);
|
||||
template.setCreateUser(userNameMap.get(template.getCreateUser()));
|
||||
if (template.getInternal()) {
|
||||
// 校验内置用户名称是否翻译
|
||||
template.setName(baseTemplateService.translateInternalTemplate(template.getName()));
|
||||
}
|
||||
Assertions.assertEquals(template, resultItem);
|
||||
Assertions.assertEquals(resultItem.getScene(), scene);
|
||||
}
|
||||
List<ProjectTemplateDTO> resultList = getResultDataArray(mvcResult, ProjectTemplateDTO.class);
|
||||
List<Template> dbTemplates = baseTemplateService.getTemplates(DEFAULT_PROJECT_ID, scene);
|
||||
assertListTemplate(scene, resultList, dbTemplates);
|
||||
|
||||
// 校验获取模板选项方法
|
||||
List<ProjectTemplateOptionDTO> projectTemplateOptions = projectTemplateService.getOption(DEFAULT_PROJECT_ID, scene);
|
||||
assertTemplateOption(resultList, projectTemplateOptions);
|
||||
|
||||
scene = TemplateScene.BUG.name();
|
||||
// @@缺陷模板请求成功
|
||||
mvcResult = this.requestGetWithOk(LIST, DEFAULT_PROJECT_ID, scene)
|
||||
.andReturn();
|
||||
// 校验数据是否正确
|
||||
resultList = getResultDataArray(mvcResult, ProjectTemplateDTO.class);
|
||||
dbTemplates = baseTemplateService.getTemplates(DEFAULT_PROJECT_ID, scene);
|
||||
assertListTemplate(scene, resultList, dbTemplates);
|
||||
|
||||
// 校验获取模板选项方法
|
||||
projectTemplateOptions = projectTemplateService.getOption(DEFAULT_PROJECT_ID, scene);
|
||||
assertTemplateOption(resultList, projectTemplateOptions);
|
||||
|
||||
// 上传jira插件,添加jira集成
|
||||
basePluginTestService.addJiraPlugin();
|
||||
basePluginTestService.addServiceIntegration(DEFAULT_ORGANIZATION_ID);
|
||||
// @@校验配置服务集成后,是否有jira模板
|
||||
mvcResult = this.requestGetWithOk(LIST, DEFAULT_PROJECT_ID, scene)
|
||||
.andReturn();
|
||||
resultList = getResultDataArray(mvcResult, ProjectTemplateDTO.class);
|
||||
// 没有配置项目信息,校验是否有jira模板
|
||||
Assertions.assertTrue(resultList.size() == dbTemplates.size());
|
||||
Assertions.assertTrue(resultList.stream().filter(item -> StringUtils.equals(item.getId(), "jira")).count() == 0);
|
||||
|
||||
// 校验获取模板选项方法
|
||||
projectTemplateOptions = projectTemplateService.getOption(DEFAULT_PROJECT_ID, scene);
|
||||
assertTemplateOption(resultList, projectTemplateOptions);
|
||||
|
||||
// 配置项目信息
|
||||
basePluginTestService.enableProjectBugConfig(DEFAULT_PROJECT_ID);
|
||||
// @@校验配置项目信息后,是否有jira模板
|
||||
mvcResult = this.requestGetWithOk(LIST, DEFAULT_PROJECT_ID, scene)
|
||||
.andReturn();
|
||||
Template jiraTemplate = getResultDataArray(mvcResult, Template.class).stream()
|
||||
.filter(item -> StringUtils.equals(item.getId(), "jira"))
|
||||
.findFirst()
|
||||
.get();
|
||||
Assertions.assertNotNull(jiraTemplate);
|
||||
|
||||
// @@校验组织是否存在
|
||||
assertErrorCode(this.requestGet(LIST, "1111", scene), NOT_FOUND);
|
||||
|
@ -259,6 +303,34 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
requestGetPermissionTest(PermissionConstants.PROJECT_TEMPLATE_READ, LIST, DEFAULT_PROJECT_ID, scene);
|
||||
}
|
||||
|
||||
private static void assertTemplateOption(List<ProjectTemplateDTO> resultList, List<ProjectTemplateOptionDTO> projectTemplateOptions) {
|
||||
Map<String, ProjectTemplateDTO> templateMap = resultList.stream().collect(Collectors.toMap(Template::getId, Function.identity()));
|
||||
Assertions.assertEquals(projectTemplateOptions.size(), resultList.size());
|
||||
projectTemplateOptions.forEach(option -> {
|
||||
ProjectTemplateDTO template = templateMap.get(option.getId());
|
||||
Assertions.assertEquals(option.getId(), template.getId());
|
||||
Assertions.assertEquals(option.getName(), template.getName());
|
||||
Assertions.assertEquals(option.getEnableDefault(), template.getEnableDefault());
|
||||
});
|
||||
}
|
||||
|
||||
private void assertListTemplate(String scene, List<ProjectTemplateDTO> resultList, List<Template> dbTemplates) {
|
||||
List<String> userIds = dbTemplates.stream().map(Template::getCreateUser).toList();
|
||||
Map<String, String> userNameMap = userLoginService.getUserNameMap(userIds);
|
||||
Assertions.assertTrue(resultList.size() == dbTemplates.size());
|
||||
for (int i = 0; i < resultList.size(); i++) {
|
||||
Template resultItem = resultList.get(i);
|
||||
Template template = dbTemplates.get(i);
|
||||
template.setCreateUser(userNameMap.get(template.getCreateUser()));
|
||||
if (template.getInternal()) {
|
||||
// 校验内置用户名称是否翻译
|
||||
template.setName(baseTemplateService.translateInternalTemplate());
|
||||
}
|
||||
Assertions.assertEquals(template, resultItem);
|
||||
Assertions.assertEquals(resultItem.getScene(), scene);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
public void get() throws Exception {
|
||||
|
@ -289,20 +361,26 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
@Order(5)
|
||||
public void setDefaultTemplate() throws Exception {
|
||||
changeOrgTemplateEnable(false);
|
||||
|
||||
String projectId = DEFAULT_PROJECT_ID;
|
||||
String scene = TemplateScene.FUNCTIONAL.name();
|
||||
String defaultTemplateId = projectTemplateService.getDefaultTemplateId(projectId, scene);
|
||||
// 校验默认没有设置默认模板,使用内置模板
|
||||
Assertions.assertNull(defaultTemplateId);
|
||||
TemplateDTO defaultTemplateDTO = projectTemplateService.getDefaultTemplateDTO(projectId, scene);
|
||||
Assertions.assertEquals(defaultTemplateDTO.getInternal(), true);
|
||||
|
||||
// @@请求成功
|
||||
this.requestGetWithOk(SET_DEFAULT, addTemplate.getId());
|
||||
this.requestGetWithOk(SET_DEFAULT, DEFAULT_PROJECT_ID, addTemplate.getId());
|
||||
Template template = templateMapper.selectByPrimaryKey(addTemplate.getId());
|
||||
assertSetDefaultTemplate(template);
|
||||
|
||||
// @校验是否开启项目模板
|
||||
changeOrgTemplateEnable(true);
|
||||
assertErrorCode(this.requestGet(SET_DEFAULT, addTemplate.getId()), PROJECT_TEMPLATE_PERMISSION);
|
||||
changeOrgTemplateEnable(false);
|
||||
defaultTemplateDTO = projectTemplateService.getDefaultTemplateDTO(projectId, scene);
|
||||
Assertions.assertEquals(defaultTemplateDTO.getId(), template.getId());
|
||||
|
||||
// @@校验日志
|
||||
checkLog(addTemplate.getId(), OperationLogType.UPDATE);
|
||||
// @@校验权限
|
||||
requestGetPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, SET_DEFAULT, addTemplate.getScopeId(), addTemplate.getScene());
|
||||
requestGetPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, SET_DEFAULT, DEFAULT_PROJECT_ID, addTemplate.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -313,23 +391,21 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
assertErrorCode(this.requestGet(DEFAULT_DELETE, addTemplate.getId()), PROJECT_TEMPLATE_PERMISSION);
|
||||
changeOrgTemplateEnable(false);
|
||||
|
||||
// @@校验内置模板删除异常
|
||||
Template internalTemplate = projectTemplateService.getInternalTemplate(DEFAULT_PROJECT_ID, TemplateScene.FUNCTIONAL.name());
|
||||
assertErrorCode(this.requestGet(DEFAULT_DELETE, internalTemplate.getId()), INTERNAL_TEMPLATE_PERMISSION);
|
||||
|
||||
// @@校验删除默认模板
|
||||
assertErrorCode(this.requestGet(DEFAULT_DELETE, addTemplate.getId()), DEFAULT_TEMPLATE_PERMISSION);
|
||||
// 设置回来,保证正常删除
|
||||
this.requestGetWithOk(SET_DEFAULT, defaultTemplate.getId());
|
||||
this.requestGetWithOk(SET_DEFAULT, DEFAULT_PROJECT_ID, defaultTemplate.getId());
|
||||
|
||||
// @@请求成功
|
||||
this.requestGetWithOk(DEFAULT_DELETE, addTemplate.getId());
|
||||
Assertions.assertNull(templateMapper.selectByPrimaryKey(addTemplate.getId()));
|
||||
Assertions.assertTrue(CollectionUtils.isEmpty(baseTemplateCustomFieldService.getByTemplateId(addTemplate.getId())));
|
||||
|
||||
// @@校验内置模板删除异常
|
||||
TemplateExample example = new TemplateExample();
|
||||
example.createCriteria()
|
||||
.andScopeTypeEqualTo(TemplateScopeType.PROJECT.name())
|
||||
.andInternalEqualTo(true);
|
||||
Template internalTemplate = templateMapper.selectByExample(example).get(0);
|
||||
assertErrorCode(this.requestGet(DEFAULT_DELETE, internalTemplate.getId()), INTERNAL_TEMPLATE_PERMISSION);
|
||||
basePluginTestService.deleteJiraPlugin();
|
||||
|
||||
// @@校验 NOT_FOUND 异常
|
||||
assertErrorCode(this.requestGet(DEFAULT_DELETE, "1111"), NOT_FOUND);
|
||||
|
@ -341,18 +417,8 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
private void assertSetDefaultTemplate(Template template) {
|
||||
Assertions.assertTrue(template.getEnableDefault());
|
||||
int defaultCount = getTemplateByScopeId(addTemplate.getScopeId())
|
||||
.stream()
|
||||
.filter(Template::getEnableDefault)
|
||||
.toList().size();
|
||||
Assertions.assertEquals(defaultCount, 1);
|
||||
}
|
||||
|
||||
private List<Template> getTemplateByScopeId(String scopeId) {
|
||||
TemplateExample example = new TemplateExample();
|
||||
example.createCriteria().andScopeIdEqualTo(scopeId);
|
||||
return templateMapper.selectByExample(example);
|
||||
String defaultTemplateId = projectTemplateService.getDefaultTemplateId(template.getScopeId(), template.getScene());
|
||||
Assertions.assertEquals(defaultTemplateId, template.getId());
|
||||
}
|
||||
|
||||
private void changeOrgTemplateEnable(boolean enable) {
|
||||
|
|
Binary file not shown.
|
@ -88,14 +88,6 @@ public class OrganizationTemplateController {
|
|||
organizationTemplateService.disableOrganizationTemplate(organizationId, scene);
|
||||
}
|
||||
|
||||
@GetMapping("/set-default/{id}")
|
||||
@Operation(summary = "设置模板模板")
|
||||
@RequiresPermissions(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE)
|
||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.setDefaultTemplateLog(#id)", msClass = OrganizationTemplateLogService.class)
|
||||
public void setDefaultTemplate(@PathVariable String id) {
|
||||
organizationTemplateService.setDefaultTemplate(id);
|
||||
}
|
||||
|
||||
@GetMapping("/is-enable/{organizationId}/{scene}")
|
||||
@Operation(summary = "是否启用组织模版")
|
||||
@RequiresPermissions(PermissionConstants.ORGANIZATION_TEMPLATE_READ)
|
||||
|
|
|
@ -50,10 +50,15 @@ public class BaseTemplateService {
|
|||
List<Template> templates = getTemplates(scopeId, scene);
|
||||
List<String> userIds = templates.stream().map(Template::getCreateUser).toList();
|
||||
Map<String, String> userNameMap = userLoginService.getUserNameMap(userIds);
|
||||
templates.forEach(item -> item.setCreateUser(userNameMap.get(item.getCreateUser())));
|
||||
translateInternalTemplate(templates);
|
||||
return templates;
|
||||
}
|
||||
|
||||
public List<Template> translateInternalTemplate(List<Template> templates) {
|
||||
templates.forEach(item -> {
|
||||
item.setCreateUser(userNameMap.get(item.getCreateUser()));
|
||||
if (item.getInternal()) {
|
||||
item.setName(translateInternalTemplate(item.getName()));
|
||||
item.setName(translateInternalTemplate());
|
||||
}
|
||||
});
|
||||
return templates;
|
||||
|
@ -74,16 +79,19 @@ public class BaseTemplateService {
|
|||
return templateMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public String translateInternalTemplate(String filedName) {
|
||||
return Translator.get("template." + filedName);
|
||||
public String translateInternalTemplate() {
|
||||
return Translator.get("template.default");
|
||||
}
|
||||
|
||||
public Template getWithCheck(String id) {
|
||||
return checkResourceExist(id);
|
||||
}
|
||||
|
||||
public Template get(String id) {
|
||||
return templateMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public TemplateDTO geDTOWithCheck(Template template) {
|
||||
protected TemplateDTO geTemplateDTO(Template template) {
|
||||
List<TemplateCustomField> templateCustomFields = baseTemplateCustomFieldService.getByTemplateId(template.getId());
|
||||
|
||||
// 查找字段名称
|
||||
|
@ -112,7 +120,6 @@ public class BaseTemplateService {
|
|||
|
||||
public Template add(Template template, List<TemplateCustomFieldRequest> customFields) {
|
||||
template.setInternal(false);
|
||||
template.setEnableDefault(false);
|
||||
return this.baseAdd(template, customFields);
|
||||
}
|
||||
|
||||
|
@ -144,7 +151,6 @@ public class BaseTemplateService {
|
|||
template.setScopeId(null);
|
||||
template.setCreateUser(null);
|
||||
template.setCreateTime(null);
|
||||
template.setEnableDefault(null);
|
||||
// customFields 为 null 则不修改
|
||||
if (customFields != null) {
|
||||
baseTemplateCustomFieldService.deleteByTemplateId(template.getId());
|
||||
|
@ -157,29 +163,10 @@ public class BaseTemplateService {
|
|||
public void delete(String id) {
|
||||
Template template = checkResourceExist(id);
|
||||
checkInternal(template);
|
||||
checkDefault(template);
|
||||
templateMapper.deleteByPrimaryKey(id);
|
||||
baseTemplateCustomFieldService.deleteByTemplateId(id);
|
||||
}
|
||||
|
||||
public void setDefaultTemplate(String id) {
|
||||
Template originTemplate = templateMapper.selectByPrimaryKey(id);
|
||||
// 将当前模板设置成默认模板
|
||||
Template template = new Template();
|
||||
template.setId(id);
|
||||
template.setEnableDefault(true);
|
||||
templateMapper.updateByPrimaryKeySelective(template);
|
||||
|
||||
// 将其他模板设置成非默认模板
|
||||
template = new Template();
|
||||
template.setEnableDefault(false);
|
||||
TemplateExample example = new TemplateExample();
|
||||
example.createCriteria()
|
||||
.andIdNotEqualTo(id)
|
||||
.andScopeIdEqualTo(originTemplate.getScopeId());
|
||||
templateMapper.updateByExampleSelective(template, example);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验时候是内置模板
|
||||
* @param template
|
||||
|
@ -190,16 +177,6 @@ public class BaseTemplateService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置成默认模板后不能删除
|
||||
* @param template
|
||||
*/
|
||||
protected void checkDefault(Template template) {
|
||||
if (template.getEnableDefault()) {
|
||||
throw new MSException(DEFAULT_TEMPLATE_PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkAddExist(Template template) {
|
||||
TemplateExample example = new TemplateExample();
|
||||
example.createCriteria()
|
||||
|
@ -329,7 +306,6 @@ public class BaseTemplateService {
|
|||
template.setScopeType(scopeType.name());
|
||||
template.setScopeId(scopeId);
|
||||
template.setEnableThirdPart(false);
|
||||
template.setEnableDefault(true);
|
||||
template.setScene(scene.name());
|
||||
templateMapper.insert(template);
|
||||
return template;
|
||||
|
|
|
@ -45,7 +45,7 @@ public class OrganizationTemplateService extends BaseTemplateService {
|
|||
public TemplateDTO geDTOWithCheck(String id) {
|
||||
Template template = super.getWithCheck(id);
|
||||
checkOrgResourceExist(template);
|
||||
return super.geDTOWithCheck(template);
|
||||
return super.geTemplateDTO(template);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -132,34 +132,6 @@ public class OrganizationTemplateService extends BaseTemplateService {
|
|||
super.delete(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将模板设置成默认模板
|
||||
* 同时将其他没模板设置成非默认模板
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public void setDefaultTemplate(String id) {
|
||||
Template template = getWithCheck(id);
|
||||
checkOrganizationTemplateEnable(template.getScopeId(), template.getScene());
|
||||
setRefDefaultTemplate(id);
|
||||
super.setDefaultTemplate(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步设置项目级别模板
|
||||
* 当开启组织模板时,操作组织模板,同时维护与之关联的项目模板
|
||||
* 避免当开启项目模板时,需要将各个资源关联的模板和字段从组织切换为项目
|
||||
* 无论是否开启组织模板,各资源都只关联各自项目下的模板和字段
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
private void setRefDefaultTemplate(String id) {
|
||||
getByRefId(id).stream()
|
||||
.map(Template::getId)
|
||||
.forEach(super::setDefaultTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步删除项目级别模板
|
||||
* 当开启组织模板时,操作组织模板,同时维护与之关联的项目模板
|
||||
|
|
|
@ -73,7 +73,7 @@ public class ServiceIntegrationService {
|
|||
}).toList();
|
||||
}
|
||||
|
||||
private List<ServiceIntegration> getServiceIntegrationByOrgId(String organizationId) {
|
||||
public List<ServiceIntegration> getServiceIntegrationByOrgId(String organizationId) {
|
||||
ServiceIntegrationExample example = new ServiceIntegrationExample();
|
||||
example.createCriteria()
|
||||
.andOrganizationIdEqualTo(organizationId);
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
package io.metersphere.system.base;
|
||||
|
||||
import io.metersphere.project.domain.ProjectApplication;
|
||||
import io.metersphere.project.domain.ProjectApplicationExample;
|
||||
import io.metersphere.project.mapper.ProjectApplicationMapper;
|
||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.domain.Plugin;
|
||||
import io.metersphere.system.domain.ServiceIntegration;
|
||||
import io.metersphere.system.mapper.PluginMapper;
|
||||
import io.metersphere.system.request.PluginUpdateRequest;
|
||||
import io.metersphere.system.request.ServiceIntegrationUpdateRequest;
|
||||
import io.metersphere.system.service.PluginService;
|
||||
import io.metersphere.system.service.ServiceIntegrationService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.metersphere.sdk.constants.InternalUserRole.ADMIN;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-10-20 11:32
|
||||
*/
|
||||
@Service
|
||||
public class BasePluginTestService {
|
||||
|
||||
@Resource
|
||||
private PluginService pluginService;
|
||||
@Value("${embedded.mockserver.host}")
|
||||
private String mockServerHost;
|
||||
@Value("${embedded.mockserver.port}")
|
||||
private int mockServerHostPort;
|
||||
@Resource
|
||||
private ServiceIntegrationService serviceIntegrationService;
|
||||
@Resource
|
||||
private ProjectApplicationMapper projectApplicationMapper;
|
||||
@Resource
|
||||
private PluginMapper pluginMapper;
|
||||
private static Plugin jiraPlugin;
|
||||
private static ServiceIntegration serviceIntegration;
|
||||
|
||||
|
||||
/**
|
||||
* 添加插件,供测试使用
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public Plugin addJiraPlugin() throws Exception {
|
||||
if (hasJiraPlugin()) {
|
||||
return jiraPlugin;
|
||||
}
|
||||
PluginUpdateRequest request = new PluginUpdateRequest();
|
||||
File jarFile = new File(
|
||||
this.getClass().getClassLoader().getResource("file/metersphere-jira-plugin-3.x.jar")
|
||||
.getPath()
|
||||
);
|
||||
FileInputStream inputStream = new FileInputStream(jarFile);
|
||||
MockMultipartFile mockMultipartFile = new MockMultipartFile(jarFile.getName(), jarFile.getName(), "jar", inputStream);
|
||||
request.setName("测试插件");
|
||||
request.setGlobal(true);
|
||||
request.setEnable(true);
|
||||
request.setCreateUser(ADMIN.name());
|
||||
jiraPlugin = pluginService.add(request, mockMultipartFile);
|
||||
return jiraPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加服务集成信息
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public ServiceIntegration addServiceIntegration(String orgId) {
|
||||
JiraIntegrationConfig integrationConfig = new JiraIntegrationConfig();
|
||||
integrationConfig.setAddress(String.format("http://%s:%s", mockServerHost, mockServerHostPort));
|
||||
Map<String, Object> integrationConfigMap = JSON.parseMap(JSON.toJSONString(integrationConfig));
|
||||
|
||||
ServiceIntegrationUpdateRequest request = new ServiceIntegrationUpdateRequest();
|
||||
request.setEnable(true);
|
||||
request.setPluginId(jiraPlugin.getId());
|
||||
request.setConfiguration(integrationConfigMap);
|
||||
request.setOrganizationId(orgId);
|
||||
serviceIntegration = serviceIntegrationService.add(request);
|
||||
return serviceIntegration;
|
||||
}
|
||||
|
||||
public Plugin getJiraPlugin() throws Exception {
|
||||
if (!hasJiraPlugin()) {
|
||||
return this.addJiraPlugin();
|
||||
}
|
||||
return jiraPlugin;
|
||||
}
|
||||
|
||||
public boolean hasJiraPlugin() {
|
||||
if (jiraPlugin != null) {
|
||||
return true;
|
||||
}
|
||||
jiraPlugin = pluginMapper.selectByPrimaryKey("jira");
|
||||
return jiraPlugin != null;
|
||||
}
|
||||
|
||||
public void deleteJiraPlugin() {
|
||||
if (jiraPlugin != null) {
|
||||
pluginService.delete(jiraPlugin.getId());
|
||||
jiraPlugin = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void enableProjectBugConfig(String defaultProjectId) {
|
||||
ProjectApplication projectApplication = new ProjectApplication();
|
||||
projectApplication.setProjectId(defaultProjectId);
|
||||
projectApplication.setType(ProjectApplicationType.BUG_SYNC_CONFIG.SYNC_ENABLE.name());
|
||||
projectApplication.setTypeValue(BooleanUtils.toStringTrueFalse(true));
|
||||
createOrUpdateConfig(projectApplication);
|
||||
}
|
||||
|
||||
public void createOrUpdateConfig(ProjectApplication application) {
|
||||
String type = application.getType();
|
||||
String projectId = application.getProjectId();
|
||||
ProjectApplicationExample example = new ProjectApplicationExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andTypeEqualTo(type);
|
||||
if (projectApplicationMapper.countByExample(example) > 0) {
|
||||
example.clear();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andTypeEqualTo(type);
|
||||
projectApplicationMapper.updateByExample(application, example);
|
||||
} else {
|
||||
projectApplicationMapper.insertSelective(application);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class JiraIntegrationConfig {
|
||||
private String account;
|
||||
private String password;
|
||||
private String token;
|
||||
private String authType;
|
||||
private String address;
|
||||
private String version;
|
||||
}
|
||||
}
|
|
@ -44,7 +44,6 @@ public class OrganizationTemplateControllerTests extends BaseTest {
|
|||
private static final String BASE_PATH = "/organization/template/";
|
||||
private static final String LIST = "list/{0}/{1}";
|
||||
private static final String DISABLE_ORG_TEMPLATE = "disable/{0}/{1}";
|
||||
private static final String SET_DEFAULT = "set-default/{0}";
|
||||
protected static final String IS_ORGANIZATION_TEMPLATE_ENABLE = "is-enable/{0}/{1}";
|
||||
|
||||
@Resource
|
||||
|
@ -286,7 +285,7 @@ public class OrganizationTemplateControllerTests extends BaseTest {
|
|||
template.setCreateUser(userNameMap.get(template.getCreateUser()));
|
||||
if (template.getInternal()) {
|
||||
// 校验内置用户名称是否翻译
|
||||
template.setName(baseTemplateService.translateInternalTemplate(template.getName()));
|
||||
template.setName(baseTemplateService.translateInternalTemplate());
|
||||
}
|
||||
Assertions.assertEquals(template, resultItem);
|
||||
Assertions.assertEquals(resultItem.getScene(), scene);
|
||||
|
@ -349,46 +348,6 @@ public class OrganizationTemplateControllerTests extends BaseTest {
|
|||
requestGetPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_ENABLE, DISABLE_ORG_TEMPLATE, addTemplate.getScopeId(), addTemplate.getScene());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void setDefaultTemplate() throws Exception {
|
||||
changeOrgTemplateEnable(true);
|
||||
// @@请求成功
|
||||
this.requestGetWithOk(SET_DEFAULT, addTemplate.getId());
|
||||
Template template = templateMapper.selectByPrimaryKey(addTemplate.getId());
|
||||
assertSetDefaultTemplate(template);
|
||||
assertRefSetDefaultTemplate(template);
|
||||
|
||||
// @校验是否开启组织模板
|
||||
changeOrgTemplateEnable(false);
|
||||
assertErrorCode(this.requestGet(SET_DEFAULT, addTemplate.getId()), ORGANIZATION_TEMPLATE_PERMISSION);
|
||||
changeOrgTemplateEnable(true);
|
||||
|
||||
// @@校验日志
|
||||
checkLog(addTemplate.getId(), OperationLogType.UPDATE);
|
||||
// @@校验权限
|
||||
requestGetPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, SET_DEFAULT, addTemplate.getScopeId(), addTemplate.getScene());
|
||||
}
|
||||
|
||||
private void assertSetDefaultTemplate(Template template) {
|
||||
Assertions.assertTrue(template.getEnableDefault());
|
||||
int defaultCount = getTemplateByScopeId(addTemplate.getScopeId())
|
||||
.stream()
|
||||
.filter(Template::getEnableDefault)
|
||||
.toList().size();
|
||||
Assertions.assertEquals(defaultCount, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验变更组织模板时,有没有同步变更项目模板
|
||||
*
|
||||
* @param template
|
||||
*/
|
||||
private void assertRefSetDefaultTemplate(Template template) {
|
||||
List<Template> refTemplates = organizationTemplateService.getByRefId(template.getId());
|
||||
refTemplates.forEach(this::assertSetDefaultTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
public void delete() throws Exception {
|
||||
|
@ -398,11 +357,6 @@ public class OrganizationTemplateControllerTests extends BaseTest {
|
|||
assertErrorCode(this.requestGet(DEFAULT_DELETE, addTemplate.getId()), ORGANIZATION_TEMPLATE_PERMISSION);
|
||||
changeOrgTemplateEnable(true);
|
||||
|
||||
// @@校验删除默认模板
|
||||
assertErrorCode(this.requestGet(DEFAULT_DELETE, addTemplate.getId()), DEFAULT_TEMPLATE_PERMISSION);
|
||||
// 设置回来,保证正常删除
|
||||
this.requestGetWithOk(SET_DEFAULT, defaultTemplate.getId());
|
||||
|
||||
// @@请求成功
|
||||
this.requestGetWithOk(DEFAULT_DELETE, addTemplate.getId());
|
||||
Assertions.assertNull(templateMapper.selectByPrimaryKey(addTemplate.getId()));
|
||||
|
|
|
@ -1,25 +1,22 @@
|
|||
package io.metersphere.system.controller;
|
||||
|
||||
import io.metersphere.plugin.platform.spi.AbstractPlatformPlugin;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.service.PluginLoadService;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.base.BasePluginTestService;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.param.ServiceIntegrationUpdateRequestDefinition;
|
||||
import io.metersphere.system.domain.Organization;
|
||||
import io.metersphere.system.domain.Plugin;
|
||||
import io.metersphere.system.domain.ServiceIntegration;
|
||||
import io.metersphere.system.dto.ServiceIntegrationDTO;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.mapper.PluginMapper;
|
||||
import io.metersphere.system.mapper.ServiceIntegrationMapper;
|
||||
import io.metersphere.system.request.PluginUpdateRequest;
|
||||
import io.metersphere.system.request.ServiceIntegrationUpdateRequest;
|
||||
import io.metersphere.system.service.OrganizationService;
|
||||
import io.metersphere.system.service.PluginService;
|
||||
import io.metersphere.system.service.PluginLoadService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.mockserver.client.MockServerClient;
|
||||
|
@ -27,15 +24,11 @@ import org.mockserver.model.Header;
|
|||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.metersphere.sdk.constants.InternalUserRole.ADMIN;
|
||||
import static io.metersphere.system.controller.handler.result.CommonResultCode.PLUGIN_ENABLE;
|
||||
import static io.metersphere.system.controller.handler.result.CommonResultCode.PLUGIN_PERMISSION;
|
||||
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
|
||||
|
@ -58,7 +51,6 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
private static final String VALIDATE_POST = "/validate/{0}";
|
||||
private static final String SCRIPT_GET = "/script/{0}";
|
||||
private static ServiceIntegration addServiceIntegration;
|
||||
private static Plugin plugin;
|
||||
private static Organization defaultOrg;
|
||||
|
||||
@Resource
|
||||
|
@ -68,7 +60,7 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
@Resource
|
||||
private PluginLoadService pluginLoadService;
|
||||
@Resource
|
||||
private PluginService pluginService;
|
||||
private BasePluginTestService basePluginTestService;
|
||||
@Resource
|
||||
private PluginMapper pluginMapper;
|
||||
@Resource
|
||||
|
@ -95,9 +87,9 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(1)
|
||||
public void add() throws Exception {
|
||||
plugin = addPlugin();
|
||||
Plugin plugin = basePluginTestService.addJiraPlugin();
|
||||
|
||||
JiraIntegrationConfig integrationConfig = new JiraIntegrationConfig();
|
||||
BasePluginTestService.JiraIntegrationConfig integrationConfig = new BasePluginTestService.JiraIntegrationConfig();
|
||||
Map<String, Object> integrationConfigMap = JSON.parseMap(JSON.toJSONString(integrationConfig));
|
||||
|
||||
// @@请求成功
|
||||
|
@ -140,7 +132,7 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(2)
|
||||
public void update() throws Exception {
|
||||
JiraIntegrationConfig integrationConfig = new JiraIntegrationConfig();
|
||||
BasePluginTestService.JiraIntegrationConfig integrationConfig = new BasePluginTestService.JiraIntegrationConfig();
|
||||
integrationConfig.setAddress(String.format("http://%s:%s", mockServerHost, mockServerHostPort));
|
||||
Map<String, Object> integrationConfigMap = JSON.parseMap(JSON.toJSONString(integrationConfig));
|
||||
|
||||
|
@ -148,7 +140,7 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
ServiceIntegrationUpdateRequest request = new ServiceIntegrationUpdateRequest();
|
||||
request.setId(addServiceIntegration.getId());
|
||||
request.setEnable(false);
|
||||
request.setPluginId(plugin.getId());
|
||||
request.setPluginId(basePluginTestService.getJiraPlugin().getId());
|
||||
request.setConfiguration(integrationConfigMap);
|
||||
request.setOrganizationId(defaultOrg.getId());
|
||||
this.requestPostWithOk(DEFAULT_UPDATE, request);
|
||||
|
@ -190,6 +182,7 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(3)
|
||||
public void list() throws Exception {
|
||||
Plugin plugin = basePluginTestService.getJiraPlugin();
|
||||
// @@请求成功
|
||||
MvcResult mvcResult = this.requestGetWithOkAndReturn(LIST, defaultOrg.getId());
|
||||
// 校验请求成功数据
|
||||
|
@ -252,7 +245,8 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(5)
|
||||
public void validatePost() throws Exception {
|
||||
JiraIntegrationConfig integrationConfig = new JiraIntegrationConfig();
|
||||
Plugin plugin = basePluginTestService.getJiraPlugin();
|
||||
BasePluginTestService.JiraIntegrationConfig integrationConfig = new BasePluginTestService.JiraIntegrationConfig();
|
||||
integrationConfig.setAddress(String.format("http://%s:%s", mockServerHost, mockServerHostPort));
|
||||
Map<String, Object> integrationConfigMap = JSON.parseMap(JSON.toJSONString(integrationConfig));
|
||||
// @@请求成功
|
||||
|
@ -277,6 +271,7 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(6)
|
||||
public void getPluginScript() throws Exception {
|
||||
Plugin plugin = basePluginTestService.getJiraPlugin();
|
||||
// @@请求成功
|
||||
MvcResult mvcResult = this.requestGetWithOkAndReturn(SCRIPT_GET, plugin.getId());
|
||||
// 校验请求成功数据
|
||||
|
@ -307,7 +302,7 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
Assertions.assertNull(serviceIntegration);
|
||||
|
||||
// 清理插件
|
||||
deletePlugin();
|
||||
basePluginTestService.deleteJiraPlugin();
|
||||
|
||||
// @@校验日志
|
||||
checkLog(addServiceIntegration.getId(), OperationLogType.DELETE);
|
||||
|
@ -319,28 +314,6 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
requestGetPermissionTest(PermissionConstants.SYSTEM_SERVICE_INTEGRATION_DELETE, DEFAULT_DELETE, addServiceIntegration.getId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加插件,供测试使用
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public Plugin addPlugin() throws Exception {
|
||||
PluginUpdateRequest request = new PluginUpdateRequest();
|
||||
File jarFile = new File(
|
||||
this.getClass().getClassLoader().getResource("file/metersphere-jira-plugin-3.x.jar")
|
||||
.getPath()
|
||||
);
|
||||
FileInputStream inputStream = new FileInputStream(jarFile);
|
||||
MockMultipartFile mockMultipartFile = new MockMultipartFile(jarFile.getName(), jarFile.getName(), "jar", inputStream);
|
||||
request.setName("测试插件");
|
||||
request.setGlobal(true);
|
||||
request.setEnable(true);
|
||||
request.setCreateUser(ADMIN.name());
|
||||
return pluginService.add(request, mockMultipartFile);
|
||||
}
|
||||
|
||||
public void setPluginEnable(String pluginId, boolean enabled) {
|
||||
Plugin plugin = new Plugin();
|
||||
plugin.setId(pluginId);
|
||||
|
@ -354,23 +327,4 @@ public class ServiceIntegrationControllerTests extends BaseTest {
|
|||
plugin.setGlobal(global);
|
||||
pluginMapper.updateByPrimaryKeySelective(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除插件
|
||||
* @throws Exception
|
||||
*/
|
||||
public void deletePlugin() {
|
||||
pluginService.delete(plugin.getId());
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class JiraIntegrationConfig {
|
||||
private String account;
|
||||
private String password;
|
||||
private String token;
|
||||
private String authType;
|
||||
private String address;
|
||||
private String version;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue