package com.ecep.contract.service; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import com.ecep.contract.PageArgument; import com.ecep.contract.PageContent; import com.ecep.contract.WebSocketClientService; import com.ecep.contract.model.IdentityEntity; import com.ecep.contract.util.ParamUtils; import com.ecep.contract.vm.IdentityViewModel; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import javafx.util.StringConverter; public class QueryService> implements ViewModelService { // 添加日志记录器 private static final Logger logger = LoggerFactory.getLogger(QueryService.class); @Autowired protected WebSocketClientService webSocketService; @Autowired protected ObjectMapper objectMapper; @SuppressWarnings("unchecked") public TV createNewViewModel() { try { Type genericSuperclass = getClass().getGenericSuperclass(); String typeName = genericSuperclass.getTypeName(); // System.out.println("typeName = " + typeName); String clz = typeName.split("<")[1].split(">")[0].split(",")[1].trim(); // System.out.println("clz = " + clz); Class clazz = Class.forName(clz); return (TV) clazz.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException("无法创建ViewModel实例", e); } } @SuppressWarnings("unchecked") public T createNewEntity() { try { Type genericSuperclass = getClass().getGenericSuperclass(); String typeName = genericSuperclass.getTypeName(); // System.out.println("typeName = " + typeName); String clz = typeName.split("<")[1].split(">")[0].split(",")[0].trim(); // System.out.println("clz = " + clz); Class clazz = Class.forName(clz); return (T) clazz.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException("无法创建Entity实例", e); } } @Override public T save(T entity) { try { return async("save", entity, entity.getClass().getName()).handle((response, ex) -> { if (ex != null) { throw new RuntimeException("保存实体失败", ex); } if (response != null) { try { objectMapper.updateValue(entity, response); } catch (JsonMappingException e) { throw new RuntimeException(e); } } return entity; }).get(); } catch (Exception e) { throw new RuntimeException("保存实体失败", e); } } @Override public void delete(T entity) { try { async("delete", entity, entity.getClass().getName()).handle((response, ex) -> { if (ex != null) { throw new RuntimeException("删除实体失败", ex); } if (response != null) { return updateValue(entity, response); } return null; }).get(); } catch (Exception e) { logger.error("删除实体失败 #{}", entity.getId(), e); throw new RuntimeException("删除实体失败", e); } } public T updateValue(T entity, JsonNode node) { try { objectMapper.updateValue(entity, node); } catch (JsonMappingException e) { throw new RuntimeException(e); } return entity; } public CompletableFuture async(String method, Object... params) { return webSocketService.invoke(getBeanName(), method, params).handle((response, ex) -> { if (ex != null) { throw new RuntimeException("远程方法+" + method + "+调用失败", ex); } return response; }); } public CompletableFuture asyncFindById(Integer id) { return async("findById", id, Integer.class).handle((response, ex) -> { if (ex != null) { throw new RuntimeException("查询实体失败", ex); } T newEntity = createNewEntity(); return updateValue(newEntity, response); }); } @Override public T findById(Integer id) { try { return asyncFindById(id).get(); } catch (Exception e) { logger.error("查询实体失败 #{}", id, e); throw new RuntimeException("查询实体失败", e); } } public List findAll() { return findAll(null, Pageable.unpaged()).getContent(); } /** * 异步查询所有实体数据,返回CompletableFuture对象 * * @param params 查询参数映射表,可以包含过滤条件等信息 * @param pageable 分页参数,包含页码、每页条数、排序规则等 * @return 包含分页结果的CompletableFuture对象 */ public CompletableFuture> asyncFindAll(Map params, Pageable pageable) { // 调用async方法发送WebSocket请求,获取异步响应结果 return async("findAll", params, PageArgument.of(pageable)).handle((response, ex) -> { if (ex != null) { throw new RuntimeException("远程方法+findAll+调用失败", ex); } try { // 将响应结果转换为PageContent对象,使用当前类的createNewEntity方法创建实体实例 PageContent pageContent = of(response, objectMapper, this::createNewEntity); // 将PageContent转换为Spring Data的Page对象并返回 return pageContent.toPage(); } catch (Exception e) { // 处理转换过程中的异常,包装为RuntimeException并附带响应内容 throw new RuntimeException(response.toString(), e); } }); } /** * 同步查询所有实体数据,实现了ViewModelService接口的findAll方法 * * @param params 查询参数映射表,可以包含过滤条件等信息 * @param pageable 分页参数,包含页码、每页条数、排序规则等 * @return 包含查询结果的Page对象 * @throws RuntimeException 当查询失败时抛出异常 */ @Override public Page findAll(Map params, Pageable pageable) { try { if (pageable == null) { pageable = Pageable.unpaged(); } // 调用异步方法并阻塞等待结果返回 return asyncFindAll(params, pageable).get(); } catch (Exception e) { // 处理异步查询过程中的任何异常,转换为运行时异常抛出 throw new RuntimeException("查询所有实体失败", e); } } /** * 异步执行计数操作,返回CompletableFuture类型结果 * * @param params 包含计数所需参数的Map集合 * @return 返回一个CompletableFuture对象,用于获取异步操作的结果 */ public CompletableFuture asyncCount(Map params) { // 调用async方法执行名为"count"的异步操作,传入参数params // 使用handle方法处理异步操作的结果或异常 return async("count", params).handle((response, ex) -> { if (ex != null) { throw new RuntimeException("远程方法+count+调用失败", ex); } // 将响应结果转换为Long类型并返回 return response.asLong(); }); } public long count(Map params) { try { return asyncCount(params).get(); } catch (Exception e) { throw new RuntimeException("计数失败", e); } } public List search(String searchText) { ParamUtils.Builder params = getSpecification(searchText); List list = findAll(params.build(), Pageable.ofSize(10)).getContent(); return list; } public static PageContent of(JsonNode response, ObjectMapper objectMapper, Supplier createNewEntity) throws JsonProcessingException { PageContent pageContent = new PageContent<>(); List content = new ArrayList<>(); if (response.has("content")) { JsonNode contentNode = response.get("content"); if (contentNode != null && contentNode.isArray()) { for (JsonNode node : contentNode) { T newEntity = createNewEntity.get(); objectMapper.updateValue(newEntity, node); content.add(newEntity); } } } pageContent.setContent(content); if (response.has("page")) { JsonNode pageNode = response.get("page"); PageArgument pageArgument = objectMapper.treeToValue(pageNode, PageArgument.class); pageContent.setPage(pageArgument); } if (response.has("totalElements")) { int totalElements = response.get("totalElements").asInt(); pageContent.setTotalElements(totalElements); } if (response.has("totalPages")) { int totalPages = response.get("totalPages").asInt(); pageContent.setTotalPages(totalPages); } return pageContent; } public StringConverter getStringConverter() { return new StringConverter<>() { @Override public String toString(T object) { return object.toString(); } @Override public T fromString(String string) { return null; } }; } }