refactor: 移除冗余方法并优化查询逻辑
移除多个服务类中重复的findAll方法实现,统一使用父类方法 优化QueryService的findOneByProperty实现,提高可读性 为EntityService添加aliasFor方法支持字段别名 修复ContractVerifyWindowController的消息处理逻辑 添加查看验证状态的功能菜单项
This commit is contained in:
@@ -3,6 +3,7 @@ package com.ecep.contract;
|
||||
import java.util.List;
|
||||
|
||||
import com.ecep.contract.constant.ParamConstant;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -22,7 +23,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
/**
|
||||
* 实体服务基类
|
||||
* 提供基础的CRUD操作和查询方法
|
||||
*
|
||||
*
|
||||
* @param <T> 实体类型
|
||||
* @param <VO> VO类型
|
||||
* @param <ID> 主键类型
|
||||
@@ -32,7 +33,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
/**
|
||||
* 获取实体数据访问层接口
|
||||
* 子类必须实现此方法,提供具体的实体数据访问层实例
|
||||
*
|
||||
*
|
||||
* @return 实体数据访问层接口
|
||||
*/
|
||||
protected abstract MyRepository<T, ID> getRepository();
|
||||
@@ -45,14 +46,14 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
* 创建新实体实例
|
||||
* 设置默认值或必要的属性
|
||||
* 实例是游离态的,未存储到数据库
|
||||
*
|
||||
*
|
||||
* @return 新实体实例
|
||||
*/
|
||||
public abstract T createNewEntity();
|
||||
|
||||
/**
|
||||
* 统计所有实体数量
|
||||
*
|
||||
*
|
||||
* @return 实体数量
|
||||
*/
|
||||
public long count() {
|
||||
@@ -61,7 +62,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 根据查询规范统计实体数量
|
||||
*
|
||||
*
|
||||
* @param spec 查询规范
|
||||
* @return 符合规范的实体数量
|
||||
*/
|
||||
@@ -71,7 +72,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 根据JSON参数节点统计实体数量
|
||||
*
|
||||
*
|
||||
* @param paramsNode JSON参数节点
|
||||
* @return 符合参数节点规范的实体数量
|
||||
*/
|
||||
@@ -81,7 +82,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 保存实体到数据库
|
||||
*
|
||||
*
|
||||
* @param entity 要保存的实体
|
||||
* @return 保存后的实体
|
||||
*/
|
||||
@@ -91,7 +92,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 删除实体
|
||||
*
|
||||
*
|
||||
* @param entity 要删除的实体
|
||||
*/
|
||||
public void delete(T entity) {
|
||||
@@ -103,7 +104,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 应用JSON参数节点到查询规范
|
||||
*
|
||||
*
|
||||
* @param node JSON参数节点
|
||||
* @return 应用参数节点后的查询规范
|
||||
*/
|
||||
@@ -121,7 +122,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 根据JSON参数节点查询所有实体
|
||||
*
|
||||
*
|
||||
* @param paramsNode JSON参数节点
|
||||
* @param pageable 分页信息
|
||||
* @return 符合参数节点规范的实体分页结果
|
||||
@@ -132,7 +133,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 根据查询规范查询所有实体
|
||||
*
|
||||
*
|
||||
* @param spec 查询规范
|
||||
* @param pageable 分页信息
|
||||
* @return 符合规范的实体分页结果
|
||||
@@ -143,7 +144,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 根据查询规范查询所有实体
|
||||
*
|
||||
*
|
||||
* @param spec 查询规范
|
||||
* @param sort 排序信息
|
||||
* @return 符合规范的实体列表
|
||||
@@ -154,7 +155,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 根据搜索文本查询所有实体
|
||||
*
|
||||
*
|
||||
* @param searchText 搜索文本
|
||||
* @return 符合搜索文本规范的实体列表
|
||||
*/
|
||||
@@ -165,7 +166,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 根据搜索文本构建查询规范
|
||||
*
|
||||
*
|
||||
* @param searchText 搜索文本
|
||||
* @return 符合搜索文本规范的查询规范
|
||||
*/
|
||||
@@ -178,7 +179,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 构建搜索规范
|
||||
*
|
||||
*
|
||||
* @param searchText 搜索文本,非空
|
||||
* @return 符合搜索文本规范的查询规范
|
||||
*/
|
||||
@@ -186,7 +187,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 构建过滤条件规范
|
||||
*
|
||||
*
|
||||
* @param filterNode 过滤条件节点
|
||||
* @return 过滤条件规范
|
||||
*/
|
||||
@@ -226,6 +227,8 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
return null;
|
||||
}
|
||||
|
||||
field = aliasFor(field, filterNode);
|
||||
|
||||
if (ParamConstant.KEY_equal.equals(operatorStr)) {
|
||||
return buildEqualSpecification(field, filterNode);
|
||||
}
|
||||
@@ -251,6 +254,17 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为查询字段添加别名
|
||||
*
|
||||
* @param field
|
||||
* @param filterNode
|
||||
* @return
|
||||
*/
|
||||
protected String aliasFor(String field, JsonNode filterNode) {
|
||||
return field;
|
||||
}
|
||||
|
||||
private <X extends Comparable<? super X>> Specification<T> buildLessThanSpecification(String field,
|
||||
JsonNode filterNode) {
|
||||
JsonNode valueNode = filterNode.get(ParamConstant.KEY_VALUE);
|
||||
@@ -324,7 +338,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* 等于操作符的逻辑
|
||||
*
|
||||
*
|
||||
* @param field
|
||||
* @param filterNode
|
||||
* @return
|
||||
@@ -343,11 +357,29 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
path = path.get(segment);
|
||||
}
|
||||
Class<?> clz = path.getJavaType();
|
||||
if (IdentityEntity.class.isAssignableFrom(clz) && valueNode.isNumber()) {
|
||||
return cb.equal(path.get("id"), valueNode.asInt());
|
||||
if (IdentityEntity.class.isAssignableFrom(clz)) {
|
||||
if (valueNode.isNumber()) {
|
||||
return cb.equal(path.get("id"), valueNode.asInt());
|
||||
}
|
||||
|
||||
if (valueNode.isObject() && valueNode.has("id")) {
|
||||
JsonNode identity = valueNode.get("id");
|
||||
if (identity.isNumber()) {
|
||||
return cb.equal(path.get("id"), identity.asInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (clz == java.lang.Enum.class) {
|
||||
// 将字符串转换为对应的枚举值
|
||||
clz = ((SqmBasicValuedSimplePath) path).getExpressibleJavaType().getJavaTypeClass();
|
||||
}
|
||||
ObjectMapper objectMapper = SpringApp.getBean(ObjectMapper.class);
|
||||
Object value = objectMapper.convertValue(valueNode, clz);
|
||||
Object value = null;
|
||||
try {
|
||||
value = objectMapper.convertValue(valueNode, clz);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("field=" + field + ", clz=" + clz.getName() + ", value=" + valueNode, e);
|
||||
}
|
||||
// Object value = valueNode.isTextual() ? valueNode.asText()
|
||||
// : valueNode.isNumber() ? valueNode.numberValue()
|
||||
// : valueNode.isBoolean() ? valueNode.asBoolean() : valueNode;
|
||||
@@ -357,7 +389,7 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
|
||||
/**
|
||||
* BETWEEN 操作符的逻辑
|
||||
*
|
||||
*
|
||||
* @param field
|
||||
* @param filterNode
|
||||
* @return
|
||||
@@ -366,16 +398,35 @@ public abstract class EntityService<T extends Voable<VO>, VO, ID> {
|
||||
JsonNode filterNode) {
|
||||
// BETWEEN 操作符:要求 value 为数组,且长度=2
|
||||
JsonNode valueNode = filterNode.get(ParamConstant.KEY_VALUE);
|
||||
if (valueNode == null || !valueNode.isArray() || valueNode.size() != 2) {
|
||||
log.debug("BETWEEN 操作符需要 value 为包含两个元素的数组");
|
||||
return null;
|
||||
JsonNode lowNode, highNode;
|
||||
boolean includeBegin = false, includeEnd = false;
|
||||
if (valueNode == null || valueNode.isNull()) {
|
||||
throw new IllegalArgumentException(field + " 的 BETWEEN 操作符需要参数");
|
||||
}
|
||||
JsonNode lowNode = valueNode.get(0);
|
||||
JsonNode highNode = valueNode.get(1);
|
||||
if (valueNode.isArray()) {
|
||||
if (valueNode.size() != 2) {
|
||||
throw new IllegalArgumentException(field + " 的 BETWEEN 操作符的 value 数组长度必须为 2");
|
||||
}
|
||||
lowNode = valueNode.get(0);
|
||||
highNode = valueNode.get(1);
|
||||
} else if (valueNode.isObject()) {
|
||||
lowNode = valueNode.get(ParamConstant.KEY_between_begin);
|
||||
highNode = valueNode.get(ParamConstant.KEY_between_end);
|
||||
|
||||
if (valueNode.has(ParamConstant.KEY_INCLUDE_BEGIN)) {
|
||||
includeBegin = valueNode.get(ParamConstant.KEY_INCLUDE_BEGIN).asBoolean();
|
||||
}
|
||||
if (valueNode.has(ParamConstant.KEY_INCLUDE_END)) {
|
||||
includeEnd = valueNode.get(ParamConstant.KEY_INCLUDE_END).asBoolean();
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(field + " 的 BETWEEN 操作符的 value 必须为数组或对象");
|
||||
}
|
||||
|
||||
if (lowNode == null || highNode == null || lowNode.isNull() || highNode.isNull()) {
|
||||
log.debug("BETWEEN 操作符的 value 数组元素不能为空");
|
||||
return null;
|
||||
throw new IllegalArgumentException(field + " 的 BETWEEN 操作符的 value 数组元素不能为空");
|
||||
}
|
||||
|
||||
return (root, query, cb) -> {
|
||||
// 支持嵌套属性路径,如 company.id
|
||||
String[] fieldPath = field.split("\\.");
|
||||
|
||||
Reference in New Issue
Block a user