feat(接口测试): 接口管理模块接口定义变更记录处理
This commit is contained in:
parent
e72c5126f2
commit
40a4e3b72d
|
@ -36,6 +36,9 @@ public class OperationHistory implements Serializable {
|
|||
@Schema(description = "操作模块/api/case/scenario/ui")
|
||||
private String module;
|
||||
|
||||
@Schema(description = "关联id(关联变更记录id来源)")
|
||||
private Long refId;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public enum Column {
|
||||
|
@ -45,7 +48,8 @@ public class OperationHistory implements Serializable {
|
|||
createUser("create_user", "createUser", "VARCHAR", false),
|
||||
sourceId("source_id", "sourceId", "VARCHAR", false),
|
||||
type("type", "type", "VARCHAR", true),
|
||||
module("module", "module", "VARCHAR", true);
|
||||
module("module", "module", "VARCHAR", true),
|
||||
refId("ref_id", "refId", "BIGINT", false);
|
||||
|
||||
private static final String BEGINNING_DELIMITER = "`";
|
||||
|
||||
|
|
|
@ -573,6 +573,66 @@ public class OperationHistoryExample {
|
|||
addCriterion("`module` not between", value1, value2, "module");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdIsNull() {
|
||||
addCriterion("ref_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdIsNotNull() {
|
||||
addCriterion("ref_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdEqualTo(Long value) {
|
||||
addCriterion("ref_id =", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdNotEqualTo(Long value) {
|
||||
addCriterion("ref_id <>", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdGreaterThan(Long value) {
|
||||
addCriterion("ref_id >", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("ref_id >=", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdLessThan(Long value) {
|
||||
addCriterion("ref_id <", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdLessThanOrEqualTo(Long value) {
|
||||
addCriterion("ref_id <=", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdIn(List<Long> values) {
|
||||
addCriterion("ref_id in", values, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdNotIn(List<Long> values) {
|
||||
addCriterion("ref_id not in", values, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdBetween(Long value1, Long value2) {
|
||||
addCriterion("ref_id between", value1, value2, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdNotBetween(Long value1, Long value2) {
|
||||
addCriterion("ref_id not between", value1, value2, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<result column="source_id" jdbcType="VARCHAR" property="sourceId" />
|
||||
<result column="type" jdbcType="VARCHAR" property="type" />
|
||||
<result column="module" jdbcType="VARCHAR" property="module" />
|
||||
<result column="ref_id" jdbcType="BIGINT" property="refId" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
|
@ -69,7 +70,7 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, project_id, create_time, create_user, source_id, `type`, `module`
|
||||
id, project_id, create_time, create_user, source_id, `type`, `module`, ref_id
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.system.domain.OperationHistoryExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -104,10 +105,10 @@
|
|||
<insert id="insert" parameterType="io.metersphere.system.domain.OperationHistory">
|
||||
insert into operation_history (id, project_id, create_time,
|
||||
create_user, source_id, `type`,
|
||||
`module`)
|
||||
`module`, ref_id)
|
||||
values (#{id,jdbcType=BIGINT}, #{projectId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
|
||||
#{createUser,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
|
||||
#{module,jdbcType=VARCHAR})
|
||||
#{module,jdbcType=VARCHAR}, #{refId,jdbcType=BIGINT})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.system.domain.OperationHistory">
|
||||
insert into operation_history
|
||||
|
@ -133,6 +134,9 @@
|
|||
<if test="module != null">
|
||||
`module`,
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
ref_id,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -156,6 +160,9 @@
|
|||
<if test="module != null">
|
||||
#{module,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
#{refId,jdbcType=BIGINT},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.system.domain.OperationHistoryExample" resultType="java.lang.Long">
|
||||
|
@ -188,6 +195,9 @@
|
|||
<if test="record.module != null">
|
||||
`module` = #{record.module,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.refId != null">
|
||||
ref_id = #{record.refId,jdbcType=BIGINT},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
|
@ -201,7 +211,8 @@
|
|||
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||
source_id = #{record.sourceId,jdbcType=VARCHAR},
|
||||
`type` = #{record.type,jdbcType=VARCHAR},
|
||||
`module` = #{record.module,jdbcType=VARCHAR}
|
||||
`module` = #{record.module,jdbcType=VARCHAR},
|
||||
ref_id = #{record.refId,jdbcType=BIGINT}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -227,6 +238,9 @@
|
|||
<if test="module != null">
|
||||
`module` = #{module,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
ref_id = #{refId,jdbcType=BIGINT},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=BIGINT}
|
||||
</update>
|
||||
|
@ -237,17 +251,18 @@
|
|||
create_user = #{createUser,jdbcType=VARCHAR},
|
||||
source_id = #{sourceId,jdbcType=VARCHAR},
|
||||
`type` = #{type,jdbcType=VARCHAR},
|
||||
`module` = #{module,jdbcType=VARCHAR}
|
||||
`module` = #{module,jdbcType=VARCHAR},
|
||||
ref_id = #{refId,jdbcType=BIGINT}
|
||||
where id = #{id,jdbcType=BIGINT}
|
||||
</update>
|
||||
<insert id="batchInsert" parameterType="map">
|
||||
insert into operation_history
|
||||
(id, project_id, create_time, create_user, source_id, `type`, `module`)
|
||||
(id, project_id, create_time, create_user, source_id, `type`, `module`, ref_id)
|
||||
values
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(#{item.id,jdbcType=BIGINT}, #{item.projectId,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT},
|
||||
#{item.createUser,jdbcType=VARCHAR}, #{item.sourceId,jdbcType=VARCHAR}, #{item.type,jdbcType=VARCHAR},
|
||||
#{item.module,jdbcType=VARCHAR})
|
||||
#{item.module,jdbcType=VARCHAR}, #{item.refId,jdbcType=BIGINT})
|
||||
</foreach>
|
||||
</insert>
|
||||
<insert id="batchInsertSelective" parameterType="map">
|
||||
|
@ -281,6 +296,9 @@
|
|||
<if test="'module'.toString() == column.value">
|
||||
#{item.module,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="'ref_id'.toString() == column.value">
|
||||
#{item.refId,jdbcType=BIGINT}
|
||||
</if>
|
||||
</foreach>
|
||||
)
|
||||
</foreach>
|
||||
|
|
|
@ -134,15 +134,15 @@ CREATE TABLE IF NOT EXISTS worker_node
|
|||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT = 'DB WorkerID Assigner for UID Generator';
|
||||
|
||||
CREATE TABLE operation_history
|
||||
(
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键' ,
|
||||
`project_id` VARCHAR(50) NOT NULL DEFAULT 'NONE' COMMENT '项目id',
|
||||
`create_time` BIGINT NOT NULL COMMENT '操作时间',
|
||||
`create_user` VARCHAR(50) COMMENT '操作人',
|
||||
`source_id` VARCHAR(50) COMMENT '资源id',
|
||||
`type` VARCHAR(20) NOT NULL COMMENT '操作类型/add/update/delete',
|
||||
`module` VARCHAR(50) COMMENT '操作模块/api/case/scenario/ui',
|
||||
CREATE TABLE IF NOT EXISTS operation_history(
|
||||
`id` BIGINT(50) NOT NULL AUTO_INCREMENT COMMENT '主键' ,
|
||||
`project_id` VARCHAR(50) NOT NULL DEFAULT 'NONE' COMMENT '项目id' ,
|
||||
`create_time` BIGINT NOT NULL COMMENT '操作时间' ,
|
||||
`create_user` VARCHAR(50) COMMENT '操作人' ,
|
||||
`source_id` VARCHAR(50) COMMENT '资源id' ,
|
||||
`type` VARCHAR(20) NOT NULL COMMENT '操作类型/add/update/delete' ,
|
||||
`module` VARCHAR(50) COMMENT '操作模块/api/case/scenario/ui' ,
|
||||
`ref_id` BIGINT(50) COMMENT '关联id(关联变更记录id来源)' ,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
|
@ -154,9 +154,6 @@ CREATE INDEX idx_module ON operation_history (`module`);
|
|||
CREATE INDEX idx_project_id ON operation_history (`project_id`);
|
||||
CREATE INDEX idx_type ON operation_history (`type`);
|
||||
|
||||
-- set innodb lock wait timeout to default
|
||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS share_info
|
||||
(
|
||||
`id` VARCHAR(50) NOT NULL COMMENT '分享ID' ,
|
||||
|
@ -170,3 +167,6 @@ CREATE TABLE IF NOT EXISTS share_info
|
|||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '分享';
|
||||
|
||||
-- set innodb lock wait timeout to default
|
||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
||||
|
|
|
@ -299,6 +299,15 @@ user_local_config.type.not_blank=用户本地配置类型不能为空
|
|||
user_local_config.type.length_range=用户本地配置类型长度必须在{min}和{max}之间
|
||||
current_user_local_config_not_validate=当前用户本地配置不合法
|
||||
|
||||
# operation_history
|
||||
operation_history.id.not_blank=变更记录 ID 不能为空
|
||||
operation_history.project_id.not_blank=变更记录项目 ID 不能为空
|
||||
operation_history.project_id.length_range=变更记录项目 ID 长度必须在{min}和{max}之间
|
||||
operation_history.type.not_blank=变更记录操作类型不能为空
|
||||
operation_history.type.length_range=变更记录操作类型长度必须在{min}和{max}之间
|
||||
operation_history.source_id.not_blank=变更记录资源 ID 不能为空
|
||||
operation_history.version_id.not_blank=变更记录版本 ID 不能为空
|
||||
operation_history.version_id.length_range=变更记录版本 ID 长度必须在{min}和{max}之间
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -301,5 +301,13 @@ user_local_config.type.not_blank=type cannot be empty
|
|||
user_local_config.type.length_range=type length must be between {min} and {max}
|
||||
current_user_local_config_not_validate=Current user local config not validate
|
||||
|
||||
|
||||
# operation_history
|
||||
operation_history.id.not_blank=Operating history id cannot be empty
|
||||
operation_history.project_id.not_blank=Operating history project id cannot be empty
|
||||
operation_history.project_id.length_range=Operating history project id length must be between {min} and {max}
|
||||
operation_history.type.not_blank=Operating history type cannot be empty
|
||||
operation_history.type.length_range=Operating history type length must be between {min} and {max}
|
||||
operation_history.source_id.not_blank=Operating history source id cannot be empty
|
||||
operation_history.version_id.not_blank=Operating history version id cannot be empty
|
||||
operation_history.version_id.length_range=Operating history version id length must be between {min} and {max}
|
||||
|
||||
|
|
|
@ -300,3 +300,13 @@ user_local_config.user_url.length_range=用户本地配置用户URL长度必须
|
|||
user_local_config.type.not_blank=用户本地配置类型不能为空
|
||||
user_local_config.type.length_range=用户本地配置类型长度必须在{min}和{max}之间
|
||||
current_user_local_config_not_validate=当前用户本地配置不合法
|
||||
|
||||
# operation_history
|
||||
operation_history.id.not_blank=变更记录 ID 不能为空
|
||||
operation_history.project_id.not_blank=变更记录项目 ID 不能为空
|
||||
operation_history.project_id.length_range=变更记录项目 ID 长度必须在{min}和{max}之间
|
||||
operation_history.type.not_blank=变更记录操作类型不能为空
|
||||
operation_history.type.length_range=变更记录操作类型长度必须在{min}和{max}之间
|
||||
operation_history.source_id.not_blank=变更记录资源 ID 不能为空
|
||||
operation_history.version_id.not_blank=变更记录版本 ID 不能为空
|
||||
operation_history.version_id.length_range=变更记录版本 ID 长度必须在{min}和{max}之间
|
|
@ -298,4 +298,14 @@ user_local_config.user_url.not_blank=用户本地配置用户URL不能為空
|
|||
user_local_config.user_url.length_range=用户本地配置用户URL長度必須在{min}和{max}之间
|
||||
user_local_config.type.not_blank=用户本地配置类型不能為空
|
||||
user_local_config.type.length_range=用户本地配置类型長度必須在{min}和{max}之间
|
||||
current_user_local_config_not_validate=当前用户本地配置不合法
|
||||
current_user_local_config_not_validate=当前用户本地配置不合法
|
||||
|
||||
# operation_history
|
||||
operation_history.id.not_blank=變更記錄 ID 不能為空
|
||||
operation_history.project_id.not_blank=變更記錄項目 ID 不能為空
|
||||
operation_history.project_id.length_range=變更記錄項目 ID 長度必須在{min}和{max}之間
|
||||
operation_history.type.not_blank=變更記錄操作類型不能為空
|
||||
operation_history.type.length_range=變更記錄操作類型長度必須在{min}和{max}之間
|
||||
operation_history.source_id.not_blank=變更記錄資源 ID 不能為空
|
||||
operation_history.version_id.not_blank=變更記錄版本 ID 不能為空
|
||||
operation_history.version_id.length_range=變更記錄版本 ID 長度必須在{min}和{max}之間
|
||||
|
|
|
@ -9,6 +9,9 @@ import io.metersphere.api.dto.request.ImportRequest;
|
|||
import io.metersphere.api.service.definition.ApiDefinitionLogService;
|
||||
import io.metersphere.api.service.definition.ApiDefinitionService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import io.metersphere.system.dto.request.OperationHistoryVersionRequest;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.security.CheckOwner;
|
||||
|
@ -202,4 +205,31 @@ public class ApiDefinitionController {
|
|||
return apiDefinitionService.apiTestImport(file, request);
|
||||
}
|
||||
|
||||
@PostMapping("/operation-history")
|
||||
@Operation(summary = "接口测试-接口管理-接口变更历史")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ)
|
||||
@CheckOwner(resourceId = "#request.getSourceId()", resourceType = "api_definition")
|
||||
public Pager<List<OperationHistoryDTO>> operationHistoryList(@Validated @RequestBody OperationHistoryRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
|
||||
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc");
|
||||
return PageUtils.setPageInfo(page, apiDefinitionService.list(request));
|
||||
}
|
||||
|
||||
@PostMapping("/operation-history/recover")
|
||||
@Operation(summary = "接口测试-接口管理-接口变更历史恢复")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_UPDATE)
|
||||
@CheckOwner(resourceId = "#request.getId()", resourceType = "operation_history")
|
||||
public void operationHistoryRecover(@Validated @RequestBody OperationHistoryVersionRequest request) {
|
||||
apiDefinitionService.recoverOperationHistory(request);
|
||||
}
|
||||
|
||||
@PostMapping("/operation-history/save")
|
||||
@Operation(summary = "接口测试-接口管理-另存变更历史为指定版本")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_UPDATE)
|
||||
@CheckOwner(resourceId = "#request.getId()", resourceType = "operation_history")
|
||||
public void saveOperationHistory(@Validated @RequestBody OperationHistoryVersionRequest request) {
|
||||
apiDefinitionService.saveOperationHistory(request);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,12 +20,15 @@ public class ApiDefinitionVersionDTO implements Serializable {
|
|||
@Schema(description = "接口ID")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "名称")
|
||||
@Schema(description = "接口名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "版本id")
|
||||
private String versionId;
|
||||
|
||||
@Schema(description = "版本name")
|
||||
private String versionName;
|
||||
|
||||
@Schema(description = "版本引用id")
|
||||
private String refId;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.api.mapper;
|
|||
import io.metersphere.api.domain.ApiDefinition;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.definition.importdto.ApiDefinitionImportDTO;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.system.dto.table.TableBatchProcessDTO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -46,4 +47,8 @@ public interface ExtApiDefinitionMapper {
|
|||
List<String> selectIdsByIdsAndDeleted(@Param("ids") List<String> ids, @Param("deleted") boolean deleted);
|
||||
|
||||
List<String> selectByProjectId(@Param("projectId") String projectId);
|
||||
|
||||
List<OptionDTO> selectVersionOptionByIds(@Param("apiIds") List<String> apiIds);
|
||||
|
||||
ApiDefinition selectApiDefinitionByVersion(@Param("refId") String refId, @Param("versionId") String versionId);
|
||||
}
|
||||
|
|
|
@ -118,13 +118,15 @@
|
|||
</select>
|
||||
|
||||
<select id="getApiDefinitionByRefId" resultType="io.metersphere.api.dto.definition.ApiDefinitionVersionDTO">
|
||||
SELECT id,
|
||||
`name`,
|
||||
version_id,
|
||||
ref_id,
|
||||
project_id
|
||||
FROM api_definition
|
||||
WHERE ref_id = #{refId}
|
||||
SELECT api_definition.id,
|
||||
api_definition.`name`,
|
||||
api_definition.version_id,
|
||||
api_definition.ref_id,
|
||||
api_definition.project_id,
|
||||
project_version.name as version_name
|
||||
from api_definition
|
||||
LEFT JOIN project_version ON project_version.id = api_definition.version_id
|
||||
where api_definition.ref_id = #{refId}
|
||||
</select>
|
||||
|
||||
<select id="getTagsByIds" resultMap="BaseResultMap">
|
||||
|
@ -470,4 +472,26 @@
|
|||
</include>
|
||||
</sql>
|
||||
|
||||
<select id="selectVersionOptionByIds" resultType="io.metersphere.system.dto.sdk.OptionDTO">
|
||||
select
|
||||
api_definition.id, project_version.name as name
|
||||
from api_definition
|
||||
LEFT JOIN project_version ON project_version.id = api_definition.version_id
|
||||
where api_definition.ref_id in
|
||||
<foreach collection="apiIds" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="selectApiDefinitionByVersion" resultType="io.metersphere.api.domain.ApiDefinition">
|
||||
select
|
||||
api_definition.id, api_definition.`name`, api_definition.protocol, api_definition.`method`,
|
||||
api_definition.`path`, api_definition.`status`, api_definition.num, api_definition.tags, api_definition.pos,
|
||||
api_definition.project_id, api_definition.module_id, api_definition.latest, api_definition.version_id,
|
||||
api_definition.ref_id, api_definition.description, api_definition.create_time, api_definition.create_user,
|
||||
api_definition.update_time, api_definition.update_user, api_definition.delete_user, api_definition.delete_time,
|
||||
api_definition.deleted
|
||||
from api_definition
|
||||
where api_definition.ref_id = #{refId} and api_definition.version_id = #{versionId}
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -59,7 +59,7 @@ public class ApiDefinitionLogService {
|
|||
OperationLogType.ADD.name(),
|
||||
OperationLogModule.API_DEFINITION,
|
||||
request.getName());
|
||||
dto.setHistory(true);
|
||||
dto.setHistory(false);
|
||||
dto.setPath("/api/definition/add");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(request));
|
||||
|
@ -74,7 +74,7 @@ public class ApiDefinitionLogService {
|
|||
*/
|
||||
public LogDTO updateLog(ApiDefinitionUpdateRequest request) {
|
||||
ApiDefinitionDTO apiDefinition = getOriginalValue(request.getId());
|
||||
if(apiDefinition.getId() != null){
|
||||
if(apiDefinition.getId() != null) {
|
||||
LogDTO dto = new LogDTO(
|
||||
request.getProjectId(),
|
||||
null,
|
||||
|
@ -100,7 +100,7 @@ public class ApiDefinitionLogService {
|
|||
*/
|
||||
public LogDTO delLog(ApiDefinitionDeleteRequest request) {
|
||||
ApiDefinitionDTO apiDefinition = getOriginalValue(request.getId());
|
||||
if(apiDefinition.getId() != null){
|
||||
if(apiDefinition.getId() != null) {
|
||||
LogDTO dto = new LogDTO(
|
||||
request.getProjectId(),
|
||||
null,
|
||||
|
@ -109,7 +109,7 @@ public class ApiDefinitionLogService {
|
|||
OperationLogType.DELETE.name(),
|
||||
OperationLogModule.API_DEFINITION,
|
||||
apiDefinition.getName());
|
||||
dto.setHistory(true);
|
||||
dto.setHistory(false);
|
||||
dto.setPath("/api/definition/delete");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(apiDefinition));
|
||||
|
@ -125,7 +125,7 @@ public class ApiDefinitionLogService {
|
|||
* @return
|
||||
*/
|
||||
public void batchDelLog(List<String> ids, String userId, String projectId) {
|
||||
saveBatchLog(projectId, ids, "/api/definition/batch-del", userId, OperationLogType.DELETE.name(), true);
|
||||
saveBatchLog(projectId, ids, "/api/definition/batch-del", userId, OperationLogType.DELETE.name(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,7 +139,7 @@ public class ApiDefinitionLogService {
|
|||
|
||||
public LogDTO copyLog(ApiDefinitionCopyRequest request) {
|
||||
ApiDefinitionDTO apiDefinition = getOriginalValue(request.getId());
|
||||
if(apiDefinition.getId() != null){
|
||||
if(apiDefinition.getId() != null) {
|
||||
LogDTO dto = new LogDTO(
|
||||
apiDefinition.getProjectId(),
|
||||
null,
|
||||
|
@ -148,7 +148,7 @@ public class ApiDefinitionLogService {
|
|||
OperationLogType.UPDATE.name(),
|
||||
OperationLogModule.API_DEFINITION,
|
||||
apiDefinition.getName());
|
||||
dto.setHistory(true);
|
||||
dto.setHistory(false);
|
||||
dto.setPath("/api/definition/copy");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(apiDefinition));
|
||||
|
@ -158,12 +158,12 @@ public class ApiDefinitionLogService {
|
|||
}
|
||||
|
||||
public void batchMoveLog(List<String> ids, String userId, String projectId) {
|
||||
saveBatchLog(projectId, ids, "/api/definition/batch-move", userId, OperationLogType.UPDATE.name(), true);
|
||||
saveBatchLog(projectId, ids, "/api/definition/batch-move", userId, OperationLogType.UPDATE.name(), false);
|
||||
}
|
||||
|
||||
public LogDTO followLog(String id) {
|
||||
ApiDefinitionDTO apiDefinition = getOriginalValue(id);
|
||||
if(apiDefinition.getId() != null){
|
||||
if(apiDefinition.getId() != null) {
|
||||
Project project = projectMapper.selectByPrimaryKey(apiDefinition.getProjectId());
|
||||
LogDTO dto = new LogDTO(
|
||||
apiDefinition.getProjectId(),
|
||||
|
@ -190,7 +190,7 @@ public class ApiDefinitionLogService {
|
|||
*/
|
||||
public LogDTO recoverLog(ApiDefinitionDeleteRequest request) {
|
||||
ApiDefinitionDTO apiDefinition = getOriginalValue(request.getId());
|
||||
if(apiDefinition.getId() != null){
|
||||
if(apiDefinition.getId() != null) {
|
||||
LogDTO dto = new LogDTO(
|
||||
request.getProjectId(),
|
||||
null,
|
||||
|
@ -199,7 +199,7 @@ public class ApiDefinitionLogService {
|
|||
OperationLogType.RECOVER.name(),
|
||||
OperationLogModule.API_DEFINITION,
|
||||
apiDefinition.getName());
|
||||
dto.setHistory(true);
|
||||
dto.setHistory(false);
|
||||
dto.setPath("/api/definition/recover");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(apiDefinition));
|
||||
|
@ -216,7 +216,7 @@ public class ApiDefinitionLogService {
|
|||
* @return
|
||||
*/
|
||||
public void batchRecoverLog(List<String> ids, String userId, String projectId) {
|
||||
saveBatchLog(projectId, ids, "/api/definition/batch-recover", userId, OperationLogType.RECOVER.name(), true);
|
||||
saveBatchLog(projectId, ids, "/api/definition/batch-recover", userId, OperationLogType.RECOVER.name(), false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -225,7 +225,7 @@ public class ApiDefinitionLogService {
|
|||
*/
|
||||
public LogDTO trashDelLog(ApiDefinitionDeleteRequest request) {
|
||||
ApiDefinitionDTO apiDefinition = getOriginalValue(request.getId());
|
||||
if(apiDefinition.getId() != null){
|
||||
if(apiDefinition.getId() != null) {
|
||||
LogDTO dto = new LogDTO(
|
||||
request.getProjectId(),
|
||||
null,
|
||||
|
@ -248,13 +248,13 @@ public class ApiDefinitionLogService {
|
|||
* 删除回收站接口定义接口日志
|
||||
*/
|
||||
public void batchTrashDelLog(List<String> ids, String userId, String projectId) {
|
||||
saveBatchLog(projectId, ids, "/api/definition/batch-trash-del", userId, OperationLogType.DELETE.name(), true);
|
||||
saveBatchLog(projectId, ids, "/api/definition/batch-trash-del", userId, OperationLogType.DELETE.name(), false);
|
||||
}
|
||||
|
||||
private ApiDefinitionDTO getOriginalValue(String id){
|
||||
private ApiDefinitionDTO getOriginalValue(String id) {
|
||||
ApiDefinitionDTO apiDefinitionDTO = new ApiDefinitionDTO();
|
||||
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(id);
|
||||
if(null != apiDefinition){
|
||||
if(null != apiDefinition) {
|
||||
// 2. 使用Optional避免空指针异常
|
||||
handleBlob(id, apiDefinitionDTO);
|
||||
BeanUtils.copyBean(apiDefinitionDTO, apiDefinition);
|
||||
|
@ -303,5 +303,41 @@ public class ApiDefinitionLogService {
|
|||
}
|
||||
}
|
||||
|
||||
public Long saveOperationHistoryLog(ApiDefinitionDTO apiDefinitionDTO, String userId, String projectId) {
|
||||
Project project = projectMapper.selectByPrimaryKey(projectId);
|
||||
LogDTO dto = new LogDTO(
|
||||
project.getId(),
|
||||
project.getOrganizationId(),
|
||||
apiDefinitionDTO.getId(),
|
||||
userId,
|
||||
OperationLogType.UPDATE.name(),
|
||||
OperationLogModule.API_DEFINITION,
|
||||
apiDefinitionDTO.getName());
|
||||
dto.setHistory(true);
|
||||
dto.setPath("/api/definition/operation-history/save");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(apiDefinitionDTO));
|
||||
operationLogService.add(dto);
|
||||
return dto.getId();
|
||||
}
|
||||
|
||||
public Long recoverOperationHistoryLog(ApiDefinitionDTO apiDefinitionDTO, String userId, String projectId) {
|
||||
Project project = projectMapper.selectByPrimaryKey(projectId);
|
||||
LogDTO dto = new LogDTO(
|
||||
project.getId(),
|
||||
project.getOrganizationId(),
|
||||
apiDefinitionDTO.getId(),
|
||||
userId,
|
||||
OperationLogType.RECOVER.name(),
|
||||
OperationLogModule.API_DEFINITION,
|
||||
apiDefinitionDTO.getName());
|
||||
dto.setHistory(true);
|
||||
dto.setPath("/api/definition/operation-history/recover");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(apiDefinitionDTO));
|
||||
operationLogService.add(dto);
|
||||
return dto.getId();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,10 +22,17 @@ import io.metersphere.sdk.constants.ApiReportStatus;
|
|||
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.domain.OperationLogBlob;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.mapper.OperationLogBlobMapper;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import io.metersphere.system.dto.request.OperationHistoryVersionRequest;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.system.dto.table.TableBatchProcessDTO;
|
||||
import io.metersphere.system.log.constants.OperationLogModule;
|
||||
import io.metersphere.system.service.OperationHistoryService;
|
||||
import io.metersphere.system.service.UserLoginService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.uid.NumGenerator;
|
||||
|
@ -42,6 +49,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -107,6 +115,12 @@ public class ApiDefinitionService {
|
|||
@Resource
|
||||
private ApiDefinitionMockService apiDefinitionMockService;
|
||||
|
||||
@Resource
|
||||
private OperationHistoryService operationHistoryService;
|
||||
|
||||
@Resource
|
||||
private OperationLogBlobMapper operationLogBlobMapper;
|
||||
|
||||
public List<ApiDefinitionDTO> getApiDefinitionPage(ApiDefinitionPageRequest request, String userId) {
|
||||
CustomFieldUtils.setBaseQueryRequestCustomMultipleFields(request, userId);
|
||||
List<ApiDefinitionDTO> list = extApiDefinitionMapper.list(request);
|
||||
|
@ -910,4 +924,84 @@ public class ApiDefinitionService {
|
|||
}
|
||||
return apiImport;
|
||||
}
|
||||
public List<OperationHistoryDTO> list(OperationHistoryRequest request) {
|
||||
List<OperationHistoryDTO> operationHistoryList = operationHistoryService.list(request);
|
||||
if (CollectionUtils.isNotEmpty(operationHistoryList)) {
|
||||
List<String> apiIds = operationHistoryList.stream()
|
||||
.map(OperationHistoryDTO::getSourceId).toList();
|
||||
|
||||
Map<String, String> apiMap = extApiDefinitionMapper.selectVersionOptionByIds(apiIds).stream()
|
||||
.collect(Collectors.toMap(OptionDTO::getId, OptionDTO::getName));
|
||||
|
||||
operationHistoryList.forEach(item -> item.setVersionName(apiMap.getOrDefault(item.getSourceId(), StringUtils.EMPTY)));
|
||||
}
|
||||
|
||||
return operationHistoryList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在所选版本的接口定义,不存在则创建,同时创建日志记录
|
||||
*/
|
||||
public void saveOperationHistory(OperationHistoryVersionRequest request) {
|
||||
ApiDefinitionExample apiDefinitionExample = new ApiDefinitionExample();
|
||||
apiDefinitionExample.createCriteria().andRefIdEqualTo(request.getSourceId()).andVersionIdEqualTo(request.getVersionId());
|
||||
List<ApiDefinition> matchingApiDefinitions = apiDefinitionMapper.selectByExample(apiDefinitionExample);
|
||||
ApiDefinition apiDefinition = matchingApiDefinitions.stream().findFirst().orElseGet(ApiDefinition::new);
|
||||
ApiDefinitionBlob copyApiDefinitionBlob = getApiDefinitionBlob(request.getSourceId());
|
||||
if (apiDefinition.getId() == null) {
|
||||
ApiDefinition copyApiDefinition = apiDefinitionMapper.selectByPrimaryKey(request.getSourceId());
|
||||
BeanUtils.copyBean(apiDefinition, copyApiDefinition);
|
||||
apiDefinition.setId(IDGenerator.nextStr());
|
||||
apiDefinition.setRefId(request.getSourceId());
|
||||
apiDefinition.setVersionId(request.getVersionId());
|
||||
apiDefinition.setCreateTime(System.currentTimeMillis());
|
||||
apiDefinition.setUpdateTime(System.currentTimeMillis());
|
||||
apiDefinitionMapper.insertSelective(apiDefinition);
|
||||
|
||||
ApiDefinitionBlob apiDefinitionBlob = new ApiDefinitionBlob();
|
||||
if(copyApiDefinitionBlob != null) {
|
||||
apiDefinitionBlob.setId(apiDefinition.getId());
|
||||
apiDefinitionBlob.setRequest(copyApiDefinitionBlob.getRequest());
|
||||
apiDefinitionBlob.setResponse(copyApiDefinitionBlob.getResponse());
|
||||
apiDefinitionBlobMapper.insertSelective(apiDefinitionBlob);
|
||||
}
|
||||
}
|
||||
ApiDefinitionDTO apiDefinitionDTO = new ApiDefinitionDTO();
|
||||
BeanUtils.copyBean(apiDefinitionDTO, apiDefinition);
|
||||
Optional.ofNullable(copyApiDefinitionBlob)
|
||||
.map(blob -> new String(blob.getRequest()))
|
||||
.ifPresent(requestBlob -> apiDefinitionDTO.setRequest(ApiDataUtils.parseObject(requestBlob, AbstractMsTestElement.class)));
|
||||
|
||||
Optional.ofNullable(copyApiDefinitionBlob)
|
||||
.map(blob -> new String(blob.getResponse()))
|
||||
.ifPresent(responseBlob -> apiDefinitionDTO.setResponse(ApiDataUtils.parseArray(responseBlob, HttpResponse.class)));
|
||||
|
||||
Long logId = apiDefinitionLogService.saveOperationHistoryLog(apiDefinitionDTO, apiDefinition.getCreateUser(), apiDefinition.getProjectId());
|
||||
operationHistoryService.associationRefId(request.getId(), logId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void recoverOperationHistory(OperationHistoryVersionRequest request) {
|
||||
OperationLogBlob operationLogBlob = operationLogBlobMapper.selectByPrimaryKey(request.getId());
|
||||
ApiDefinitionDTO apiDefinitionDTO = ApiDataUtils.parseObject(new String(operationLogBlob.getOriginalValue()), ApiDefinitionDTO.class);
|
||||
Long logId = recoverApiDefinition(apiDefinitionDTO);
|
||||
operationHistoryService.associationRefId(operationLogBlob.getId(), logId);
|
||||
}
|
||||
|
||||
public Long recoverApiDefinition(ApiDefinitionDTO apiDefinitionDTO) {
|
||||
ApiDefinition apiDefinition = new ApiDefinition();
|
||||
BeanUtils.copyBean(apiDefinition, apiDefinitionDTO);
|
||||
apiDefinition.setUpdateTime(System.currentTimeMillis());
|
||||
apiDefinitionMapper.updateByPrimaryKeySelective(apiDefinition);
|
||||
|
||||
ApiDefinitionBlob apiDefinitionBlob = new ApiDefinitionBlob();
|
||||
apiDefinitionBlob.setId(apiDefinition.getId());
|
||||
apiDefinitionBlob.setRequest(ApiDataUtils.toJSONString(apiDefinitionDTO.getRequest()).getBytes(StandardCharsets.UTF_8));
|
||||
apiDefinitionBlob.setResponse(ApiDataUtils.toJSONString(apiDefinitionDTO.getResponse()).getBytes(StandardCharsets.UTF_8));
|
||||
apiDefinitionBlobMapper.updateByPrimaryKeySelective(apiDefinitionBlob);
|
||||
|
||||
// 记录操作日志
|
||||
return apiDefinitionLogService.recoverOperationHistoryLog(apiDefinitionDTO, apiDefinition.getCreateUser(), apiDefinition.getProjectId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,19 @@ import io.metersphere.sdk.constants.SessionConstants;
|
|||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.file.FileCenter;
|
||||
import io.metersphere.sdk.file.FileRequest;
|
||||
import io.metersphere.sdk.mapper.OperationLogBlobMapper;
|
||||
import io.metersphere.sdk.mapper.OperationLogMapper;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
import io.metersphere.system.controller.handler.result.MsHttpResultCode;
|
||||
import io.metersphere.system.domain.OperationHistory;
|
||||
import io.metersphere.system.domain.OperationHistoryExample;
|
||||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import io.metersphere.system.dto.request.OperationHistoryVersionRequest;
|
||||
import io.metersphere.system.dto.sdk.BaseCondition;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.mapper.OperationHistoryMapper;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -85,6 +92,9 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
private static final String GET = BASE_PATH + "get-detail/";
|
||||
private static final String FOLLOW = BASE_PATH + "follow/";
|
||||
private static final String VERSION = BASE_PATH + "version/";
|
||||
private static final String OPERATION_HISTORY = BASE_PATH + "operation-history";
|
||||
private static final String OPERATION_HISTORY_RECOVER = BASE_PATH + "operation-history/recover";
|
||||
private static final String OPERATION_HISTORY_SAVE = BASE_PATH + "operation-history/save";
|
||||
private static final String UPLOAD_TEMP_FILE = BASE_PATH + "/upload/temp/file";
|
||||
|
||||
private static final String DEFAULT_MODULE_ID = "10001";
|
||||
|
@ -119,6 +129,15 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
@Resource
|
||||
private ExtApiDefinitionCustomFieldMapper extApiDefinitionCustomFieldMapper;
|
||||
|
||||
@Resource
|
||||
private OperationHistoryMapper operationHistoryMapper;
|
||||
|
||||
@Resource
|
||||
private OperationLogMapper operationLogMapper;
|
||||
|
||||
@Resource
|
||||
private OperationLogBlobMapper operationLogBlobMapper;
|
||||
|
||||
@Resource
|
||||
private FileMetadataService fileMetadataService;
|
||||
private static String fileMetadataId;
|
||||
|
@ -895,6 +914,88 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
|
||||
@Test
|
||||
@Order(12)
|
||||
public void testOperationHistoryList() throws Exception {
|
||||
OperationHistoryRequest request = new OperationHistoryRequest();
|
||||
apiDefinition = apiDefinitionMapper.selectByPrimaryKey("1001");
|
||||
request.setSourceId(apiDefinition.getId());
|
||||
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||
request.setCurrent(1);
|
||||
request.setPageSize(10);
|
||||
request.setSort(Map.of("createTime", "asc"));
|
||||
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(OPERATION_HISTORY, request);
|
||||
// 获取返回值
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
// 返回请求正常
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
Pager<?> pageData = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class);
|
||||
// 返回值不为空
|
||||
Assertions.assertNotNull(pageData);
|
||||
// 返回值的页码和当前页码相同
|
||||
Assertions.assertEquals(pageData.getCurrent(), request.getCurrent());
|
||||
// 返回的数据量不超过规定要返回的数据量相同
|
||||
Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(pageData.getList())).size() <= request.getPageSize());
|
||||
request.setSort(Map.of());
|
||||
this.requestPost(OPERATION_HISTORY, request);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(12)
|
||||
public void testOperationHistorySave() throws Exception {
|
||||
OperationHistoryVersionRequest operationHistoryVersionRequest = new OperationHistoryVersionRequest();
|
||||
apiDefinition = apiDefinitionMapper.selectByPrimaryKey("1002");
|
||||
OperationHistoryExample operationHistoryExample = new OperationHistoryExample();
|
||||
operationHistoryExample.createCriteria().andSourceIdEqualTo(apiDefinition.getId());
|
||||
operationHistoryExample.setOrderByClause("id DESC");
|
||||
OperationHistory operationHistory = operationHistoryMapper.selectByExample(operationHistoryExample).getFirst();
|
||||
operationHistoryVersionRequest.setId(operationHistory.getId());
|
||||
operationHistoryVersionRequest.setSourceId(apiDefinition.getId());
|
||||
operationHistoryVersionRequest.setVersionId(apiDefinition.getVersionId());
|
||||
this.requestPostWithOkAndReturn(OPERATION_HISTORY_SAVE, operationHistoryVersionRequest);
|
||||
checkLogModelList.add(new CheckLogModel(apiDefinition.getId(), OperationLogType.UPDATE, OPERATION_HISTORY_SAVE));
|
||||
OperationHistoryExample comparisonExample = new OperationHistoryExample();
|
||||
comparisonExample.createCriteria().andSourceIdEqualTo(apiDefinition.getId()).andRefIdEqualTo(operationHistory.getId()).andTypeEqualTo(OperationLogType.UPDATE.name());
|
||||
comparisonExample.setOrderByClause("id DESC");
|
||||
OperationHistory comparison = operationHistoryMapper.selectByExample(operationHistoryExample).getFirst();
|
||||
Assertions.assertNotNull(comparison);
|
||||
|
||||
operationHistoryVersionRequest.setId(operationHistory.getId());
|
||||
operationHistoryVersionRequest.setSourceId("1002");
|
||||
operationHistoryVersionRequest.setVersionId("1002002002");
|
||||
this.requestPostWithOkAndReturn(OPERATION_HISTORY_SAVE, operationHistoryVersionRequest);
|
||||
checkLogModelList.add(new CheckLogModel(apiDefinition.getId(), OperationLogType.UPDATE, OPERATION_HISTORY_SAVE));
|
||||
OperationHistoryExample comparisonExampleNewVersion = new OperationHistoryExample();
|
||||
comparisonExampleNewVersion.createCriteria().andSourceIdEqualTo(apiDefinition.getId()).andRefIdEqualTo(operationHistory.getId()).andTypeEqualTo(OperationLogType.UPDATE.name());
|
||||
comparisonExampleNewVersion.setOrderByClause("id DESC");
|
||||
OperationHistory comparisonNewVersion = operationHistoryMapper.selectByExample(operationHistoryExample).getFirst();
|
||||
Assertions.assertNotNull(comparisonNewVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(13)
|
||||
public void testOperationHistoryRecover() throws Exception {
|
||||
OperationHistoryVersionRequest operationHistoryVersionRequest = new OperationHistoryVersionRequest();
|
||||
apiDefinition = apiDefinitionMapper.selectByPrimaryKey("1002");
|
||||
OperationHistoryExample operationHistoryExample = new OperationHistoryExample();
|
||||
operationHistoryExample.createCriteria().andSourceIdEqualTo(apiDefinition.getId());
|
||||
operationHistoryExample.setOrderByClause("id DESC");
|
||||
OperationHistory operationHistory = operationHistoryMapper.selectByExample(operationHistoryExample).getFirst();
|
||||
operationHistoryVersionRequest.setId(operationHistory.getId());
|
||||
operationHistoryVersionRequest.setSourceId(apiDefinition.getId());
|
||||
operationHistoryVersionRequest.setVersionId(apiDefinition.getVersionId());
|
||||
this.requestPostWithOkAndReturn(OPERATION_HISTORY_RECOVER, operationHistoryVersionRequest);
|
||||
checkLogModelList.add(new CheckLogModel(apiDefinition.getId(), OperationLogType.RECOVER, OPERATION_HISTORY_RECOVER));
|
||||
OperationHistoryExample comparisonExample = new OperationHistoryExample();
|
||||
comparisonExample.createCriteria().andSourceIdEqualTo(apiDefinition.getId()).andRefIdEqualTo(operationHistory.getId()).andTypeEqualTo(OperationLogType.RECOVER.name());
|
||||
comparisonExample.setOrderByClause("id DESC");
|
||||
OperationHistory comparison = operationHistoryMapper.selectByExample(operationHistoryExample).getFirst();
|
||||
Assertions.assertNotNull(comparison);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(14)
|
||||
public void testDel() throws Exception {
|
||||
LogUtils.info("delete api test");
|
||||
apiDefinition = apiDefinitionMapper.selectByPrimaryKey("1001");
|
||||
|
@ -968,7 +1069,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Order(13)
|
||||
@Order(15)
|
||||
public void testBatchDel() throws Exception {
|
||||
LogUtils.info("batch delete api test");
|
||||
ApiDefinitionBatchRequest request = new ApiDefinitionBatchRequest();
|
||||
|
@ -1002,7 +1103,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
|
||||
|
||||
@Test
|
||||
@Order(14)
|
||||
@Order(16)
|
||||
public void testRecover() throws Exception {
|
||||
LogUtils.info("recover api test");
|
||||
apiDefinition = apiDefinitionMapper.selectByPrimaryKey("1001");
|
||||
|
@ -1047,7 +1148,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Order(15)
|
||||
@Order(20)
|
||||
public void testBatchRecover() throws Exception {
|
||||
LogUtils.info("batch recover api test");
|
||||
ApiDefinitionBatchRequest request = new ApiDefinitionBatchRequest();
|
||||
|
@ -1095,7 +1196,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Order(16)
|
||||
@Order(21)
|
||||
public void testTrashDel() throws Exception {
|
||||
LogUtils.info("trashDel api test");
|
||||
apiDefinition = apiDefinitionMapper.selectByPrimaryKey("1001");
|
||||
|
@ -1137,7 +1238,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Order(17)
|
||||
@Order(25)
|
||||
public void testBatchTrashDel() throws Exception {
|
||||
LogUtils.info("batch trash delete api test");
|
||||
ApiDefinitionBatchRequest request = new ApiDefinitionBatchRequest();
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package io.metersphere.system.dto;
|
||||
|
||||
import io.metersphere.system.domain.OperationHistory;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author: LAN
|
||||
* @date: 2024/1/2 19:03
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Data
|
||||
public class OperationHistoryDTO extends OperationHistory implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// 操作人
|
||||
private String createUserName;
|
||||
|
||||
// 版本
|
||||
private String versionName;
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.metersphere.system.dto.request;
|
||||
|
||||
import io.metersphere.system.dto.sdk.BasePageRequest;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class OperationHistoryRequest extends BasePageRequest {
|
||||
|
||||
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{operation_history.project_id.not_blank}")
|
||||
@Size(min = 1, max = 50, message = "{operation_history.project_id.length_range}")
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "资源id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{operation_history.source_id.not_blank}")
|
||||
private String sourceId;
|
||||
|
||||
@Schema(description = "操作人")
|
||||
private String createUser;
|
||||
|
||||
@Schema(description = "操作类型")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "操作模块")
|
||||
private String module;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package io.metersphere.system.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author: LAN
|
||||
* @date: 2024/1/3 16:40
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class OperationHistoryVersionRequest implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "变更记录id")
|
||||
@NotNull(message = "{operation_history.id.not_blank}")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "资源id(当前变更记录的资源id)")
|
||||
@NotBlank(message = "{operation_history.source_id.not_blank}")
|
||||
private String sourceId;
|
||||
|
||||
@Schema(description = "版本id")
|
||||
@NotBlank(message = "{operation_history.version_id.not_blank}")
|
||||
@Size(min = 1, max = 50, message = "{operation_history.version_id.length_range}")
|
||||
private String versionId;
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package io.metersphere.system.mapper;
|
||||
|
||||
|
||||
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -12,4 +14,6 @@ public interface BaseOperationHistoryMapper {
|
|||
List<Long> selectIdsBySourceId(@Param("sourceId") String sourceId, @Param("limit") int limit);
|
||||
|
||||
void deleteByIds(@Param("sourceId") String sourceId, @Param("ids") List<Long> ids);
|
||||
|
||||
List<OperationHistoryDTO> list(@Param("request") OperationHistoryRequest request);
|
||||
}
|
|
@ -18,4 +18,26 @@
|
|||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="list" resultType="io.metersphere.system.dto.OperationHistoryDTO">
|
||||
select id, project_id, create_time, create_user, source_id, `type`, `module`, ref_id
|
||||
from operation_history
|
||||
<where>
|
||||
<if test="request.projectId != null and request.projectId != ''">
|
||||
AND project_id = #{request.projectId,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="request.sourceId != null and request.sourceId != ''">
|
||||
AND source_id = #{request.sourceId,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="request.createUser != null and request.createUser != ''">
|
||||
AND create_user = #{request.createUser,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="request.type != null and request.type != ''">
|
||||
AND `type` = #{request.type,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="request.module != null and request.module != ''">
|
||||
AND `module` = #{request.module,jdbcType=VARCHAR}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package io.metersphere.system.service;
|
||||
|
||||
import io.metersphere.system.domain.OperationHistory;
|
||||
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.system.mapper.BaseOperationHistoryMapper;
|
||||
import io.metersphere.system.mapper.BaseUserMapper;
|
||||
import io.metersphere.system.mapper.OperationHistoryMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class OperationHistoryService {
|
||||
@Resource
|
||||
private BaseOperationHistoryMapper baseOperationHistoryMapper;
|
||||
|
||||
@Resource
|
||||
private BaseUserMapper baseUserMapper;
|
||||
|
||||
@Resource
|
||||
private OperationHistoryMapper operationHistoryMapper;
|
||||
|
||||
|
||||
public List<OperationHistoryDTO> list(OperationHistoryRequest request) {
|
||||
List<OperationHistoryDTO> list = baseOperationHistoryMapper.list(request);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
List<String> userIds = list.stream().distinct()
|
||||
.map(OperationHistoryDTO::getCreateUser).toList();
|
||||
|
||||
Map<String, String> userMap = baseUserMapper.selectUserOptionByIds(userIds).stream()
|
||||
.collect(Collectors.toMap(OptionDTO::getId, OptionDTO::getName));
|
||||
|
||||
list.forEach(item -> item.setCreateUserName(userMap.getOrDefault(item.getCreateUser(), StringUtils.EMPTY)));
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void associationRefId(Long refLogId, Long logId) {
|
||||
OperationHistory operationHistory = operationHistoryMapper.selectByPrimaryKey(logId);
|
||||
operationHistory.setRefId(refLogId);
|
||||
operationHistoryMapper.updateByPrimaryKeySelective(operationHistory);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue