feat(service): 新增QueryService接口实现,支持通用查询功能 docs(util): 完善ProxyUtils工具类的注释说明 fix(model): 修复CustomerCatalog实现IdentityEntity接口 style: 优化代码格式和导入顺序 perf(util): 提升FileUtils工具类功能,新增文件处理方法 chore: 更新README.md文件,补充UI资源路径说明 build: 更新pom.xml文件中的mainClass配置 test: 调整测试类命名和路径 ci: 更新CI配置文件中的类引用 refactor(controller): 重构表格单元格异步更新逻辑 docs(constant): 新增常量定义和注释 style: 统一代码风格和命名规范 refactor(service): 重构服务类继承关系 perf(controller): 优化表格数据加载性能 fix(service): 修复文件类型服务缓存问题 docs(model): 完善视图模型类注释 refactor(util): 重构文件工具类方法 style: 清理无用导入和代码 chore: 更新.gitignore文件 build: 调整项目依赖配置 refactor(controller): 重构控制器基类 perf(service): 优化查询服务性能 fix(controller): 修复表格数据加载异常 docs: 更新代码注释和文档 style: 统一代码缩进和格式
203 lines
7.2 KiB
Java
203 lines
7.2 KiB
Java
package com.ecep.contract.service;
|
|
|
|
import com.ecep.contract.PageArgument;
|
|
import com.ecep.contract.PageContent;
|
|
import com.ecep.contract.WebSocketService;
|
|
import com.ecep.contract.model.IdentityEntity;
|
|
import com.ecep.contract.msg.SimpleMessage;
|
|
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 org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.data.domain.Page;
|
|
import org.springframework.data.domain.Pageable;
|
|
|
|
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.concurrent.TimeUnit;
|
|
import java.util.function.Supplier;
|
|
|
|
public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel<T>>
|
|
implements ViewModelService<T, TV> {
|
|
@Autowired
|
|
protected WebSocketService 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) {
|
|
SimpleMessage msg = new SimpleMessage();
|
|
msg.setService(getBeanName());
|
|
msg.setMethod("save");
|
|
msg.setArguments(entity);
|
|
try {
|
|
Object response = webSocketService.send(msg).get(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS);
|
|
if (response != null) {
|
|
objectMapper.updateValue(entity, response);
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return entity;
|
|
}
|
|
|
|
@Override
|
|
public void delete(T entity) {
|
|
SimpleMessage msg = new SimpleMessage();
|
|
msg.setService(getBeanName());
|
|
msg.setMethod("delete");
|
|
msg.setArguments(entity);
|
|
try {
|
|
JsonNode response = webSocketService.send(msg).get(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS);
|
|
if (response != null) {
|
|
objectMapper.updateValue(entity, response);
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public CompletableFuture<T> asyncFindById(Integer id) {
|
|
SimpleMessage msg = new SimpleMessage();
|
|
msg.setService(getBeanName());
|
|
msg.setMethod("findById");
|
|
msg.setArguments(id);
|
|
return webSocketService.send(msg).orTimeout(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS).handle((response, ex) -> {
|
|
if (ex != null) {
|
|
return null;
|
|
}
|
|
if (response == null) {
|
|
return null;
|
|
}
|
|
T newEntity = createNewEntity();
|
|
try {
|
|
objectMapper.updateValue(newEntity, response);
|
|
} catch (JsonMappingException e) {
|
|
throw new RuntimeException(response.toString(), e);
|
|
}
|
|
return newEntity;
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public T findById(Integer id) {
|
|
try {
|
|
return asyncFindById(id).get();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public List<T> findAll() {
|
|
return findAll(null, Pageable.unpaged()).getContent();
|
|
}
|
|
|
|
public CompletableFuture<Page<T>> asyncFindAll(Map<String, Object> params, Pageable pageable) {
|
|
SimpleMessage msg = new SimpleMessage();
|
|
msg.setService(getBeanName());
|
|
msg.setMethod("findAll");
|
|
msg.setArguments(params, PageArgument.of(pageable));
|
|
return webSocketService.send(msg).orTimeout(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS).handle((response, ex) -> {
|
|
if (ex != null) {
|
|
return null;
|
|
}
|
|
if (response == null) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
PageContent<T> pageContent = of(response, objectMapper, this::createNewEntity);
|
|
return pageContent.toPage();
|
|
} catch (Exception e) {
|
|
throw new RuntimeException(response.toString(), e);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Page<T> findAll(Map<String, Object> params, Pageable pageable) {
|
|
try {
|
|
return asyncFindAll(params, pageable).get();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public List<T> search(String searchText) {
|
|
Map<String, Object> params = getSpecification(searchText);
|
|
List<T> list = findAll(params, Pageable.ofSize(10)).getContent();
|
|
return list;
|
|
}
|
|
|
|
|
|
public static <T> PageContent<T> of(JsonNode response, ObjectMapper objectMapper, Supplier<T> createNewEntity)
|
|
throws JsonProcessingException {
|
|
|
|
PageContent<T> pageContent = new PageContent<>();
|
|
List<T> 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;
|
|
}
|
|
|
|
}
|