1
0

refactor(common): 重构响应结构,使用泛型记录替代Map

- 将 responseCrudData() 重命名为 responseListData()
- 新增 ListItem 和 DetailItem 泛型记录替代 Map 包装
- 更新 QueryController 接口支持双泛型参数
- 优化类型安全性和代码可读性
This commit is contained in:
2026-01-06 15:28:27 +08:00
parent 6840d4a366
commit 8a944923ea
4 changed files with 31 additions and 23 deletions

View File

@@ -1,5 +1,6 @@
package com.lanyuanxiaoyao.service.template.common.controller; package com.lanyuanxiaoyao.service.template.common.controller;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@@ -28,7 +29,7 @@ import java.util.Map;
* <ul> * <ul>
* <li>成功响应: 使用 responseSuccess() 系列方法</li> * <li>成功响应: 使用 responseSuccess() 系列方法</li>
* <li>错误响应: 使用 responseError() 系列方法</li> * <li>错误响应: 使用 responseError() 系列方法</li>
* <li>CRUD操作: 使用 responseCrudData() 方法返回列表数据</li> * <li>CRUD操作: 使用 responseListData() 方法返回列表数据</li>
* <li>详情查询: 使用 responseDetailData() 方法返回单条记录</li> * <li>详情查询: 使用 responseDetailData() 方法返回单条记录</li>
* </ul> * </ul>
* </p> * </p>
@@ -165,6 +166,10 @@ public record GlobalResponse<T>(Integer status, String message, T data) {
return responseMapData(Map.of(key, value)); return responseMapData(Map.of(key, value));
} }
public static <T> GlobalResponse<ListItem<T>> responseListData() {
return responseListData(List.of(), 0);
}
/** /**
* 返回CRUD列表数据的成功响应Integer类型总数 * 返回CRUD列表数据的成功响应Integer类型总数
* <p> * <p>
@@ -176,8 +181,8 @@ public record GlobalResponse<T>(Integer status, String message, T data) {
* @param total 总记录数 * @param total 总记录数
* @return 成功响应对象 * @return 成功响应对象
*/ */
public static <T> GlobalResponse<Map<String, Object>> responseCrudData(Iterable<T> data, Integer total) { public static <T> GlobalResponse<ListItem<T>> responseListData(Iterable<T> data, Integer total) {
return responseCrudData(data, total.longValue()); return responseListData(data, total.longValue());
} }
/** /**
@@ -191,8 +196,8 @@ public record GlobalResponse<T>(Integer status, String message, T data) {
* @param total 总记录数 * @param total 总记录数
* @return 成功响应对象 * @return 成功响应对象
*/ */
public static <T> GlobalResponse<Map<String, Object>> responseCrudData(Iterable<T> data, Long total) { public static <T> GlobalResponse<ListItem<T>> responseListData(Iterable<T> data, Long total) {
return responseMapData(Map.of("items", data, "total", total)); return responseSuccess(new ListItem<>(data, total));
} }
/** /**
@@ -201,10 +206,16 @@ public record GlobalResponse<T>(Integer status, String message, T data) {
* 适用于详情查询将单条记录封装为Map格式 * 适用于详情查询将单条记录封装为Map格式
* </p> * </p>
* *
* @param detail 详情数据 * @param data 详情数据
* @return 成功响应对象 * @return 成功响应对象
*/ */
public static GlobalResponse<Map<String, Object>> responseDetailData(Object detail) { public static <T> GlobalResponse<DetailItem<T>> responseDetailData(T data) {
return responseMapData("detail", detail); return responseSuccess(new DetailItem<>(data));
}
public record ListItem<T>(Iterable<T> items, Long total) {
}
public record DetailItem<T>(T item) {
} }
} }

View File

@@ -1,7 +1,5 @@
package com.lanyuanxiaoyao.service.template.common.controller; package com.lanyuanxiaoyao.service.template.common.controller;
import java.util.Map;
/** /**
* 查询控制器接口,用于定义统一的查询实体详情和列表的接口规范 * 查询控制器接口,用于定义统一的查询实体详情和列表的接口规范
* *
@@ -53,9 +51,9 @@ import java.util.Map;
* </ul> * </ul>
* </p> * </p>
* *
* @param <QUERY_ITEM> 查询结果的实体类型 * @param <DETAIL_ITEM> 查询结果的实体类型
*/ */
public interface QueryController<QUERY_ITEM> { public interface QueryController<LIST_ITEM, DETAIL_ITEM> {
String LIST = "/list"; String LIST = "/list";
String DETAIL = "/detail/{id}"; String DETAIL = "/detail/{id}";
@@ -65,7 +63,7 @@ public interface QueryController<QUERY_ITEM> {
* @return GlobalResponse<Map<String, Object>> 返回实体列表 * @return GlobalResponse<Map<String, Object>> 返回实体列表
* @throws Exception 查询过程中可能抛出的异常 * @throws Exception 查询过程中可能抛出的异常
*/ */
GlobalResponse<Map<String, Object>> list() throws Exception; GlobalResponse<GlobalResponse.ListItem<LIST_ITEM>> list() throws Exception;
/** /**
* 根据查询条件获取实体列表 * 根据查询条件获取实体列表
@@ -74,7 +72,7 @@ public interface QueryController<QUERY_ITEM> {
* @return GlobalResponse<Map<String, Object>> 返回符合条件的实体列表 * @return GlobalResponse<Map<String, Object>> 返回符合条件的实体列表
* @throws Exception 查询过程中可能抛出的异常 * @throws Exception 查询过程中可能抛出的异常
*/ */
GlobalResponse<Map<String, Object>> list(Query query) throws Exception; GlobalResponse<GlobalResponse.ListItem<LIST_ITEM>> list(Query query) throws Exception;
/** /**
* 根据ID获取实体详情 * 根据ID获取实体详情
@@ -83,5 +81,5 @@ public interface QueryController<QUERY_ITEM> {
* @return GlobalResponse<QUERY_ITEM> 返回实体详情 * @return GlobalResponse<QUERY_ITEM> 返回实体详情
* @throws Exception 查询过程中可能抛出的异常 * @throws Exception 查询过程中可能抛出的异常
*/ */
GlobalResponse<QUERY_ITEM> detail(Long id) throws Exception; GlobalResponse<DETAIL_ITEM> detail(Long id) throws Exception;
} }

View File

@@ -1,4 +1,4 @@
package com.lanyuanxiaoyao.service.template.common.controller; package com.lanyuanxiaoyao.service.template.common.controller;
public interface SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> extends SaveController<SAVE_ITEM>, QueryController<DETAIL_ITEM>, RemoveController { public interface SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> extends SaveController<SAVE_ITEM>, QueryController<LIST_ITEM, DETAIL_ITEM>, RemoveController {
} }

View File

@@ -1,12 +1,11 @@
package com.lanyuanxiaoyao.service.template.jpa.controller; package com.lanyuanxiaoyao.service.template.jpa.controller;
import com.lanyuanxiaoyao.service.template.common.controller.GlobalResponse; import com.lanyuanxiaoyao.service.template.common.controller.GlobalResponse;
import com.lanyuanxiaoyao.service.template.common.controller.Query;
import com.lanyuanxiaoyao.service.template.common.controller.SimpleController; import com.lanyuanxiaoyao.service.template.common.controller.SimpleController;
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper; import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity; import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
import com.lanyuanxiaoyao.service.template.jpa.service.SimpleServiceSupport; import com.lanyuanxiaoyao.service.template.jpa.service.SimpleServiceSupport;
import java.util.List;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -131,10 +130,10 @@ public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_
@Transactional(readOnly = true) @Transactional(readOnly = true)
@GetMapping(LIST) @GetMapping(LIST)
@Override @Override
public GlobalResponse<Map<String, Object>> list() throws Exception { public GlobalResponse<GlobalResponse.ListItem<LIST_ITEM>> list() throws Exception {
var mapper = listItemMapper(); var mapper = listItemMapper();
var result = service.list(); var result = service.list();
return GlobalResponse.responseCrudData( return GlobalResponse.responseListData(
result result
.stream() .stream()
.map(entity -> { .map(entity -> {
@@ -159,13 +158,13 @@ public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_
@Transactional(readOnly = true) @Transactional(readOnly = true)
@PostMapping(LIST) @PostMapping(LIST)
@Override @Override
public GlobalResponse<Map<String, Object>> list(@RequestBody com.lanyuanxiaoyao.service.template.common.controller.Query query) throws Exception { public GlobalResponse<GlobalResponse.ListItem<LIST_ITEM>> list(@RequestBody Query query) throws Exception {
if (ObjectHelper.isNull(query)) { if (ObjectHelper.isNull(query)) {
return GlobalResponse.responseCrudData(List.of(), 0); return GlobalResponse.responseListData();
} }
var mapper = listItemMapper(); var mapper = listItemMapper();
var result = service.list(query); var result = service.list(query);
return GlobalResponse.responseCrudData( return GlobalResponse.responseListData(
result.items() result.items()
.map(entity -> { .map(entity -> {
try { try {