- 完成REQ-010-17(性能优化和限流处理)的所有6个阶段 - 创建ADR文档:0026-performance-optimization.md - 创建Prompt文档:027-performance-optimization.md - 创建会话记录:20260119-performance-optimization.md - 创建变更记录:20260119-performance-optimization.md - 创建复盘报告:20260119-performance-optimization-retro.md - 更新index.md和CHANGELOG.md - 完成REQ-010-2(基础实体类和Mapper创建)的前3个阶段 - 更新ADR文档:0011-entity-mapper-create.md - 创建Prompt文档:002-entity-mapper-create.md - 更新index.md 所有文档均按照SSOT方法论创建,包括需求定义、架构决策、提示词资产化、执行会话、变更记录和闭环复盘。
35 KiB
35 KiB
Prompt First - 版本回溯功能
输入引用
引用相关的 docs 文档链接:
- REQ-010-13.md - 版本回溯功能需求文档
- 0022-version-rollback.md - 版本回溯功能架构决策
- REQ-010-7.md - 文件存储和解压处理需求文档
- REQ-010-12.md - 文件哈希对比和增量检测需求文档
- file/index.md - 文件模块 API 文档索引(唯一真源)
Context Maps
强制列出本次 Prompt 依赖的 Canvas 文件:
- Authentication.canvas - 项目架构视觉化展示
- 相关节点: 集成核心 - 提供与Salesforce的各种连接方式
目标
实现版本回溯功能,支持查看和恢复历史版本的元数据文件。包括版本历史记录、版本对比、版本恢复、版本回滚等功能。
输出格式
代码示例(语言:Java)
约束
- 技术栈限制: 必须基于现有的 Spring Boot 3 + MyBatis Plus 技术栈
- 架构约束: 必须遵循 Authentication.canvas 中定义的架构和调用关系
- 模块约束: 必须在 datai-salesforce-metadata 模块下实现
- 数据库约束: 必须使用 MyBatis Plus 作为持久层框架
- 性能约束: 版本对比和恢复性能必须满足要求
- 依赖约束: 必须复用现有的 IFileStorageService、IMetadataRetrieveService、IMetadataDeployService 服务接口
Rule Set
"请严格参考 @Authentication.canvas 中的状态机转移逻辑,不要自行发挥。"
具体规则:
- 必须使用 Canvas 中定义的类名和方法名
- 必须遵循 Canvas 中定义的调用关系
- 必须参考 Canvas 中的流程图逻辑
验收标准
- 功能完整性: 所有版本回溯功能能够正常工作
- 性能指标: 版本对比和恢复性能满足要求
- 安全性: 恢复和回滚操作安全可靠,有完整的日志记录
- 代码规范性: 代码符合项目编码规范,有清晰的注释
- 可维护性: 代码结构清晰,易于扩展和维护
- 可测试性: 代码易于单元测试和集成测试
风险
- 版本记录风险: 版本记录不完整可能导致无法恢复
- 对比风险: 版本对比不准确可能导致误判
- 恢复风险: 恢复操作失败可能导致数据不一致
- 回滚风险: 回滚操作失败可能导致无法恢复
- 存储空间风险: 版本历史记录过多可能占用大量存储空间
使用记录
| 日期 | 使用场景 | 输入参数 | 输出结果 | 反馈 | 改进措施 |
|---|---|---|---|---|---|
| 2026-01-19 | 实现版本回溯功能 | REQ-010-13.md, 0022-version-rollback.md | 完整的代码实现 | 无 | 无 |
核心代码实现
1. MetadataVersion 实体类
package com.datai.salesforce.metadata.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 元数据版本实体类
*/
@Data
@TableName("datai_metadata_version")
public class MetadataVersion {
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 版本号
*/
private String versionNumber;
/**
* 文件路径
*/
private String filePath;
/**
* 文件哈希值
*/
private String fileHash;
/**
* 文件内容
*/
private String fileContent;
/**
* 版本类型
*/
private String versionType;
/**
* 任务ID
*/
private Long taskId;
/**
* 组织配置ID
*/
private Long orgConfigId;
/**
* 版本时间
*/
private LocalDateTime versionTime;
/**
* 部门ID
*/
private Long deptId;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 备注
*/
private String remark;
}
2. MetadataVersionMapper 接口
package com.datai.salesforce.metadata.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
/**
* 元数据版本 Mapper 接口
*/
@Mapper
public interface MetadataVersionMapper extends BaseMapper<MetadataVersion> {
/**
* 按时间查询版本
* @param startTime 开始时间
* @param endTime 结束时间
* @return 版本列表
*/
List<MetadataVersion> selectByTimeRange(@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
/**
* 按任务查询版本
* @param taskId 任务ID
* @return 版本列表
*/
List<MetadataVersion> selectByTaskId(@Param("taskId") Long taskId);
/**
* 按文件路径查询版本
* @param filePath 文件路径
* @return 版本列表
*/
List<MetadataVersion> selectByFilePath(@Param("filePath") String filePath);
/**
* 查询最新版本
* @param filePath 文件路径
* @return 最新版本
*/
MetadataVersion selectLatestVersion(@Param("filePath") String filePath);
/**
* 按时间查询版本(分页)
* @param page 分页参数
* @param startTime 开始时间
* @param endTime 结束时间
* @return 版本列表
*/
IPage<MetadataVersion> selectByTimeRangePage(Page<MetadataVersion> page,
@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
}
3. IMetadataVersionService 服务接口
package com.datai.salesforce.metadata.service.version;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import java.time.LocalDateTime;
import java.util.List;
/**
* 元数据版本服务接口
*/
public interface IMetadataVersionService {
/**
* 创建版本
* @param version 版本信息
* @return 版本ID
*/
Long createVersion(MetadataVersion version);
/**
* 查询版本
* @param id 版本ID
* @return 版本信息
*/
MetadataVersion getVersion(Long id);
/**
* 按时间查询版本
* @param startTime 开始时间
* @param endTime 结束时间
* @return 版本列表
*/
List<MetadataVersion> getVersionsByTimeRange(LocalDateTime startTime, LocalDateTime endTime);
/**
* 按任务查询版本
* @param taskId 任务ID
* @return 版本列表
*/
List<MetadataVersion> getVersionsByTaskId(Long taskId);
/**
* 按文件路径查询版本
* @param filePath 文件路径
* @return 版本列表
*/
List<MetadataVersion> getVersionsByFilePath(String filePath);
/**
* 查询最新版本
* @param filePath 文件路径
* @return 最新版本
*/
MetadataVersion getLatestVersion(String filePath);
/**
* 按时间查询版本(分页)
* @param pageNum 页码
* @param pageSize 每页大小
* @param startTime 开始时间
* @param endTime 结束时间
* @return 版本列表
*/
IPage<MetadataVersion> getVersionsByTimeRangePage(int pageNum, int pageSize,
LocalDateTime startTime, LocalDateTime endTime);
/**
* 删除版本
* @param id 版本ID
* @return 删除结果
*/
boolean deleteVersion(Long id);
/**
* 批量删除版本
* @param ids 版本ID列表
* @return 删除结果
*/
boolean batchDeleteVersions(List<Long> ids);
}
4. MetadataVersionServiceImpl 服务实现
package com.datai.salesforce.metadata.service.version.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import com.datai.salesforce.metadata.mapper.MetadataVersionMapper;
import com.datai.salesforce.metadata.service.version.IMetadataVersionService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
/**
* 元数据版本服务实现类
*/
@Service
public class MetadataVersionServiceImpl extends ServiceImpl<MetadataVersionMapper, MetadataVersion>
implements IMetadataVersionService {
@Override
public Long createVersion(MetadataVersion version) {
version.setCreateTime(LocalDateTime.now());
version.setUpdateTime(LocalDateTime.now());
save(version);
return version.getId();
}
@Override
public MetadataVersion getVersion(Long id) {
return getById(id);
}
@Override
public List<MetadataVersion> getVersionsByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
return baseMapper.selectByTimeRange(startTime, endTime);
}
@Override
public List<MetadataVersion> getVersionsByTaskId(Long taskId) {
return baseMapper.selectByTaskId(taskId);
}
@Override
public List<MetadataVersion> getVersionsByFilePath(String filePath) {
return baseMapper.selectByFilePath(filePath);
}
@Override
public MetadataVersion getLatestVersion(String filePath) {
return baseMapper.selectLatestVersion(filePath);
}
@Override
public IPage<MetadataVersion> getVersionsByTimeRangePage(int pageNum, int pageSize,
LocalDateTime startTime, LocalDateTime endTime) {
Page<MetadataVersion> page = new Page<>(pageNum, pageSize);
return baseMapper.selectByTimeRangePage(page, startTime, endTime);
}
@Override
public boolean deleteVersion(Long id) {
return removeById(id);
}
@Override
public boolean batchDeleteVersions(List<Long> ids) {
return removeByIds(ids);
}
}
5. IVersionComparisonService 服务接口
package com.datai.salesforce.metadata.service.version;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import java.util.Map;
/**
* 版本对比服务接口
*/
public interface IVersionComparisonService {
/**
* 对比版本
* @param versionId1 版本ID1
* @param versionId2 版本ID2
* @return 对比结果
*/
Map<String, Object> compareVersions(Long versionId1, Long versionId2);
/**
* 对比文件内容
* @param content1 文件内容1
* @param content2 文件内容2
* @return 对比结果
*/
Map<String, Object> compareFileContent(String content1, String content2);
/**
* 对比文件哈希
* @param hash1 文件哈希1
* @param hash2 文件哈希2
* @return 对比结果
*/
Map<String, Object> compareFileHash(String hash1, String hash2);
}
6. VersionComparisonServiceImpl 服务实现
package com.datai.salesforce.metadata.service.version.impl;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import com.datai.salesforce.metadata.service.version.IVersionComparisonService;
import com.datai.salesforce.metadata.service.version.IMetadataVersionService;
import com.google.diffmatchpatch.DiffMatchPatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 版本对比服务实现类
*/
@Service
public class VersionComparisonServiceImpl implements IVersionComparisonService {
@Autowired
private IMetadataVersionService metadataVersionService;
private final DiffMatchPatch diffMatchPatch = new DiffMatchPatch();
@Override
public Map<String, Object> compareVersions(Long versionId1, Long versionId2) {
MetadataVersion version1 = metadataVersionService.getVersion(versionId1);
MetadataVersion version2 = metadataVersionService.getVersion(versionId2);
Map<String, Object> result = new HashMap<>();
result.put("version1", version1);
result.put("version2", version2);
result.put("contentDiff", compareFileContent(version1.getFileContent(), version2.getFileContent()));
result.put("hashDiff", compareFileHash(version1.getFileHash(), version2.getFileHash()));
return result;
}
@Override
public Map<String, Object> compareFileContent(String content1, String content2) {
LinkedList<DiffMatchPatch.Diff> diffs = diffMatchPatch.diffMain(content1, content2, false);
diffMatchPatch.diffCleanupSemantic(diffs);
Map<String, Object> result = new HashMap<>();
result.put("diffs", diffs);
result.put("hasChanges", diffs.size() > 1);
return result;
}
@Override
public Map<String, Object> compareFileHash(String hash1, String hash2) {
Map<String, Object> result = new HashMap<>();
result.put("hash1", hash1);
result.put("hash2", hash2);
result.put("isEqual", hash1.equals(hash2));
return result;
}
}
7. IVersionRecoveryService 服务接口
package com.datai.salesforce.metadata.service.version;
import com.datai.salesforce.metadata.entity.MetadataVersion;
/**
* 版本恢复服务接口
*/
public interface IVersionRecoveryService {
/**
* 恢复版本
* @param versionId 版本ID
* @return 恢复结果
*/
String recoverVersion(Long versionId);
/**
* 恢复版本(异步)
* @param versionId 版本ID
* @return 恢复结果
*/
java.util.concurrent.Future<String> recoverVersionAsync(Long versionId);
}
8. VersionRecoveryServiceImpl 服务实现
package com.datai.salesforce.metadata.service.version.impl;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import com.datai.salesforce.metadata.service.deploy.IMetadataDeployService;
import com.datai.salesforce.metadata.service.version.IVersionRecoveryService;
import com.datai.salesforce.metadata.service.version.IMetadataVersionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
/**
* 版本恢复服务实现类
*/
@Service
public class VersionRecoveryServiceImpl implements IVersionRecoveryService {
@Autowired
private IMetadataVersionService metadataVersionService;
@Autowired
private IMetadataDeployService metadataDeployService;
@Override
@Transactional
public String recoverVersion(Long versionId) {
MetadataVersion version = metadataVersionService.getVersion(versionId);
if (version == null) {
throw new RuntimeException("Version not found");
}
String result = metadataDeployService.deploy(version.getTaskId(),
version.getOrgConfigId(),
version.getFileContent());
return result;
}
@Override
@Async("deployExecutor")
public Future<String> recoverVersionAsync(Long versionId) {
return CompletableFuture.completedFuture(recoverVersion(versionId));
}
}
9. IVersionRollbackService 服务接口
package com.datai.salesforce.metadata.service.version;
/**
* 版本回滚服务接口
*/
public interface IVersionRollbackService {
/**
* 回滚到上一个版本
* @param filePath 文件路径
* @return 回滚结果
*/
String rollbackToPreviousVersion(String filePath);
/**
* 回滚到上一个版本(异步)
* @param filePath 文件路径
* @return 回滚结果
*/
java.util.concurrent.Future<String> rollbackToPreviousVersionAsync(String filePath);
}
10. VersionRollbackServiceImpl 服务实现
package com.datai.salesforce.metadata.service.version.impl;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import com.datai.salesforce.metadata.service.deploy.IMetadataDeployService;
import com.datai.salesforce.metadata.service.version.IVersionRollbackService;
import com.datai.salesforce.metadata.service.version.IMetadataVersionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
/**
* 版本回滚服务实现类
*/
@Service
public class VersionRollbackServiceImpl implements IVersionRollbackService {
@Autowired
private IMetadataVersionService metadataVersionService;
@Autowired
private IMetadataDeployService metadataDeployService;
@Override
@Transactional
public String rollbackToPreviousVersion(String filePath) {
List<MetadataVersion> versions = metadataVersionService.getVersionsByFilePath(filePath);
if (versions == null || versions.size() < 2) {
throw new RuntimeException("No previous version found");
}
MetadataVersion previousVersion = versions.get(1);
String result = metadataDeployService.deploy(previousVersion.getTaskId(),
previousVersion.getOrgConfigId(),
previousVersion.getFileContent());
return result;
}
@Override
@Async("deployExecutor")
public Future<String> rollbackToPreviousVersionAsync(String filePath) {
return CompletableFuture.completedFuture(rollbackToPreviousVersion(filePath));
}
}
11. VersionHistoryController 控制器
package com.datai.salesforce.metadata.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import com.datai.salesforce.metadata.service.version.IMetadataVersionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
* 版本历史控制器
*/
@RestController
@RequestMapping("/api/metadata/version-history")
public class VersionHistoryController {
@Autowired
private IMetadataVersionService metadataVersionService;
@PostMapping("/create")
public Map<String, Object> createVersion(@RequestBody MetadataVersion version) {
Long versionId = metadataVersionService.createVersion(version);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("versionId", versionId);
return response;
}
@GetMapping("/get/{id}")
public Map<String, Object> getVersion(@PathVariable Long id) {
MetadataVersion version = metadataVersionService.getVersion(id);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("version", version);
return response;
}
@GetMapping("/by-time-range")
public Map<String, Object> getVersionsByTimeRange(@RequestParam String startTime,
@RequestParam String endTime) {
LocalDateTime start = LocalDateTime.parse(startTime);
LocalDateTime end = LocalDateTime.parse(endTime);
List<MetadataVersion> versions = metadataVersionService.getVersionsByTimeRange(start, end);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("versions", versions);
return response;
}
@GetMapping("/by-task/{taskId}")
public Map<String, Object> getVersionsByTaskId(@PathVariable Long taskId) {
List<MetadataVersion> versions = metadataVersionService.getVersionsByTaskId(taskId);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("versions", versions);
return response;
}
@GetMapping("/by-file-path")
public Map<String, Object> getVersionsByFilePath(@RequestParam String filePath) {
List<MetadataVersion> versions = metadataVersionService.getVersionsByFilePath(filePath);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("versions", versions);
return response;
}
@GetMapping("/latest")
public Map<String, Object> getLatestVersion(@RequestParam String filePath) {
MetadataVersion version = metadataVersionService.getLatestVersion(filePath);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("version", version);
return response;
}
@GetMapping("/by-time-range-page")
public Map<String, Object> getVersionsByTimeRangePage(@RequestParam int pageNum,
@RequestParam int pageSize,
@RequestParam String startTime,
@RequestParam String endTime) {
LocalDateTime start = LocalDateTime.parse(startTime);
LocalDateTime end = LocalDateTime.parse(endTime);
IPage<MetadataVersion> versions = metadataVersionService.getVersionsByTimeRangePage(pageNum, pageSize, start, end);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("versions", versions);
return response;
}
@DeleteMapping("/delete/{id}")
public Map<String, Object> deleteVersion(@PathVariable Long id) {
boolean result = metadataVersionService.deleteVersion(id);
Map<String, Object> response = new HashMap<>();
response.put("success", result);
return response;
}
@DeleteMapping("/batch-delete")
public Map<String, Object> batchDeleteVersions(@RequestBody List<Long> ids) {
boolean result = metadataVersionService.batchDeleteVersions(ids);
Map<String, Object> response = new HashMap<>();
response.put("success", result);
return response;
}
}
12. VersionComparisonController 控制器
package com.datai.salesforce.metadata.controller;
import com.datai.salesforce.metadata.service.version.IVersionComparisonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* 版本对比控制器
*/
@RestController
@RequestMapping("/api/metadata/version-comparison")
public class VersionComparisonController {
@Autowired
private IVersionComparisonService versionComparisonService;
@PostMapping("/compare-versions")
public Map<String, Object> compareVersions(@RequestBody Map<String, Long> request) {
Long versionId1 = request.get("versionId1");
Long versionId2 = request.get("versionId2");
Map<String, Object> result = versionComparisonService.compareVersions(versionId1, versionId2);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("result", result);
return response;
}
@PostMapping("/compare-content")
public Map<String, Object> compareFileContent(@RequestBody Map<String, String> request) {
String content1 = request.get("content1");
String content2 = request.get("content2");
Map<String, Object> result = versionComparisonService.compareFileContent(content1, content2);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("result", result);
return response;
}
@PostMapping("/compare-hash")
public Map<String, Object> compareFileHash(@RequestBody Map<String, String> request) {
String hash1 = request.get("hash1");
String hash2 = request.get("hash2");
Map<String, Object> result = versionComparisonService.compareFileHash(hash1, hash2);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("result", result);
return response;
}
}
13. VersionRecoveryController 控制器
package com.datai.salesforce.metadata.controller;
import com.datai.salesforce.metadata.service.version.IVersionRecoveryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* 版本恢复控制器
*/
@RestController
@RequestMapping("/api/metadata/version-recovery")
public class VersionRecoveryController {
@Autowired
private IVersionRecoveryService versionRecoveryService;
@PostMapping("/recover")
public Map<String, Object> recoverVersion(@RequestBody Map<String, Long> request) {
Long versionId = request.get("versionId");
String result = versionRecoveryService.recoverVersion(versionId);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("result", result);
return response;
}
}
14. VersionRollbackController 控制器
package com.datai.salesforce.metadata.controller;
import com.datai.salesforce.metadata.service.version.IVersionRollbackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* 版本回滚控制器
*/
@RestController
@RequestMapping("/api/metadata/version-rollback")
public class VersionRollbackController {
@Autowired
private IVersionRollbackService versionRollbackService;
@PostMapping("/rollback")
public Map<String, Object> rollbackToPreviousVersion(@RequestBody Map<String, String> request) {
String filePath = request.get("filePath");
String result = versionRollbackService.rollbackToPreviousVersion(filePath);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("result", result);
return response;
}
}
15. DTO 类
package com.datai.salesforce.metadata.dto;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* 版本历史创建请求
*/
@Data
public class VersionHistoryCreateRequest {
private String versionNumber;
private String filePath;
private String fileHash;
private String fileContent;
private String versionType;
private Long taskId;
private Long orgConfigId;
}
/**
* 版本历史创建响应
*/
@Data
public class VersionHistoryCreateResponse {
private boolean success;
private Long versionId;
}
/**
* 版本历史查询请求
*/
@Data
public class VersionHistoryQueryRequest {
private LocalDateTime startTime;
private LocalDateTime endTime;
private Long taskId;
private String filePath;
private int pageNum;
private int pageSize;
}
/**
* 版本历史查询响应
*/
@Data
public class VersionHistoryQueryResponse {
private boolean success;
private List<MetadataVersion> versions;
}
/**
* 版本对比请求
*/
@Data
public class VersionComparisonRequest {
private Long versionId1;
private Long versionId2;
}
/**
* 版本对比响应
*/
@Data
public class VersionComparisonResponse {
private boolean success;
private java.util.Map<String, Object> result;
}
/**
* 文件内容对比请求
*/
@Data
public class FileContentComparisonRequest {
private String content1;
private String content2;
}
/**
* 文件内容对比响应
*/
@Data
public class FileContentComparisonResponse {
private boolean success;
private java.util.Map<String, Object> result;
}
/**
* 文件哈希对比请求
*/
@Data
public class FileHashComparisonRequest {
private String hash1;
private String hash2;
}
/**
* 文件哈希对比响应
*/
@Data
public class FileHashComparisonResponse {
private boolean success;
private java.util.Map<String, Object> result;
}
/**
* 版本恢复请求
*/
@Data
public class VersionRecoveryRequest {
private Long versionId;
}
/**
* 版本恢复响应
*/
@Data
public class VersionRecoveryResponse {
private boolean success;
private String result;
}
/**
* 版本回滚请求
*/
@Data
public class VersionRollbackRequest {
private String filePath;
}
/**
* 版本回滚响应
*/
@Data
public class VersionRollbackResponse {
private boolean success;
private String result;
}
16. 异常类
package com.datai.salesforce.metadata.exception;
/**
* 版本历史异常
*/
public class VersionHistoryException extends RuntimeException {
public VersionHistoryException(String message) {
super(message);
}
public VersionHistoryException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* 版本对比异常
*/
public class VersionComparisonException extends RuntimeException {
public VersionComparisonException(String message) {
super(message);
}
public VersionComparisonException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* 版本恢复异常
*/
public class VersionRecoveryException extends RuntimeException {
public VersionRecoveryException(String message) {
super(message);
}
public VersionRecoveryException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* 版本回滚异常
*/
public class VersionRollbackException extends RuntimeException {
public VersionRollbackException(String message) {
super(message);
}
public VersionRollbackException(String message, Throwable cause) {
super(message, cause);
}
}
单元测试
MetadataVersionServiceImplTest
package com.datai.salesforce.metadata.service.version.impl;
import com.datai.salesforce.metadata.entity.MetadataVersion;
import com.datai.salesforce.metadata.service.version.IMetadataVersionService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class MetadataVersionServiceImplTest {
@Autowired
private IMetadataVersionService metadataVersionService;
@Test
void testCreateVersion() {
MetadataVersion version = new MetadataVersion();
version.setVersionNumber("v1.0.0");
version.setFilePath("test.txt");
version.setFileHash("abc123");
version.setFileContent("test content");
version.setVersionType("RETRIEVE");
version.setTaskId(1L);
version.setOrgConfigId(1L);
version.setVersionTime(LocalDateTime.now());
Long versionId = metadataVersionService.createVersion(version);
assertNotNull(versionId);
assertTrue(versionId > 0);
}
@Test
void testGetVersion() {
MetadataVersion version = metadataVersionService.getVersion(1L);
assertNotNull(version);
}
}
VersionComparisonServiceImplTest
package com.datai.salesforce.metadata.service.version.impl;
import com.datai.salesforce.metadata.service.version.IVersionComparisonService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class VersionComparisonServiceImplTest {
@Autowired
private IVersionComparisonService versionComparisonService;
@Test
void testCompareFileContent() {
String content1 = "Hello World";
String content2 = "Hello Java";
Map<String, Object> result = versionComparisonService.compareFileContent(content1, content2);
assertNotNull(result);
assertTrue((Boolean) result.get("hasChanges"));
}
@Test
void testCompareFileHash() {
String hash1 = "abc123";
String hash2 = "def456";
Map<String, Object> result = versionComparisonService.compareFileHash(hash1, hash2);
assertNotNull(result);
assertFalse((Boolean) result.get("isEqual"));
}
}
配置文件
application.yml
spring:
task:
execution:
pool:
core-size: 5
max-size: 10
queue-capacity: 100
thread-name-prefix: version-executor-
version-rollback:
max-versions: 100
retention-days: 30
数据库表
datai_metadata_version
CREATE TABLE `datai_metadata_version` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`version_number` varchar(50) NOT NULL COMMENT '版本号',
`file_path` varchar(500) NOT NULL COMMENT '文件路径',
`file_hash` varchar(64) DEFAULT NULL COMMENT '文件哈希值',
`file_content` text COMMENT '文件内容',
`version_type` varchar(20) NOT NULL COMMENT '版本类型',
`task_id` bigint DEFAULT NULL COMMENT '任务ID',
`org_config_id` bigint DEFAULT NULL COMMENT '组织配置ID',
`version_time` datetime NOT NULL COMMENT '版本时间',
`dept_id` bigint DEFAULT NULL COMMENT '部门ID',
`create_by` varchar(64) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
KEY `idx_task_id` (`task_id`),
KEY `idx_org_config_id` (`org_config_id`),
KEY `idx_file_path` (`file_path`),
KEY `idx_version_time` (`version_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='元数据版本表';
总结
本 Prompt 提供了版本回溯功能的完整实现,包括:
- 版本历史记录 - 记录每次拉取和部署的版本
- 版本对比 - 对比不同版本的元数据文件
- 版本恢复 - 恢复到指定的历史版本
- 版本回滚 - 回滚到上一个版本
所有代码都遵循 Spring Boot 3 + MyBatis Plus 技术栈,复用现有的服务接口,保持代码一致性。