15 KiB
DTO And RequestResult Refactor Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 将现有枚举、附件、RAG 三块接口统一改造成 DTO 入参与 DTO 返回,并引入 RequestResult 作为统一响应包装。
Architecture: controller、service、mapper 三层都尽量以 DTO 作为边界对象,实体类仅用于 MyBatis-Plus 持久化与表映射。控制层统一返回 RequestResult<T>,查询条件走 request/query DTO,列表和详情都返回 response DTO,避免继续直接暴露实体和零散参数。
Tech Stack: Java 21、Spring Boot 4、MyBatis-Plus、Spring MVC、JUnit 5
Task 1: 建立统一响应体和 DTO 包结构
Files:
-
Create:
src/main/java/com/bruce/common/dto/RequestResult.java -
Create:
src/main/java/com/bruce/common/dto/request/ -
Create:
src/main/java/com/bruce/common/dto/response/ -
Create:
src/main/java/com/bruce/rag/dto/request/ -
Create:
src/main/java/com/bruce/rag/dto/response/ -
Modify:
src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java -
Modify:
src/test/java/com/bruce/rag/RagComponentStructureTests.java -
Step 1: 写失败测试,固定统一返回体存在且控制层不再暴露裸实体
在结构测试中增加如下断言思路:
Method saveOrUpdateMethod = SysEnumController.class.getMethod("saveOrUpdate", SysEnumSaveRequest.class); assertEquals(RequestResult.class, saveOrUpdateMethod.getReturnType());Method listMethod = RagStoreController.class.getMethod("list", RagStoreQueryRequest.class); assertEquals(RequestResult.class, listMethod.getReturnType()); -
Step 2: 运行测试并确认失败
Run:
.\mvnw.cmd "-Dtest=SysEnumComponentStructureTests,RagComponentStructureTests" testExpected: FAIL,提示 DTO 或
RequestResult类型不存在,或控制器方法签名不匹配。 -
Step 3: 最小化实现统一响应体和基础 DTO 目录
RequestResult.java采用如下结构:@Data @NoArgsConstructor @AllArgsConstructor public class RequestResult<T> { private boolean success; private String code; private String message; private T data; public static <T> RequestResult<T> success(T data) { return new RequestResult<>(true, "SUCCESS", "操作成功", data); } public static <T> RequestResult<T> success(String message, T data) { return new RequestResult<>(true, "SUCCESS", message, data); } public static <T> RequestResult<T> failure(String code, String message) { return new RequestResult<>(false, code, message, null); } } -
Step 4: 运行测试并确认通过
Run:
.\mvnw.cmd "-Dtest=SysEnumComponentStructureTests,RagComponentStructureTests" testExpected: PASS 或只剩下后续控制器签名相关失败。
-
Step 5: Commit
git add src/main/java/com/bruce/common/dto src/main/java/com/bruce/rag/dto src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java src/test/java/com/bruce/rag/RagComponentStructureTests.java git commit -m "refactor: 增加统一响应体与DTO结构"
Task 2: 重构 sys_enum 模块为 DTO 入参与 DTO 返回
Files:
-
Create:
src/main/java/com/bruce/common/dto/request/SysEnumQueryRequest.java -
Create:
src/main/java/com/bruce/common/dto/request/SysEnumSaveRequest.java -
Create:
src/main/java/com/bruce/common/dto/response/SysEnumResponse.java -
Modify:
src/main/java/com/bruce/common/controller/SysEnumController.java -
Modify:
src/main/java/com/bruce/common/service/ISysEnumService.java -
Modify:
src/main/java/com/bruce/common/service/impl/SysEnumServiceImpl.java -
Modify:
src/main/java/com/bruce/common/mapper/SysEnumMapper.java -
Modify:
src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java -
Step 1: 写失败测试,固定 sys_enum 控制器和服务都使用 DTO
在
SysEnumComponentStructureTests中增加断言:Method queryMethod = SysEnumController.class.getMethod("queryByCatalogAndType", SysEnumQueryRequest.class); Method saveMethod = SysEnumController.class.getMethod("saveOrUpdate", SysEnumSaveRequest.class); Method serviceMethod = ISysEnumService.class.getMethod("listByCatalogAndType", SysEnumQueryRequest.class); -
Step 2: 运行测试并确认失败
Run:
.\mvnw.cmd "-Dtest=SysEnumComponentStructureTests" testExpected: FAIL,提示方法签名仍然是
String或SysEnum。 -
Step 3: 最小化实现 request/response DTO
SysEnumQueryRequest.java:@Data public class SysEnumQueryRequest { private String catalog; private String type; }SysEnumSaveRequest.java:@Data public class SysEnumSaveRequest { private Long id; private String catalog; private String type; private String name; private Integer value; private String strvalue; private Integer sort; private String remark; }SysEnumResponse.java:@Data public class SysEnumResponse { private Long id; private String catalog; private String type; private String name; private Integer value; private String strvalue; private Integer sort; private String remark; } -
Step 4: 修改 mapper/service/controller
ISysEnumService返回List<SysEnumResponse>,保存返回SysEnumResponseSysEnumServiceImpl新增 DTO 与实体互转私有方法SysEnumMapper保留 MP 基础能力;如需自定义查询,新增 DTO 查询方法签名SysEnumController所有接口返回RequestResult<?>
控制器目标形态:
@PostMapping("/query") public RequestResult<List<SysEnumResponse>> queryByCatalogAndType(@RequestBody SysEnumQueryRequest request) { return RequestResult.success(sysEnumService.listByCatalogAndType(request)); } -
Step 5: 运行测试并确认通过
Run:
.\mvnw.cmd "-Dtest=SysEnumComponentStructureTests" testExpected: PASS
-
Step 6: Commit
git add src/main/java/com/bruce/common/controller/SysEnumController.java src/main/java/com/bruce/common/service/ISysEnumService.java src/main/java/com/bruce/common/service/impl/SysEnumServiceImpl.java src/main/java/com/bruce/common/dto/request/SysEnumQueryRequest.java src/main/java/com/bruce/common/dto/request/SysEnumSaveRequest.java src/main/java/com/bruce/common/dto/response/SysEnumResponse.java src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java git commit -m "refactor: 调整sys_enum接口为DTO模式"
Task 3: 重构 sys_attachment 模块为 DTO 入参与 DTO 返回
Files:
-
Create:
src/main/java/com/bruce/common/dto/request/SysAttachmentUploadRequest.java -
Create:
src/main/java/com/bruce/common/dto/request/SysAttachmentQueryRequest.java -
Create:
src/main/java/com/bruce/common/dto/response/SysAttachmentResponse.java -
Modify:
src/main/java/com/bruce/common/controller/SysAttachmentController.java -
Modify:
src/main/java/com/bruce/common/service/ISysAttachmentService.java -
Modify:
src/main/java/com/bruce/common/service/impl/SysAttachmentServiceImpl.java -
Modify:
src/test/java/com/bruce/common/attachment/SysAttachmentComponentStructureTests.java -
Step 1: 写失败测试,固定附件接口返回
RequestResult且 service 返回 DTO示例断言:
Method uploadMethod = SysAttachmentController.class.getMethod("upload", MultipartFile.class, SysAttachmentUploadRequest.class); assertEquals(RequestResult.class, uploadMethod.getReturnType()); -
Step 2: 运行测试并确认失败
Run:
.\mvnw.cmd "-Dtest=SysAttachmentComponentStructureTests" testExpected: FAIL,提示控制器或服务方法签名不匹配。
-
Step 3: 新增附件 DTO
SysAttachmentUploadRequest.java:@Data public class SysAttachmentUploadRequest { private String sourceType; private Long sourceId; }SysAttachmentQueryRequest.java:@Data public class SysAttachmentQueryRequest { private String sourceType; private Long sourceId; }SysAttachmentResponse.java:@Data public class SysAttachmentResponse { private Long id; private String sourceType; private Long sourceId; private String originalName; private String fileName; private String fileSuffix; private String contentType; private Long fileSize; private String storageType; private String filePath; private String fileUrl; private String remark; } -
Step 4: 修改附件控制器和服务
ISysAttachmentService.upload返回SysAttachmentResponse- 控制器上传接口返回
RequestResult<SysAttachmentResponse> - 如补充列表查询,也走
SysAttachmentQueryRequest
-
Step 5: 运行测试并确认通过
Run:
.\mvnw.cmd "-Dtest=SysAttachmentComponentStructureTests" testExpected: PASS
-
Step 6: Commit
git add src/main/java/com/bruce/common/controller/SysAttachmentController.java src/main/java/com/bruce/common/service/ISysAttachmentService.java src/main/java/com/bruce/common/service/impl/SysAttachmentServiceImpl.java src/main/java/com/bruce/common/dto/request/SysAttachmentUploadRequest.java src/main/java/com/bruce/common/dto/request/SysAttachmentQueryRequest.java src/main/java/com/bruce/common/dto/response/SysAttachmentResponse.java src/test/java/com/bruce/common/attachment/SysAttachmentComponentStructureTests.java git commit -m "refactor: 调整附件接口为DTO模式"
Task 4: 重构 rag_store 与 rag_document 模块为 DTO 入参与 DTO 返回
Files:
-
Create:
src/main/java/com/bruce/rag/dto/request/RagStoreQueryRequest.java -
Create:
src/main/java/com/bruce/rag/dto/request/RagStoreSaveRequest.java -
Create:
src/main/java/com/bruce/rag/dto/request/RagDocumentQueryRequest.java -
Create:
src/main/java/com/bruce/rag/dto/request/RagDocumentSaveRequest.java -
Create:
src/main/java/com/bruce/rag/dto/response/RagStoreResponse.java -
Create:
src/main/java/com/bruce/rag/dto/response/RagDocumentResponse.java -
Modify:
src/main/java/com/bruce/rag/controller/RagStoreController.java -
Modify:
src/main/java/com/bruce/rag/controller/RagDocumentController.java -
Modify:
src/main/java/com/bruce/rag/service/IRagStoreService.java -
Modify:
src/main/java/com/bruce/rag/service/IRagDocumentService.java -
Modify:
src/main/java/com/bruce/rag/service/impl/RagStoreServiceImpl.java -
Modify:
src/main/java/com/bruce/rag/service/impl/RagDocumentServiceImpl.java -
Modify:
src/test/java/com/bruce/rag/RagComponentStructureTests.java -
Step 1: 写失败测试,固定 RAG 控制器和服务都使用 DTO
示例断言:
Method storeListMethod = RagStoreController.class.getMethod("list", RagStoreQueryRequest.class); Method documentListMethod = RagDocumentController.class.getMethod("list", RagDocumentQueryRequest.class); assertEquals(RequestResult.class, storeListMethod.getReturnType()); assertEquals(RequestResult.class, documentListMethod.getReturnType()); -
Step 2: 运行测试并确认失败
Run:
.\mvnw.cmd "-Dtest=RagComponentStructureTests" testExpected: FAIL,提示控制器和 service 仍然暴露实体或无 DTO。
-
Step 3: 新增 RAG DTO
RagStoreQueryRequest.java:@Data public class RagStoreQueryRequest { private String storeCode; private String storeName; private String status; }RagStoreResponse.java:@Data public class RagStoreResponse { private Long id; private String storeCode; private String storeName; private String description; private String status; private String remark; }RagDocumentQueryRequest.java:@Data public class RagDocumentQueryRequest { private Long storeId; private Long attachmentId; private String parseStatus; private String indexStatus; private Boolean enabled; }RagDocumentResponse.java:@Data public class RagDocumentResponse { private Long id; private Long storeId; private Long attachmentId; private String documentTitle; private String documentSummary; private String parseStatus; private String indexStatus; private Boolean enabled; private String errorMessage; private String remark; } -
Step 4: 修改 RAG service/controller
IRagStoreService、IRagDocumentService返回 DTORagStoreController和RagDocumentController返回RequestResult- 查询接口改为
@PostMapping("/query")+@RequestBody QueryRequest
-
Step 5: 运行测试并确认通过
Run:
.\mvnw.cmd "-Dtest=RagComponentStructureTests" testExpected: PASS
-
Step 6: Commit
git add src/main/java/com/bruce/rag/controller/RagStoreController.java src/main/java/com/bruce/rag/controller/RagDocumentController.java src/main/java/com/bruce/rag/service/IRagStoreService.java src/main/java/com/bruce/rag/service/IRagDocumentService.java src/main/java/com/bruce/rag/service/impl/RagStoreServiceImpl.java src/main/java/com/bruce/rag/service/impl/RagDocumentServiceImpl.java src/main/java/com/bruce/rag/dto/request src/main/java/com/bruce/rag/dto/response src/test/java/com/bruce/rag/RagComponentStructureTests.java git commit -m "refactor: 调整RAG接口为DTO模式"
Task 5: 全量验证与整理
Files:
-
Modify:
src/test/java/com/bruce/common/attachment/SysAttachmentComponentStructureTests.java -
Modify:
src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java -
Modify:
src/test/java/com/bruce/rag/RagComponentStructureTests.java -
Step 1: 运行定向测试,确认三块 DTO 改造都覆盖到
Run:
.\mvnw.cmd "-Dtest=SysAttachmentComponentStructureTests,SysEnumComponentStructureTests,RagComponentStructureTests" testExpected: PASS
-
Step 2: 运行全量测试
Run:
.\mvnw.cmd testExpected:
BUILD SUCCESS -
Step 3: 检查工作区
Run:
git status --shortExpected: 仅显示本次预期文件,或为空(若已提交)。
-
Step 4: Commit
git add src/test/java/com/bruce/common/attachment/SysAttachmentComponentStructureTests.java src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java src/test/java/com/bruce/rag/RagComponentStructureTests.java git commit -m "test: 校验DTO接口改造结构"