refactor(项目管理): 优化环境上传下载

This commit is contained in:
wxg0103 2023-12-07 15:36:17 +08:00 committed by wxg0103
parent 1aab460ee0
commit f933967063
34 changed files with 787 additions and 763 deletions

View File

@ -44,6 +44,10 @@ public class Environment implements Serializable {
@Schema(description = "描述")
private String description;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{environment.pos.not_blank}", groups = {Created.class})
private Long pos;
private static final long serialVersionUID = 1L;
public enum Column {
@ -55,7 +59,8 @@ public class Environment implements Serializable {
createTime("create_time", "createTime", "BIGINT", false),
updateTime("update_time", "updateTime", "BIGINT", false),
mock("mock", "mock", "BIT", false),
description("description", "description", "VARCHAR", false);
description("description", "description", "VARCHAR", false),
pos("pos", "pos", "BIGINT", false);
private static final String BEGINNING_DELIMITER = "`";

View File

@ -703,6 +703,66 @@ public class EnvironmentExample {
addCriterion("description not between", value1, value2, "description");
return (Criteria) this;
}
public Criteria andPosIsNull() {
addCriterion("pos is null");
return (Criteria) this;
}
public Criteria andPosIsNotNull() {
addCriterion("pos is not null");
return (Criteria) this;
}
public Criteria andPosEqualTo(Long value) {
addCriterion("pos =", value, "pos");
return (Criteria) this;
}
public Criteria andPosNotEqualTo(Long value) {
addCriterion("pos <>", value, "pos");
return (Criteria) this;
}
public Criteria andPosGreaterThan(Long value) {
addCriterion("pos >", value, "pos");
return (Criteria) this;
}
public Criteria andPosGreaterThanOrEqualTo(Long value) {
addCriterion("pos >=", value, "pos");
return (Criteria) this;
}
public Criteria andPosLessThan(Long value) {
addCriterion("pos <", value, "pos");
return (Criteria) this;
}
public Criteria andPosLessThanOrEqualTo(Long value) {
addCriterion("pos <=", value, "pos");
return (Criteria) this;
}
public Criteria andPosIn(List<Long> values) {
addCriterion("pos in", values, "pos");
return (Criteria) this;
}
public Criteria andPosNotIn(List<Long> values) {
addCriterion("pos not in", values, "pos");
return (Criteria) this;
}
public Criteria andPosBetween(Long value1, Long value2) {
addCriterion("pos between", value1, value2, "pos");
return (Criteria) this;
}
public Criteria andPosNotBetween(Long value1, Long value2) {
addCriterion("pos not between", value1, value2, "pos");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -40,6 +40,10 @@ public class EnvironmentGroup implements Serializable {
@Schema(description = "更新时间")
private Long updateTime;
@Schema(description = "自定义排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{environment_group.pos.not_blank}", groups = {Created.class})
private Long pos;
private static final long serialVersionUID = 1L;
public enum Column {
@ -50,7 +54,8 @@ public class EnvironmentGroup implements Serializable {
createUser("create_user", "createUser", "VARCHAR", false),
updateUser("update_user", "updateUser", "VARCHAR", false),
createTime("create_time", "createTime", "BIGINT", false),
updateTime("update_time", "updateTime", "BIGINT", false);
updateTime("update_time", "updateTime", "BIGINT", false),
pos("pos", "pos", "BIGINT", false);
private static final String BEGINNING_DELIMITER = "`";

View File

@ -643,6 +643,66 @@ public class EnvironmentGroupExample {
addCriterion("update_time not between", value1, value2, "updateTime");
return (Criteria) this;
}
public Criteria andPosIsNull() {
addCriterion("pos is null");
return (Criteria) this;
}
public Criteria andPosIsNotNull() {
addCriterion("pos is not null");
return (Criteria) this;
}
public Criteria andPosEqualTo(Long value) {
addCriterion("pos =", value, "pos");
return (Criteria) this;
}
public Criteria andPosNotEqualTo(Long value) {
addCriterion("pos <>", value, "pos");
return (Criteria) this;
}
public Criteria andPosGreaterThan(Long value) {
addCriterion("pos >", value, "pos");
return (Criteria) this;
}
public Criteria andPosGreaterThanOrEqualTo(Long value) {
addCriterion("pos >=", value, "pos");
return (Criteria) this;
}
public Criteria andPosLessThan(Long value) {
addCriterion("pos <", value, "pos");
return (Criteria) this;
}
public Criteria andPosLessThanOrEqualTo(Long value) {
addCriterion("pos <=", value, "pos");
return (Criteria) this;
}
public Criteria andPosIn(List<Long> values) {
addCriterion("pos in", values, "pos");
return (Criteria) this;
}
public Criteria andPosNotIn(List<Long> values) {
addCriterion("pos not in", values, "pos");
return (Criteria) this;
}
public Criteria andPosBetween(Long value1, Long value2) {
addCriterion("pos between", value1, value2, "pos");
return (Criteria) this;
}
public Criteria andPosNotBetween(Long value1, Long value2) {
addCriterion("pos not between", value1, value2, "pos");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -10,6 +10,7 @@
<result column="update_user" jdbcType="VARCHAR" property="updateUser" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<result column="pos" jdbcType="BIGINT" property="pos" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -70,7 +71,8 @@
</where>
</sql>
<sql id="Base_Column_List">
id, `name`, project_id, description, create_user, update_user, create_time, update_time
id, `name`, project_id, description, create_user, update_user, create_time, update_time,
pos
</sql>
<select id="selectByExample" parameterType="io.metersphere.sdk.domain.EnvironmentGroupExample" resultMap="BaseResultMap">
select
@ -105,10 +107,12 @@
<insert id="insert" parameterType="io.metersphere.sdk.domain.EnvironmentGroup">
insert into environment_group (id, `name`, project_id,
description, create_user, update_user,
create_time, update_time)
create_time, update_time, pos
)
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR},
#{description,jdbcType=VARCHAR}, #{createUser,jdbcType=VARCHAR}, #{updateUser,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT})
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{pos,jdbcType=BIGINT}
)
</insert>
<insert id="insertSelective" parameterType="io.metersphere.sdk.domain.EnvironmentGroup">
insert into environment_group
@ -137,6 +141,9 @@
<if test="updateTime != null">
update_time,
</if>
<if test="pos != null">
pos,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -163,6 +170,9 @@
<if test="updateTime != null">
#{updateTime,jdbcType=BIGINT},
</if>
<if test="pos != null">
#{pos,jdbcType=BIGINT},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.sdk.domain.EnvironmentGroupExample" resultType="java.lang.Long">
@ -198,6 +208,9 @@
<if test="record.updateTime != null">
update_time = #{record.updateTime,jdbcType=BIGINT},
</if>
<if test="record.pos != null">
pos = #{record.pos,jdbcType=BIGINT},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -212,7 +225,8 @@
create_user = #{record.createUser,jdbcType=VARCHAR},
update_user = #{record.updateUser,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT}
update_time = #{record.updateTime,jdbcType=BIGINT},
pos = #{record.pos,jdbcType=BIGINT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -241,6 +255,9 @@
<if test="updateTime != null">
update_time = #{updateTime,jdbcType=BIGINT},
</if>
<if test="pos != null">
pos = #{pos,jdbcType=BIGINT},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -252,18 +269,20 @@
create_user = #{createUser,jdbcType=VARCHAR},
update_user = #{updateUser,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT}
update_time = #{updateTime,jdbcType=BIGINT},
pos = #{pos,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR}
</update>
<insert id="batchInsert" parameterType="map">
insert into environment_group
(id, `name`, project_id, description, create_user, update_user, create_time, update_time
)
(id, `name`, project_id, description, create_user, update_user, create_time, update_time,
pos)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, #{item.projectId,jdbcType=VARCHAR},
#{item.description,jdbcType=VARCHAR}, #{item.createUser,jdbcType=VARCHAR}, #{item.updateUser,jdbcType=VARCHAR},
#{item.createTime,jdbcType=BIGINT}, #{item.updateTime,jdbcType=BIGINT})
#{item.createTime,jdbcType=BIGINT}, #{item.updateTime,jdbcType=BIGINT}, #{item.pos,jdbcType=BIGINT}
)
</foreach>
</insert>
<insert id="batchInsertSelective" parameterType="map">
@ -300,6 +319,9 @@
<if test="'update_time'.toString() == column.value">
#{item.updateTime,jdbcType=BIGINT}
</if>
<if test="'pos'.toString() == column.value">
#{item.pos,jdbcType=BIGINT}
</if>
</foreach>
)
</foreach>

View File

@ -11,6 +11,7 @@
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<result column="mock" jdbcType="BIT" property="mock" />
<result column="description" jdbcType="VARCHAR" property="description" />
<result column="pos" jdbcType="BIGINT" property="pos" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -72,7 +73,7 @@
</sql>
<sql id="Base_Column_List">
id, `name`, project_id, create_user, update_user, create_time, update_time, mock,
description
description, pos
</sql>
<select id="selectByExample" parameterType="io.metersphere.sdk.domain.EnvironmentExample" resultMap="BaseResultMap">
select
@ -107,12 +108,12 @@
<insert id="insert" parameterType="io.metersphere.sdk.domain.Environment">
insert into environment (id, `name`, project_id,
create_user, update_user, create_time,
update_time, mock, description
)
update_time, mock, description,
pos)
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR},
#{createUser,jdbcType=VARCHAR}, #{updateUser,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
#{updateTime,jdbcType=BIGINT}, #{mock,jdbcType=BIT}, #{description,jdbcType=VARCHAR}
)
#{updateTime,jdbcType=BIGINT}, #{mock,jdbcType=BIT}, #{description,jdbcType=VARCHAR},
#{pos,jdbcType=BIGINT})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.sdk.domain.Environment">
insert into environment
@ -144,6 +145,9 @@
<if test="description != null">
description,
</if>
<if test="pos != null">
pos,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -173,6 +177,9 @@
<if test="description != null">
#{description,jdbcType=VARCHAR},
</if>
<if test="pos != null">
#{pos,jdbcType=BIGINT},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.sdk.domain.EnvironmentExample" resultType="java.lang.Long">
@ -211,6 +218,9 @@
<if test="record.description != null">
description = #{record.description,jdbcType=VARCHAR},
</if>
<if test="record.pos != null">
pos = #{record.pos,jdbcType=BIGINT},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -226,7 +236,8 @@
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
mock = #{record.mock,jdbcType=BIT},
description = #{record.description,jdbcType=VARCHAR}
description = #{record.description,jdbcType=VARCHAR},
pos = #{record.pos,jdbcType=BIGINT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -258,6 +269,9 @@
<if test="description != null">
description = #{description,jdbcType=VARCHAR},
</if>
<if test="pos != null">
pos = #{pos,jdbcType=BIGINT},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -270,19 +284,20 @@
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
mock = #{mock,jdbcType=BIT},
description = #{description,jdbcType=VARCHAR}
description = #{description,jdbcType=VARCHAR},
pos = #{pos,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR}
</update>
<insert id="batchInsert" parameterType="map">
insert into environment
(id, `name`, project_id, create_user, update_user, create_time, update_time, mock,
description)
description, pos)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, #{item.projectId,jdbcType=VARCHAR},
#{item.createUser,jdbcType=VARCHAR}, #{item.updateUser,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT},
#{item.updateTime,jdbcType=BIGINT}, #{item.mock,jdbcType=BIT}, #{item.description,jdbcType=VARCHAR}
)
#{item.updateTime,jdbcType=BIGINT}, #{item.mock,jdbcType=BIT}, #{item.description,jdbcType=VARCHAR},
#{item.pos,jdbcType=BIGINT})
</foreach>
</insert>
<insert id="batchInsertSelective" parameterType="map">
@ -322,6 +337,9 @@
<if test="'description'.toString() == column.value">
#{item.description,jdbcType=VARCHAR}
</if>
<if test="'pos'.toString() == column.value">
#{item.pos,jdbcType=BIGINT}
</if>
</foreach>
)
</foreach>

View File

@ -50,6 +50,7 @@ CREATE TABLE IF NOT EXISTS environment
`update_time` BIGINT NOT NULL COMMENT '更新时间',
`mock` BIT NOT NULL DEFAULT 0 COMMENT '是否是mock环境',
`description` VARCHAR(255) COMMENT '描述' ,
`pos` BIGINT NOT NULL COMMENT '排序' ,
PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
@ -76,6 +77,7 @@ CREATE TABLE IF NOT EXISTS environment_group(
`update_user` VARCHAR(50) NOT NULL COMMENT '修改人' ,
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
`update_time` BIGINT NOT NULL COMMENT '更新时间' ,
`pos` BIGINT NOT NULL COMMENT '排序' ,
PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4

View File

@ -35,10 +35,10 @@ INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PARAMETER_SETTING_AUTH:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_AUTH:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_LOG:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY_ADD:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY_ADD:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY_ADD:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY_ADD:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY:READ');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL:READ');
INSERT INTO user_role_permission (id, role_id, permission_id)
@ -732,6 +732,6 @@ VALUES (UUID_SHORT(), '100001100001', 'CRON', '0 0 2 * * ?', 'io.metersphere.pro
INSERT INTO project_application (`project_id`, `type`, `type_value`) VALUES ('100001100001', 'VERSION_ENABLE', 'FALSE');
-- 初始化默认项目mock环境
INSERT INTO environment (`id`, `project_id`, `name`, `create_user`, `create_time`, `update_user`, `update_time`, `mock`) VALUES (UUID_SHORT(), '100001100001', 'Mock环境', 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true);
INSERT INTO environment (`id`, `project_id`, `name`, `create_user`, `create_time`, `update_user`, `update_time`, `mock`,`pos`) VALUES (UUID_SHORT(), '100001100001', 'Mock环境', 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, 5000);
-- set innodb lock wait timeout to default
SET SESSION innodb_lock_wait_timeout = DEFAULT;

View File

@ -263,10 +263,10 @@ public class PermissionConstants {
/*------ end: API_MANAGEMENT ------*/
//个人中心
/*------ start: PERSONAL_CENTER ------*/
public static final String SYSTEM_PERSONAL_API_KEY_ADD = "SYSTEM_PERSONAL_API_KEY_ADD:READ+ADD";
public static final String SYSTEM_PERSONAL_API_KEY_DELETE = "SYSTEM_PERSONAL_API_KEY_DELETE:READ+DELETE";
public static final String SYSTEM_PERSONAL_API_KEY_READ = "SYSTEM_PERSONAL_API_KEY_READ:READ";
public static final String SYSTEM_PERSONAL_API_KEY_UPDATE = "SYSTEM_PERSONAL_API_KEY_UPDATE:READ+UPDATE";
public static final String SYSTEM_PERSONAL_API_KEY_ADD = "SYSTEM_PERSONAL_API_KEYD:READ+ADD";
public static final String SYSTEM_PERSONAL_API_KEY_DELETE = "SYSTEM_PERSONAL_API_KEY:READ+DELETE";
public static final String SYSTEM_PERSONAL_API_KEY_READ = "SYSTEM_PERSONAL_API_KEY:READ";
public static final String SYSTEM_PERSONAL_API_KEY_UPDATE = "SYSTEM_PERSONAL_API_KEY:READ+UPDATE";
public static final String SYSTEM_PERSONAL_READ = "SYSTEM_PERSONAL:READ";
public static final String SYSTEM_PERSONAL_READ_UPDATE = "SYSTEM_PERSONAL:READ+UPDATE";
}

View File

@ -466,4 +466,7 @@ file.name.error=文件名不合法
project_template_permission_error=未开启项目模板
plugin_bug_template_remark=模板为系统自动获取,不支持编辑和查看
global_params=全局参数.json
env_info_all=环境信息(总).json

View File

@ -503,3 +503,6 @@ 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
default_template=default template
global_params=Global params.json
env_info_all=All environment info.json

View File

@ -502,3 +502,6 @@ project_template_permission_error=未开启项目模板
third_part_config_is_null=第三方平台配置信息不能为空
plugin_bug_template_remark=模板为系统自动获取,不支持编辑和查看
default_template=默认模板
global_params=全局参数.json
env_info_all=环境信息(总).json

View File

@ -502,4 +502,7 @@ file.name.error=文件名不合法
project_template_permission_error=未開啟項目模板
third_part_config_is_null=第三方平臺配置信息不能爲空
plugin_bug_template_remark=模板為系統自動獲取,不支持編輯和查看
default_template=默認模板
default_template=默認模板
global_params=全局參數.json
env_info_all=環境信息(总).json

View File

@ -246,6 +246,7 @@ permission.system_organization_project_member.delete=删除成员
permission.system_operation_log.name=日志
permission.organization_operation_log.name=日志
permission.personal_settings=个人设置
permission.my_settings_personal_info=个人信息
permission.my_settings=我的设置
permission.api_keys=Api Keys
# template

View File

@ -261,6 +261,7 @@ permission.organization_template.name=Template
permission.system_organization_template.enable=Enable project templates
permission.personal_settings=Personal settings
permission.my_settings=My settings
permission.my_settings_personal_info=Personal information
permission.api_keys=Api Keys
# 状态流

View File

@ -250,6 +250,7 @@ permission.organization_operation_log.name=日志
permission.personal_settings=个人设置
permission.my_settings=我的设置
permission.api_keys=Api Keys
permission.my_settings_personal_info=个人信息
# template
permission.system_template_custom_field.name=模板和字段的关联关系
template_custom_field.exist=模板和字段的关联关系已存在

View File

@ -249,6 +249,7 @@ permission.organization_operation_log.name=日志
permission.personal_settings=個人設置
permission.my_settings=我的設置
permission.api_keys=Api Keys
permission.my_settings_personal_info=個人信息
# template
permission.system_template_custom_field.name=模板和字段的關聯關係
template_custom_field.exist=模板和字段的關聯關係已存在

View File

@ -1,7 +1,8 @@
package io.metersphere.project.controller;
import io.metersphere.project.dto.environment.EnvironmentExportDTO;
import io.metersphere.project.dto.environment.EnvironmentExportRequest;
import io.metersphere.project.dto.environment.EnvironmentFilterRequest;
import io.metersphere.project.dto.environment.EnvironmentImportRequest;
import io.metersphere.project.dto.environment.EnvironmentRequest;
import io.metersphere.project.dto.environment.datasource.DataSource;
import io.metersphere.project.dto.environment.ssl.KeyStoreEntry;
@ -11,6 +12,7 @@ import io.metersphere.project.service.EnvironmentService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.domain.Environment;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.system.log.annotation.Log;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.utils.SessionUtils;
@ -21,6 +23,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -95,15 +98,15 @@ public class EnvironmentController {
@PostMapping(value = "/import", consumes = {"multipart/form-data"})
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_IMPORT)
@Operation(summary = "项目管理-环境-环境目录-导入")
public void create(@RequestPart(value = "file") MultipartFile file) {
environmentService.create(file, SessionUtils.getUserId(), SessionUtils.getCurrentProjectId());
public void create(@RequestPart(value = "request") EnvironmentImportRequest request, @RequestPart(value = "file") MultipartFile file) {
environmentService.create(request, file, SessionUtils.getUserId(), SessionUtils.getCurrentProjectId());
}
@PostMapping("/export")
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_EXPORT)
@Operation(summary = "项目管理-环境-环境目录-导出")
public String export(@Validated @RequestBody EnvironmentExportDTO request) {
return environmentService.export(request);
public ResponseEntity<byte[]> export(@Validated @RequestBody EnvironmentExportRequest request) {
return environmentService.exportZip(request);
}
@PostMapping(value = "/get/entry")
@ -112,4 +115,12 @@ public class EnvironmentController {
return commandService.getEntry(password, sslFiles);
}
@PostMapping("/edit/pos")
@Operation(summary = "项目管理-环境-环境目录-修改排序")
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE)
public void editPos(@Validated @RequestBody PosRequest request) {
environmentService.editPos(request);
}
}

View File

@ -9,6 +9,7 @@ import io.metersphere.project.service.EnvironmentGroupService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.domain.EnvironmentGroup;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.system.log.annotation.Log;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.utils.SessionUtils;
@ -73,4 +74,12 @@ public class EnvironmentGroupController {
public List<OptionDTO> getProject() {
return environmentGroupService.getProject(SessionUtils.getUserId());
}
@PostMapping("/edit/pos")
@Operation(summary = "项目管理-环境-环境组-修改排序")
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE)
public void editPos(@Validated @RequestBody PosRequest request) {
environmentGroupService.editPos(request);
}
}

View File

@ -1,19 +1,16 @@
package io.metersphere.project.dto.environment;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Data
public class EnvironmentExportDTO extends TableBatchProcessDTO {
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{project_application.project_id.not_blank}")
@Size(min = 1, max = 50, message = "{project_parameters.project_id.length_range}")
private String projectId;
public class EnvironmentExportDTO {
@Schema(description = "是否是全局参数")
private Boolean globalParam = false;
@Schema(description = "是否是环境")
private Boolean environment = false;
@Schema(description = "数据")
private String data;
}

View File

@ -0,0 +1,23 @@
package io.metersphere.project.dto.environment;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Data
public class EnvironmentExportRequest extends TableBatchProcessDTO {
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{project_application.project_id.not_blank}")
@Size(min = 1, max = 50, message = "{project_parameters.project_id.length_range}")
private String projectId;
@Schema(description = "是否勾选全局参数", requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean globalParam = false;
@Schema(description = "是否勾选环境", requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean environment = false;
}

View File

@ -0,0 +1,12 @@
package io.metersphere.project.dto.environment;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class EnvironmentImportRequest {
@Schema(description = "是否覆盖数据")
private Boolean cover = false;
}

View File

@ -11,4 +11,16 @@ public interface ExtEnvironmentMapper {
List<Environment> selectByKeyword(@Param("keyword") String keyword, @Param("selectId") boolean selectId , @Param("projectId") String projectId);
List<EnvironmentGroup> groupList(@Param("keyword") String keyword, @Param("projectId") String projectId);
Long getPos(String projectId);
Long getPrePos(@Param("projectId") String projectId, @Param("basePos") Long basePos);
Long getLastPos(@Param("projectId") String projectId, @Param("basePos") Long basePos);
Long getGroupPos(String projectId);
Long getGroupPrePos(@Param("projectId") String projectId, @Param("basePos") Long basePos);
Long getGroupLastPos(@Param("projectId") String projectId, @Param("basePos") Long basePos);
}

View File

@ -35,4 +35,49 @@
</if>
ORDER BY update_time DESC
</select>
<select id="getPos" resultType="java.lang.Long">
SELECT pos
FROM environment
WHERE project_id = #{projectId}
ORDER BY pos DESC
LIMIT 1;
</select>
<select id="getPrePos" resultType="java.lang.Long">
select `pos` from environment where project_id = #{projectId}
<if test="basePos != null">
and `pos` &lt; #{basePos}
</if>
order by `pos` desc limit 1;
</select>
<select id="getLastPos" resultType="java.lang.Long">
select `pos` from environment where project_id = #{projectId}
<if test="basePos != null">
and `pos` &gt; #{basePos}
</if>
order by `pos` desc limit 1;
</select>
<select id="getGroupPos" resultType="java.lang.Long">
SELECT pos
FROM environment_group
WHERE project_id = #{projectId}
ORDER BY pos DESC
LIMIT 1;
</select>
<select id="getGroupPrePos" resultType="java.lang.Long">
select `pos` from environment_group where project_id = #{projectId}
<if test="basePos != null">
and `pos` &gt; #{basePos}
</if>
order by `pos` desc limit 1;
</select>
<select id="getGroupLastPos" resultType="java.lang.Long">
select `pos` from environment_group where project_id = #{projectId}
<if test="basePos != null">
and `pos` &gt; #{basePos}
</if>
order by `pos` desc limit 1;
</select>
</mapper>

View File

@ -1,15 +1,14 @@
package io.metersphere.project.service;
import io.metersphere.sdk.domain.EnvironmentExample;
import io.metersphere.sdk.domain.ProjectParametersExample;
import io.metersphere.sdk.mapper.EnvironmentBlobMapper;
import io.metersphere.sdk.mapper.EnvironmentMapper;
import io.metersphere.sdk.mapper.ProjectParametersMapper;
import io.metersphere.system.service.CleanupProjectResourceService;
import io.metersphere.sdk.domain.*;
import io.metersphere.sdk.mapper.*;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.service.CleanupProjectResourceService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class CleanupEnvironmentResourceService implements CleanupProjectResourceService {
@ -19,6 +18,10 @@ public class CleanupEnvironmentResourceService implements CleanupProjectResource
private EnvironmentBlobMapper environmentBlobMapper;
@Resource
private ProjectParametersMapper projectParametersMapper;
@Resource
private EnvironmentGroupMapper environmentGroupMapper;
@Resource
private EnvironmentGroupRelationMapper environmentGroupRelationMapper;
@Override
public void deleteResources(String projectId) {
@ -29,7 +32,19 @@ public class CleanupEnvironmentResourceService implements CleanupProjectResource
ProjectParametersExample projectExample = new ProjectParametersExample();
projectExample.createCriteria().andProjectIdEqualTo(projectId);
projectParametersMapper.deleteByExample(projectExample);
EnvironmentGroupExample environmentGroupExample = new EnvironmentGroupExample();
environmentGroupExample.createCriteria().andProjectIdEqualTo(projectId);
List<EnvironmentGroup> environmentGroups = environmentGroupMapper.selectByExample(environmentGroupExample);
if (!environmentGroups.isEmpty()) {
//取所有的id
List<String> ids = environmentGroups.stream().map(EnvironmentGroup::getId).toList();
EnvironmentGroupRelationExample environmentGroupRelationExample = new EnvironmentGroupRelationExample();
environmentGroupRelationExample.createCriteria().andEnvironmentGroupIdIn(ids);
environmentGroupRelationMapper.deleteByExample(environmentGroupRelationExample);
}
environmentMapper.deleteByExample(environmentExample);
LogUtils.info("删除当前项目[" + projectId + "]相关环境资源");
}
@Override

View File

@ -31,6 +31,7 @@ public class CreateEnvironmentResourceService implements CreateProjectResourceSe
environment.setCreateUser(project.getCreateUser());
environment.setName(MOCK_EVN_NAME);
environment.setMock(true);
environment.setPos(5000L);
environment.setProjectId(projectId);
environment.setCreateTime(System.currentTimeMillis());
environment.setUpdateUser(project.getCreateUser());

View File

@ -20,9 +20,11 @@ import io.metersphere.system.domain.Organization;
import io.metersphere.system.domain.OrganizationExample;
import io.metersphere.system.domain.UserRoleRelationExample;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.system.mapper.OrganizationMapper;
import io.metersphere.system.mapper.UserRoleRelationMapper;
import io.metersphere.system.uid.IDGenerator;
import io.metersphere.system.utils.ServiceUtils;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
@ -64,6 +66,8 @@ public class EnvironmentGroupService {
@Resource
private OrganizationMapper organizationMapper;
public static final Long ORDER_STEP = 5000L;
public EnvironmentGroup add(EnvironmentGroupRequest request, String userId) {
EnvironmentGroup environmentGroup = new EnvironmentGroup();
BeanUtils.copyProperties(request, environmentGroup);
@ -75,6 +79,7 @@ public class EnvironmentGroupService {
environmentGroup.setUpdateTime(System.currentTimeMillis());
environmentGroup.setCreateUser(userId);
environmentGroup.setUpdateUser(userId);
environmentGroup.setPos(getNextOrder(request.getProjectId()));
environmentGroupMapper.insertSelective(environmentGroup);
request.setId(environmentGroup.getId());
this.insertGroupProject(request);
@ -82,6 +87,11 @@ public class EnvironmentGroupService {
return environmentGroup;
}
public Long getNextOrder(String projectId) {
Long pos = extEnvironmentMapper.getGroupPos(projectId);
return (pos == null ? 0 : pos) + ORDER_STEP;
}
private void insertGroupProject(EnvironmentGroupRequest request) {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
EnvironmentGroupRelationMapper mapper = sqlSession.getMapper(EnvironmentGroupRelationMapper.class);
@ -231,4 +241,13 @@ public class EnvironmentGroupService {
});
return result;
}
public void editPos(PosRequest request) {
ServiceUtils.updatePosField(request,
EnvironmentGroup.class,
environmentGroupMapper::selectByPrimaryKey,
extEnvironmentMapper::getGroupPrePos,
extEnvironmentMapper::getGroupLastPos,
environmentGroupMapper::updateByPrimaryKeySelective);
}
}

View File

@ -2,28 +2,25 @@ package io.metersphere.project.service;
import io.metersphere.project.domain.Project;
import io.metersphere.project.dto.environment.EnvironmentConfig;
import io.metersphere.project.dto.environment.EnvironmentExportDTO;
import io.metersphere.project.dto.environment.EnvironmentFilterRequest;
import io.metersphere.project.dto.environment.EnvironmentRequest;
import io.metersphere.project.dto.environment.*;
import io.metersphere.project.dto.environment.datasource.DataSource;
import io.metersphere.project.mapper.ExtEnvironmentMapper;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.project.utils.FileDownloadUtils;
import io.metersphere.sdk.constants.DefaultRepositoryDir;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.domain.Environment;
import io.metersphere.sdk.domain.EnvironmentBlob;
import io.metersphere.sdk.domain.EnvironmentBlobExample;
import io.metersphere.sdk.domain.EnvironmentExample;
import io.metersphere.sdk.domain.*;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.mapper.EnvironmentBlobMapper;
import io.metersphere.sdk.mapper.EnvironmentMapper;
import io.metersphere.sdk.mapper.ProjectParametersMapper;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.sdk.BaseSystemConfigDTO;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.system.file.FileRequest;
import io.metersphere.system.file.MinioRepository;
import io.metersphere.system.log.constants.OperationLogModule;
@ -33,10 +30,14 @@ import io.metersphere.system.log.service.OperationLogService;
import io.metersphere.system.service.JdbcDriverPluginService;
import io.metersphere.system.service.SystemParameterService;
import io.metersphere.system.uid.IDGenerator;
import io.metersphere.system.utils.ServiceUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@ -63,6 +64,9 @@ public class EnvironmentService {
private OperationLogService operationLogService;
@Resource
private ExtEnvironmentMapper extEnvironmentMapper;
public static final Long ORDER_STEP = 5000L;
@Resource
private ProjectParametersMapper projectParametersMapper;
private static final String USERNAME = "user";
private static final String PASSWORD = "password";
@ -122,6 +126,7 @@ public class EnvironmentService {
environment.setUpdateTime(System.currentTimeMillis());
environment.setMock(false);
environment.setDescription(request.getDescription());
environment.setPos(getNextOrder(request.getProjectId()));
environmentMapper.insert(environment);
request.setId(environment.getId());
EnvironmentBlob environmentBlob = new EnvironmentBlob();
@ -177,8 +182,56 @@ public class EnvironmentService {
return environmentRequest;
}
public String export(EnvironmentExportDTO environmentExportDTO) {
List<String> environmentIds = this.getEnvironmentIds(environmentExportDTO);
public Long getNextOrder(String projectId) {
Long pos = extEnvironmentMapper.getPos(projectId);
return (pos == null ? 0 : pos) + ORDER_STEP;
}
public ResponseEntity<byte[]> exportZip(EnvironmentExportRequest request) {
try {
byte[] bytes = this.download(request);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/octet-stream"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "files.zip")
.body(bytes);
} catch (Exception e) {
return ResponseEntity.status(509).body(e.getMessage().getBytes());
}
}
public byte[] download(EnvironmentExportRequest request) {
Map<String, byte[]> files = new LinkedHashMap<>();
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
if (BooleanUtils.isTrue(request.getGlobalParam())) {
//查询全局参数
EnvironmentExportDTO environmentExportDTO = new EnvironmentExportDTO();
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(request.getProjectId());
List<ProjectParameters> projectParameters = projectParametersMapper.selectByExampleWithBLOBs(projectParametersExample);
if (CollectionUtils.isNotEmpty(projectParameters)) {
environmentExportDTO.setGlobalParam(true);
environmentExportDTO.setData(new String(projectParameters.get(0).getParameters()));
files.put(StringUtils.join(project.getName(), "_", Translator.get("global_params")), JSON.toJSONString(environmentExportDTO).getBytes());
}
}
if (BooleanUtils.isTrue(request.getEnvironment())) {
EnvironmentExportDTO environmentExportDTO = new EnvironmentExportDTO();
List<EnvironmentRequest> environmentList = this.exportEnv(request);
if (CollectionUtils.isNotEmpty(environmentList)) {
environmentExportDTO.setEnvironment(true);
environmentExportDTO.setData(JSON.toJSONString(environmentList));
if (environmentList.size() == 1) {
files.put(StringUtils.join(project.getName(), "_", environmentList.get(0).getName(), ".json"), JSON.toJSONString(environmentList.get(0)).getBytes());
} else {
files.put(StringUtils.join(project.getName(), "_", Translator.get("env_info_all")), JSON.toJSONString(environmentExportDTO).getBytes());
}
}
}
return FileDownloadUtils.listBytesToZip(files);
}
public List<EnvironmentRequest> exportEnv(EnvironmentExportRequest environmentExportRequest) {
List<String> environmentIds = this.getEnvironmentIds(environmentExportRequest);
// 查询环境
EnvironmentExample environmentExample = new EnvironmentExample();
environmentExample.createCriteria().andIdIn(environmentIds);
@ -205,20 +258,7 @@ public class EnvironmentService {
}
environmentRequests.add(environmentRequest);
});
return JSON.toJSONString(environmentRequests);
}
private List<String> getEnvironmentIds(EnvironmentExportDTO request) {
if (request.isSelectAll()) {
List<Environment> environments = extEnvironmentMapper.selectByKeyword(request.getCondition().getKeyword(), true, request.getProjectId());
List<String> environmentIds = environments.stream().map(Environment::getId).collect(Collectors.toList());
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(request.getExcludeIds())) {
environmentIds.removeAll(request.getExcludeIds());
}
return environmentIds;
} else {
return request.getSelectIds();
}
return environmentRequests;
}
public void checkEnvironmentExist(Environment environment) {
@ -231,61 +271,29 @@ public class EnvironmentService {
}
}
public void create(MultipartFile file, String userId, String currentProjectId) {
if (file != null) {
try {
InputStream inputStream = file.getInputStream();
// 读取文件内容
String content = new String(inputStream.readAllBytes());
inputStream.close();
// 拿到的参数是一个list
List<EnvironmentRequest> environmentRequests = JSON.parseArray(content, EnvironmentRequest.class);
if (CollectionUtils.isNotEmpty(environmentRequests)) {
List<Environment> environments = new ArrayList<>();
List<EnvironmentBlob> environmentBlobs = new ArrayList<>();
List<LogDTO> logDos = new ArrayList<>();
Project project = projectMapper.selectByPrimaryKey(currentProjectId);
environmentRequests.forEach(environmentRequest -> {
Environment environment = new Environment();
environment.setId(IDGenerator.nextStr());
environment.setCreateUser(userId);
environment.setName(environmentRequest.getName());
environment.setProjectId(currentProjectId);
environment.setUpdateUser(userId);
environment.setUpdateTime(System.currentTimeMillis());
environment.setMock(false);
checkEnvironmentExist(environment);
environment.setCreateTime(System.currentTimeMillis());
environment.setProjectId(currentProjectId);
environments.add(environment);
EnvironmentBlob environmentBlob = new EnvironmentBlob();
environmentBlob.setId(environment.getId());
environmentBlob.setConfig(JSON.toJSONBytes(environmentRequest.getConfig()));
environmentBlobs.add(environmentBlob);
LogDTO logDTO = new LogDTO(
currentProjectId,
project.getOrganizationId(),
environment.getId(),
userId,
OperationLogType.ADD.name(),
OperationLogModule.PROJECT_ENVIRONMENT_SETTING,
environment.getName());
logDTO.setMethod(HttpMethodConstants.POST.name());
logDTO.setOriginalValue(JSON.toJSONBytes(environmentRequest.getConfig()));
logDTO.setPath(PATH);
logDos.add(logDTO);
});
environmentMapper.batchInsert(environments);
environmentBlobMapper.batchInsert(environmentBlobs);
operationLogService.batchAdd(logDos);
}
} catch (Exception e) {
LogUtils.error("获取文件输入流异常", e);
throw new RuntimeException("获取文件输入流异常", e);
private List<String> getEnvironmentIds(EnvironmentExportRequest request) {
if (request.isSelectAll()) {
List<Environment> environments = extEnvironmentMapper.selectByKeyword(request.getCondition().getKeyword(), true, request.getProjectId());
List<String> environmentIds = environments.stream().map(Environment::getId).collect(Collectors.toList());
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(request.getExcludeIds())) {
environmentIds.removeAll(request.getExcludeIds());
}
return environmentIds;
} else {
return request.getSelectIds();
}
}
public Environment getExitsEnv(Environment environment) {
EnvironmentExample environmentExample = new EnvironmentExample();
environmentExample.createCriteria().andNameEqualTo(environment.getName()).andProjectIdEqualTo(environment.getProjectId()).andIdNotEqualTo(environment.getId());
List<Environment> environments = environmentMapper.selectByExample(environmentExample);
if (CollectionUtils.isNotEmpty(environments)) {
return environments.get(0);
}
return null;
}
public EnvironmentRequest update(EnvironmentRequest request, String userId, List<MultipartFile> sslFiles) {
Environment environment = new Environment();
environment.setId(request.getId());
@ -303,4 +311,104 @@ public class EnvironmentService {
return request;
}
public void create(EnvironmentImportRequest request, MultipartFile file, String userId, String currentProjectId) {
if (file != null) {
try {
InputStream inputStream = file.getInputStream();
// 读取文件内容
String content = new String(inputStream.readAllBytes());
inputStream.close();
//参数是一个对象
EnvironmentExportDTO environmentExportDTO = JSON.parseObject(content, EnvironmentExportDTO.class);
if (environmentExportDTO != null) {
if (BooleanUtils.isTrue(environmentExportDTO.getGlobalParam())) {
String data = environmentExportDTO.getData();
//解析出来的参数是一个对象
if (BooleanUtils.isTrue(request.getCover())) {
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(currentProjectId);
if (projectParametersMapper.countByExample(projectParametersExample) > 0) {
projectParametersMapper.deleteByExample(projectParametersExample);
}
ProjectParameters projectParameters = new ProjectParameters();
projectParameters.setId(IDGenerator.nextStr());
projectParameters.setProjectId(currentProjectId);
projectParameters.setCreateUser(userId);
projectParameters.setUpdateUser(userId);
projectParameters.setCreateTime(System.currentTimeMillis());
projectParameters.setUpdateTime(System.currentTimeMillis());
projectParameters.setParameters(data.getBytes());
projectParametersMapper.insert(projectParameters);
}
}
if (BooleanUtils.isTrue(environmentExportDTO.getEnvironment())) {
// 拿到的参数是一个list
List<EnvironmentRequest> environmentRequests = JSON.parseArray(environmentExportDTO.getData(), EnvironmentRequest.class);
if (CollectionUtils.isNotEmpty(environmentRequests)) {
List<Environment> environments = new ArrayList<>();
List<EnvironmentBlob> environmentBlobs = new ArrayList<>();
List<LogDTO> logDos = new ArrayList<>();
Project project = projectMapper.selectByPrimaryKey(currentProjectId);
environmentRequests.forEach(environmentRequest -> {
Environment environment = new Environment();
environment.setId(IDGenerator.nextStr());
environment.setCreateUser(userId);
environment.setName(environmentRequest.getName());
environment.setProjectId(currentProjectId);
environment.setUpdateUser(userId);
environment.setUpdateTime(System.currentTimeMillis());
environment.setMock(false);
environment.setPos(getNextOrder(currentProjectId));
Environment exitsEnv = getExitsEnv(environment);
if (exitsEnv != null && BooleanUtils.isTrue(request.getCover())) {
environmentMapper.deleteByPrimaryKey(exitsEnv.getId());
environmentBlobMapper.deleteByPrimaryKey(exitsEnv.getId());
} else if (exitsEnv != null && BooleanUtils.isFalse(request.getCover())) {
return;
}
environment.setCreateTime(System.currentTimeMillis());
environment.setProjectId(currentProjectId);
environments.add(environment);
EnvironmentBlob environmentBlob = new EnvironmentBlob();
environmentBlob.setId(environment.getId());
environmentBlob.setConfig(JSON.toJSONBytes(environmentRequest.getConfig()));
environmentBlobs.add(environmentBlob);
LogDTO logDTO = new LogDTO(
currentProjectId,
project.getOrganizationId(),
environment.getId(),
userId,
OperationLogType.ADD.name(),
OperationLogModule.PROJECT_ENVIRONMENT_SETTING,
environment.getName());
logDTO.setMethod(HttpMethodConstants.POST.name());
logDTO.setOriginalValue(JSON.toJSONBytes(environmentRequest.getConfig()));
logDTO.setPath(PATH);
logDos.add(logDTO);
});
if (CollectionUtils.isNotEmpty(environments)
&& CollectionUtils.isNotEmpty(environmentBlobs)
&& CollectionUtils.isNotEmpty(logDos)) {
environmentMapper.batchInsert(environments);
environmentBlobMapper.batchInsert(environmentBlobs);
operationLogService.batchAdd(logDos);
}
}
}
}
} catch (Exception e) {
LogUtils.error("获取文件输入流异常", e);
throw new RuntimeException("获取文件输入流异常", e);
}
}
}
public void editPos(PosRequest request) {
ServiceUtils.updatePosField(request,
Environment.class,
environmentMapper::selectByPrimaryKey,
extEnvironmentMapper::getPrePos,
extEnvironmentMapper::getLastPos,
environmentMapper::updateByPrimaryKeySelective);
}
}

View File

@ -1,6 +1,10 @@
package io.metersphere.project.controller;
import io.metersphere.project.service.CleanupEnvironmentResourceService;
import io.metersphere.sdk.domain.EnvironmentGroup;
import io.metersphere.sdk.domain.EnvironmentGroupRelation;
import io.metersphere.sdk.mapper.EnvironmentGroupMapper;
import io.metersphere.sdk.mapper.EnvironmentGroupRelationMapper;
import io.metersphere.system.invoker.ProjectServiceInvoker;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
@ -19,6 +23,10 @@ public class CleanupEnvironmentTests {
private final ProjectServiceInvoker serviceInvoker;
@Resource
private CleanupEnvironmentResourceService cleanupEnvironmentResourceService;
@Resource
private EnvironmentGroupMapper environmentGroupMapper;
@Resource
private EnvironmentGroupRelationMapper environmentGroupRelationMapper;
@Autowired
public CleanupEnvironmentTests(ProjectServiceInvoker serviceInvoker) {
this.serviceInvoker = serviceInvoker;
@ -27,6 +35,22 @@ public class CleanupEnvironmentTests {
@Test
@Order(1)
public void testCleanupResource() throws Exception {
EnvironmentGroup environmentGroup = new EnvironmentGroup();
environmentGroup.setId("test");
environmentGroup.setPos(1L);
environmentGroup.setName("test");
environmentGroup.setProjectId("test");
environmentGroup.setUpdateUser("admin");
environmentGroup.setCreateUser("admin");
environmentGroup.setCreateTime(System.currentTimeMillis());
environmentGroup.setUpdateTime(System.currentTimeMillis());
environmentGroupMapper.insert(environmentGroup);
EnvironmentGroupRelation environmentGroupRelation = new EnvironmentGroupRelation();
environmentGroupRelation.setId("test");
environmentGroupRelation.setEnvironmentGroupId("test");
environmentGroupRelation.setEnvironmentId("test");
environmentGroupRelation.setProjectId("test");
environmentGroupRelationMapper.insert(environmentGroupRelation);
serviceInvoker.invokeServices("test");
cleanupEnvironmentResourceService.cleanReportResources("test");
}

View File

@ -21,16 +21,20 @@ import io.metersphere.project.dto.environment.variables.CommonVariables;
import io.metersphere.sdk.constants.DefaultRepositoryDir;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.constants.VariableTypeConstants;
import io.metersphere.sdk.domain.Environment;
import io.metersphere.sdk.domain.EnvironmentBlob;
import io.metersphere.sdk.domain.EnvironmentExample;
import io.metersphere.sdk.domain.ProjectParametersExample;
import io.metersphere.sdk.mapper.EnvironmentBlobMapper;
import io.metersphere.sdk.mapper.EnvironmentMapper;
import io.metersphere.sdk.mapper.ProjectParametersMapper;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.system.file.FileRequest;
import io.metersphere.system.file.MinioRepository;
import io.metersphere.system.log.constants.OperationLogType;
@ -80,6 +84,7 @@ public class EnvironmentControllerTests extends BaseTest {
private static final String getEnTry = prefix + "/get/entry";
private static final String importEnv = prefix + "/import";
private static final String exportEnv = prefix + "/export";
private static final String POS_URL = prefix + "/edit/pos";
private static final String validate = prefix + "/database/validate";
private static final String getOptions = prefix + "/database/driver-options/";
@ -92,6 +97,8 @@ public class EnvironmentControllerTests extends BaseTest {
private EnvironmentMapper environmentMapper;
@Resource
private EnvironmentBlobMapper environmentBlobMapper;
@Resource
private ProjectParametersMapper projectParametersMapper;
@Value("${spring.datasource.url}")
private String dburl;
@Value("${spring.datasource.username}")
@ -709,6 +716,7 @@ public class EnvironmentControllerTests extends BaseTest {
environment.setUpdateTime(System.currentTimeMillis());
environment.setCreateUser("createUser");
environment.setMock(false);
environment.setPos(1000L);
environment.setCreateTime(System.currentTimeMillis());
environmentMapper.insert(environment);
EnvironmentBlob environmentBlob = new EnvironmentBlob();
@ -885,6 +893,24 @@ public class EnvironmentControllerTests extends BaseTest {
@Test
@Order(10)
public void testPos() throws Exception {
PosRequest posRequest = new PosRequest();
posRequest.setProjectId(DEFAULT_PROJECT_ID);
posRequest.setTargetId("environmentId1");
EnvironmentExample example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andMockEqualTo(true);
List<Environment> environments = environmentMapper.selectByExample(example);
posRequest.setMoveId(environments.get(0).getId());
posRequest.setMoveMode("AFTER");
this.requestPostWithOkAndReturn(POS_URL, posRequest);
posRequest.setMoveMode("BEFORE");
this.requestPostWithOkAndReturn(POS_URL, posRequest);
}
@Test
@Order(11)
public void testDeleteSuccess() throws Exception {
//校验参数
EnvironmentExample example = new EnvironmentExample();
@ -921,7 +947,7 @@ public class EnvironmentControllerTests extends BaseTest {
}
@Test
@Order(11)
@Order(12)
public void testList() throws Exception {
EnvironmentFilterRequest environmentDTO = new EnvironmentFilterRequest();
environmentDTO.setProjectId(DEFAULT_PROJECT_ID);
@ -947,7 +973,7 @@ public class EnvironmentControllerTests extends BaseTest {
}
@Test
@Order(12)
@Order(13)
public void testGetEntry() throws Exception {
String password = "123456";
FileInputStream inputStream = new FileInputStream(new File(
@ -985,35 +1011,83 @@ public class EnvironmentControllerTests extends BaseTest {
}
@Test
@Order(13)
public void testExport() throws Exception {
//指定id
EnvironmentExportDTO environmentExportDTO = new EnvironmentExportDTO();
environmentExportDTO.setProjectId(DEFAULT_PROJECT_ID);
environmentExportDTO.setSelectIds(List.of("environmentId1"));
private List<CommonVariables> getEnvVariables(int length) {
List<CommonVariables> commonVariables = new ArrayList<>();
for (int i = 0; i < length; i++) {
CommonVariables envVariable = new CommonVariables();
envVariable.setName("name" + i);
envVariable.setValue("value" + i);
envVariable.setDescription("desc" + i);
envVariable.setType(VariableTypeConstants.CONSTANT.name());
commonVariables.add(envVariable);
}
return commonVariables;
}
MvcResult mvcResult = this.responsePost(exportEnv, environmentExportDTO);
String response = parseObjectFromMvcResult(mvcResult, String.class);
//判断response只有一条数据
Assertions.assertNotNull(response);
List<EnvironmentRequest> environments = JSON.parseArray(response, EnvironmentRequest.class);
Assertions.assertEquals(1, environments.size());
//全选
environmentExportDTO.setSelectIds(List.of("environmentId1"));
environmentExportDTO.setSelectAll(true);
environmentExportDTO.setExcludeIds(List.of("environmentId1"));
mvcResult = this.responsePost(exportEnv, environmentExportDTO);
response = parseObjectFromMvcResult(mvcResult, String.class);
Assertions.assertNotNull(response);
environmentExportDTO.setProjectId(DEFAULT_PROJECT_ID);
//校验权限
requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ_EXPORT, exportEnv, environmentExportDTO);
//根据需要多长的list 生成不同的List<KeyValue> headers
private List<KeyValue> getHeaders(int length) {
List<KeyValue> headers = new ArrayList<>();
for (int i = 0; i < length; i++) {
KeyValue header = new KeyValue();
header.setName("key" + i);
header.setValue("value" + i);
headers.add(header);
}
return headers;
}
@Test
@Order(14)
public void testExport() throws Exception {
//指定id
EnvironmentExportRequest environmentExportRequest = new EnvironmentExportRequest();
environmentExportRequest.setProjectId(DEFAULT_PROJECT_ID);
environmentExportRequest.setEnvironment(true);
environmentExportRequest.setSelectIds(List.of("environmentId1"));
MvcResult mvcResult = this.requestPostDownloadFile(exportEnv, null, environmentExportRequest);
byte[] fileBytes = mvcResult.getResponse().getContentAsByteArray();
Assertions.assertNotNull(fileBytes);
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
if (projectParametersMapper.countByExample(projectParametersExample) == 0) {
//全局参数
GlobalParamsRequest request = new GlobalParamsRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
GlobalParams globalParams = new GlobalParams();
globalParams.setHeaders(getHeaders(1));
globalParams.setCommonVariables(getEnvVariables(1));
request.setGlobalParams(globalParams);
this.responsePost("/project/global/params/add", request);
}
//全选
environmentExportRequest.setGlobalParam(true);
environmentExportRequest.setSelectIds(List.of("environmentId1"));
environmentExportRequest.setSelectAll(true);
environmentExportRequest.setExcludeIds(List.of("environmentId1"));
MvcResult mvcResult1 = this.requestPostDownloadFile(exportEnv, null, environmentExportRequest);
byte[] fileBytes1 = mvcResult1.getResponse().getContentAsByteArray();
Assertions.assertNotNull(fileBytes1);
projectParametersMapper.deleteByExample(projectParametersExample);
environmentExportRequest.setSelectIds(List.of("不存在blob"));
environmentExportRequest.setSelectAll(false);
environmentExportRequest.setEnvironment(true);
mockMvc.perform(getPostRequestBuilder(exportEnv, environmentExportRequest))
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
.andExpect(ERROR_REQUEST_MATCHER);
}
protected MvcResult requestPostDownloadFile(String url, MediaType contentType, Object param) throws Exception {
if (contentType == null) {
contentType = MediaType.APPLICATION_OCTET_STREAM;
}
return mockMvc.perform(getPostRequestBuilder(url, param))
.andExpect(content().contentType(contentType))
.andExpect(status().isOk()).andReturn();
}
@Test
@Order(15)
public void testImport() throws Exception {
//校验参数
FileInputStream inputStream = new FileInputStream(new File(
@ -1021,10 +1095,70 @@ public class EnvironmentControllerTests extends BaseTest {
.getPath()));
MockMultipartFile file = new MockMultipartFile("file", "huanj.json", MediaType.APPLICATION_OCTET_STREAM_VALUE, inputStream);
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
EnvironmentImportRequest request = new EnvironmentImportRequest();
request.setCover(true);
paramMap.add("file", List.of(file));
paramMap.add("request", JSON.toJSONString(request));
requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID);
//校验权限
requestMultipartPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ_IMPORT, importEnv, paramMap);
requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID);
request.setCover(false);
paramMap.clear();
paramMap.add("file", List.of(file));
paramMap.add("request", JSON.toJSONString(request));
requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID);
//上传全局参数
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
if (projectParametersMapper.countByExample(projectParametersExample) == 0) {
//全局参数
GlobalParamsRequest globalParamsRequest = new GlobalParamsRequest();
globalParamsRequest.setProjectId(DEFAULT_PROJECT_ID);
GlobalParams globalParams = new GlobalParams();
globalParams.setHeaders(getHeaders(1));
globalParams.setCommonVariables(getEnvVariables(1));
globalParamsRequest.setGlobalParams(globalParams);
this.responsePost("/project/global/params/add", globalParamsRequest);
}
inputStream = new FileInputStream(new File(
this.getClass().getClassLoader().getResource("file/globalParam.json")
.getPath()));
file = new MockMultipartFile("file", "globalParam.json", MediaType.APPLICATION_OCTET_STREAM_VALUE, inputStream);
paramMap = new LinkedMultiValueMap<>();
request = new EnvironmentImportRequest();
request.setCover(true);
paramMap.add("file", List.of(file));
paramMap.add("request", JSON.toJSONString(request));
requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID);
request.setCover(false);
paramMap.clear();
paramMap.add("file", List.of(file));
paramMap.add("request", JSON.toJSONString(request));
requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID);
projectParametersMapper.deleteByExample(projectParametersExample);
inputStream = new FileInputStream(new File(
this.getClass().getClassLoader().getResource("file/txtFile.txt")
.getPath()));
file = new MockMultipartFile("file", "txtFile.txt", MediaType.APPLICATION_OCTET_STREAM_VALUE, inputStream);
paramMap = new LinkedMultiValueMap<>();
request = new EnvironmentImportRequest();
request.setCover(true);
paramMap.add("file", List.of(file));
paramMap.add("request", JSON.toJSONString(request));
MockMultipartHttpServletRequestBuilder requestBuilder = getMultipartRequestBuilderWithParam(importEnv, paramMap);
MockHttpServletRequestBuilder header = requestBuilder
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.header(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN")
.header(SessionConstants.CURRENT_PROJECT, DEFAULT_PROJECT_ID);
mockMvc.perform(header)
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(ERROR_REQUEST_MATCHER);
}
}

View File

@ -15,6 +15,7 @@ import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.system.log.constants.OperationLogType;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.*;
@ -48,6 +49,7 @@ public class EnvironmentGroupControllerTests extends BaseTest {
private static final String delete = prefix + "/delete/";
private static final String list = prefix + "/list";
private static final String getProject = prefix + "/get-project";
private static final String POS_URL = prefix + "/edit/pos";
private static final ResultMatcher BAD_REQUEST_MATCHER = status().isBadRequest();
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
private static String GROUP_ID;
@ -295,6 +297,23 @@ public class EnvironmentGroupControllerTests extends BaseTest {
requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ, list, environmentDTO);
}
@Test
@Order(10)
public void testPos() throws Exception {
PosRequest posRequest = new PosRequest();
posRequest.setProjectId(DEFAULT_PROJECT_ID);
posRequest.setTargetId(getEnvironmentGroup());
EnvironmentGroupExample example = new EnvironmentGroupExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("校验权限");
List<EnvironmentGroup> environments = environmentGroupMapper.selectByExample(example);
posRequest.setMoveId(environments.get(0).getId());
posRequest.setMoveMode("AFTER");
this.requestPostWithOkAndReturn(POS_URL, posRequest);
posRequest.setMoveMode("BEFORE");
this.requestPostWithOkAndReturn(POS_URL, posRequest);
}
@Test
@Order(12)
public void testDeleteSuccess() throws Exception {

View File

@ -0,0 +1 @@
{"globalParam":true,"environment":false,"data":"{\"headers\":[{\"name\":\"key0\",\"value\":\"value0\",\"enable\":true}],\"commonVariables\":[{\"id\":null,\"name\":\"name0\",\"type\":\"CONSTANT\",\"value\":\"value0\",\"enable\":true,\"description\":\"desc0\"}]}"}

File diff suppressed because one or more lines are too long

View File

@ -297,26 +297,32 @@
"type": "SYSTEM",
"children": [
{
"id": "API_KEYS",
"name": "permission.api_keys",
"id": "PERSONAL_INFO",
"name": "my_settings_personal_info",
"permissions": [
{
"id": "SYSTEM_PERSONAL:READ"
},
{
"id": "SYSTEM_PERSONAL:READ+UPDATE"
}
]
},
{
"id": "API_KEYS",
"name": "permission.api_keys",
"permissions": [
{
"id": "SYSTEM_PERSONAL_API_KEY:READ+ADD"
},
{
"id": "SYSTEM_PERSONAL_API_KEY_ADD:READ+ADD"
"id": "SYSTEM_PERSONAL_API_KEY:READ"
},
{
"id": "SYSTEM_PERSONAL_API_KEY_ADD:READ"
"id": "SYSTEM_PERSONAL_API_KEY:READ+UPDATE"
},
{
"id": "SYSTEM_PERSONAL_API_KEY_ADD:READ+UPDATE"
},
{
"id": "SYSTEM_PERSONAL_API_KEY_ADD:READ+DELETE"
"id": "SYSTEM_PERSONAL_API_KEY:READ+DELETE"
}
]
}