commit:VO支持以及bug修复

This commit is contained in:
Jerry
2020-12-18 22:52:35 +08:00
parent ecec5ae30a
commit d86ae86f1c
558 changed files with 8019 additions and 10785 deletions

View File

@@ -1,8 +1,6 @@
package com.orange.demo.common.core.advice;
import com.orange.demo.common.core.exception.InvalidClassFieldException;
import com.orange.demo.common.core.exception.InvalidDataFieldException;
import com.orange.demo.common.core.exception.InvalidDataModelException;
import com.orange.demo.common.core.exception.*;
import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.exception.RedisCacheAccessException;
import com.orange.demo.common.core.object.ResponseResult;
@@ -113,6 +111,19 @@ public class MyExceptionHandler {
return ResponseResult.error(ErrorCodeEnum.DATA_ACCESS_FAILED);
}
/**
* 操作不存在或已逻辑删除数据的异常处理方法。
*
* @param ex 异常对象。
* @param request http请求。
* @return 应答对象。
*/
@ExceptionHandler(value = NoDataAffectException.class)
public ResponseResult<Void> noDataEffectExceptionHandle(Exception ex, HttpServletRequest request) {
log.error("NoDataAffectException exception from URL [" + request.getRequestURI() + "]", ex);
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
/**
* Redis缓存访问异常处理方法。
*

View File

@@ -1,9 +1,6 @@
package com.orange.demo.common.core.base.client;
import com.orange.demo.common.core.object.MyAggregationParam;
import com.orange.demo.common.core.object.MyQueryParam;
import com.orange.demo.common.core.object.ResponseResult;
import com.orange.demo.common.core.object.Tuple2;
import com.orange.demo.common.core.object.*;
import java.util.*;
@@ -11,11 +8,12 @@ import java.util.*;
* 远程调用接口。
*
* @param <D> 主DomainDto域数据对象类型。
* @param <V> 主DomainVo域数据对象类型。
* @param <K> 主键类型。
* @author Jerry
* @date 2020-08-08
*/
public interface BaseClient<D, K> {
public interface BaseClient<D, V, K> {
/**
* 基于主键的(in list)获取远程数据接口。
@@ -24,7 +22,7 @@ public interface BaseClient<D, K> {
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象集合。
*/
ResponseResult<List<D>> listByIds(Set<K> filterIds, Boolean withDict);
ResponseResult<List<V>> listByIds(Set<K> filterIds, Boolean withDict);
/**
* 基于主键Id获取远程对象。
@@ -33,7 +31,7 @@ public interface BaseClient<D, K> {
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象数据。
*/
ResponseResult<D> getById(K id, Boolean withDict);
ResponseResult<V> getById(K id, Boolean withDict);
/**
* 判断参数列表中指定的主键Id是否全部存在。
@@ -76,9 +74,9 @@ public interface BaseClient<D, K> {
* 缺省实现是因为字典类型的远程调用客户端中,不需要实现该方法,因此尽早抛出异常,用户可自行修改。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含主对象集合
* @return 分页数据集合对象。如MyQueryParam参数的分页属性为空则不会执行分页操作只是基于MyPageData对象返回数据结果
*/
default ResponseResult<List<D>> listBy(MyQueryParam queryParam) {
default ResponseResult<MyPageData<V>> listBy(MyQueryParam queryParam) {
throw new UnsupportedOperationException();
}
@@ -89,7 +87,7 @@ public interface BaseClient<D, K> {
* @param queryParam 查询参数。
* @return 应答结果对象,包含主对象集合。
*/
default ResponseResult<D> getBy(MyQueryParam queryParam) {
default ResponseResult<V> getBy(MyQueryParam queryParam) {
throw new UnsupportedOperationException();
}
@@ -98,9 +96,9 @@ public interface BaseClient<D, K> {
* 缺省实现是因为字典类型的远程调用客户端中,不需要实现该方法,因此尽早抛出异常,用户可自行修改。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含主对象集合
* @return 分页数据集合对象。如MyQueryParam参数的分页属性为空则不会执行分页操作只是基于MyPageData对象返回数据结果
*/
default ResponseResult<List<Map<String, Object>>> listMapBy(MyQueryParam queryParam) {
default ResponseResult<MyPageData<Map<String, Object>>> listMapBy(MyQueryParam queryParam) {
throw new UnsupportedOperationException();
}
@@ -130,9 +128,9 @@ public interface BaseClient<D, K> {
* 根据主键Id及其列表数据(not in list)进行过滤,返回给定的数据。返回的对象数据中,仅仅包含实体对象自己的数据,以及配置的字典关联数据。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含数据列表,以及整个符合条件的数据总量(分页之前)
* @return 应答结果对象,包含分页查询数据列表。
*/
default ResponseResult<Tuple2<List<D>, K>> listByNotInList(MyQueryParam queryParam) {
default ResponseResult<MyPageData<V>> listByNotInList(MyQueryParam queryParam) {
throw new UnsupportedOperationException();
}
}

View File

@@ -1,10 +1,7 @@
package com.orange.demo.common.core.base.client;
import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.object.MyAggregationParam;
import com.orange.demo.common.core.object.MyQueryParam;
import com.orange.demo.common.core.object.ResponseResult;
import com.orange.demo.common.core.object.Tuple2;
import com.orange.demo.common.core.object.*;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
@@ -13,23 +10,24 @@ import java.util.*;
/**
* FeignClient 熔断降级处理对象。
*
* @param <D> 实体对象类型。
* @param <D> 主DomainDto域数据对象类型。
* @param <V> 主DomainVo域数据对象类型。
* @param <K> 主键类型。
* @param <T> Feign客户端对象类型。
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public abstract class BaseFallbackFactory<D, K, T extends BaseClient<D, K>>
implements FallbackFactory<T>, BaseClient<D, K> {
public abstract class BaseFallbackFactory<D, V, K, T extends BaseClient<D, V, K>>
implements FallbackFactory<T>, BaseClient<D, V, K> {
@Override
public ResponseResult<List<D>> listByIds(Set<K> idSet, Boolean withDict) {
public ResponseResult<List<V>> listByIds(Set<K> idSet, Boolean withDict) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@Override
public ResponseResult<D> getById(K id, Boolean withDict) {
public ResponseResult<V> getById(K id, Boolean withDict) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@@ -54,17 +52,17 @@ public abstract class BaseFallbackFactory<D, K, T extends BaseClient<D, K>>
}
@Override
public ResponseResult<List<D>> listBy(MyQueryParam queryParam) {
public ResponseResult<MyPageData<V>> listBy(MyQueryParam queryParam) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@Override
public ResponseResult<D> getBy(MyQueryParam queryParam) {
public ResponseResult<V> getBy(MyQueryParam queryParam) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@Override
public ResponseResult<List<Map<String, Object>>> listMapBy(MyQueryParam queryParam) {
public ResponseResult<MyPageData<Map<String, Object>>> listMapBy(MyQueryParam queryParam) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@@ -79,7 +77,7 @@ public abstract class BaseFallbackFactory<D, K, T extends BaseClient<D, K>>
}
@Override
public ResponseResult<Tuple2<List<D>, K>> listByNotInList(MyQueryParam queryParam) {
public ResponseResult<MyPageData<V>> listByNotInList(MyQueryParam queryParam) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
}

View File

@@ -11,6 +11,7 @@ import com.orange.demo.common.core.exception.RemoteDataBuildException;
import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.util.MyCommonUtil;
import com.orange.demo.common.core.util.MyModelUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@@ -30,22 +31,22 @@ import java.util.stream.Collectors;
* 控制器Controller的基类。
*
* @param <M> 主Model实体对象类型。
* @param <D> 主DomainDto域对象类型。
* @param <V> 主Model的DomainVO域对象类型。
* @param <K> 主键类型。
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public abstract class BaseController<M, D, K> {
public abstract class BaseController<M, V, K> {
/**
* 当前Service关联的主Model实体对象的Class。
*/
protected Class<M> modelClass;
/**
* 当前Service关联的主DomainDto域对象的Class。
* 当前Service关联的主model的VO对象的Class。
*/
protected Class<D> domainDtoClass;
protected Class<V> domainVoClass;
/**
* 当前Service关联的主Model对象主键字段名称。
*/
@@ -56,7 +57,7 @@ public abstract class BaseController<M, D, K> {
*
* @return 子类中注入的BaseService类。
*/
protected abstract BaseService<M, D, K> service();
protected abstract BaseService<M, K> service();
/**
* 构造函数。
@@ -64,7 +65,7 @@ public abstract class BaseController<M, D, K> {
@SuppressWarnings("unchecked")
public BaseController() {
modelClass = (Class<M>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
domainDtoClass = (Class<D>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
domainVoClass = (Class<V>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
Field[] fields = ReflectUtil.getFields(modelClass);
for (Field field : fields) {
if (null != field.getAnnotation(Id.class)) {
@@ -83,21 +84,21 @@ public abstract class BaseController<M, D, K> {
* @return 应答结果对象,包含主对象集合。
* @throws RemoteDataBuildException buildRelationForDataList会抛出该异常。
*/
public ResponseResult<List<D>> baseListByIds(
Set<K> filterIds, Boolean withDict, BaseModelMapper<D, M> modelMapper) {
public ResponseResult<List<V>> baseListByIds(
Set<K> filterIds, Boolean withDict, BaseModelMapper<V, M> modelMapper) {
if (MyCommonUtil.existBlankArgument(filterIds, withDict)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
List<M> resultList = service().getInList(idFieldName, filterIds);
List<D> resultDtoList = null;
List<V> resultVoList = null;
if (CollectionUtils.isEmpty(resultList)) {
return ResponseResult.success(resultDtoList);
return ResponseResult.success(resultVoList);
}
if (Boolean.TRUE.equals(withDict)) {
service().buildRelationForDataList(resultList, MyRelationParam.dictOnly(), null);
}
resultDtoList = convertToDomainList(resultList, modelMapper);
return ResponseResult.success(resultDtoList);
resultVoList = convertToVoList(resultList, modelMapper);
return ResponseResult.success(resultVoList);
}
/**
@@ -109,20 +110,20 @@ public abstract class BaseController<M, D, K> {
* @return 应答结果对象,包含主对象数据。
* @throws RemoteDataBuildException buildRelationForData会抛出此异常。
*/
public ResponseResult<D> baseGetById(K id, Boolean withDict, BaseModelMapper<D, M> modelMapper) {
public ResponseResult<V> baseGetById(K id, Boolean withDict, BaseModelMapper<V, M> modelMapper) {
if (MyCommonUtil.existBlankArgument(id, withDict)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
M resultObject = service().getById(id);
D resultDtoObject = null;
V resultVoObject = null;
if (resultObject == null) {
return ResponseResult.success(resultDtoObject);
return ResponseResult.success(resultVoObject);
}
if (Boolean.TRUE.equals(withDict)) {
service().buildRelationForData(resultObject, MyRelationParam.dictOnly(), null);
}
resultDtoObject = this.convertToDomain(resultObject, modelMapper);
return ResponseResult.success(resultDtoObject);
resultVoObject = this.convertToVo(resultObject, modelMapper);
return ResponseResult.success(resultVoObject);
}
/**
@@ -150,13 +151,11 @@ public abstract class BaseController<M, D, K> {
/**
* 删除符合过滤条件的数据。
*
* @param filter 过滤对象。
* @param modelMapper 对象映射函数对象。如果为空则使用MyModelUtil中的缺省转换函数。
* @param filter 过滤对象。
* @return 删除数量。
*/
public ResponseResult<Integer> baseDeleteBy(
D filter, BaseModelMapper<D, M> modelMapper) throws Exception {
return ResponseResult.success(service().removeBy(convertToModel(filter, modelMapper)));
public ResponseResult<Integer> baseDeleteBy(M filter) throws Exception {
return ResponseResult.success(service().removeBy(filter));
}
/**
@@ -165,10 +164,10 @@ public abstract class BaseController<M, D, K> {
*
* @param queryParam 查询参数。
* @param modelMapper 对象映射函数对象。如果为空则使用MyModelUtil中的缺省转换函数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果
* @return 分页数据集合对象。如MyQueryParam参数的分页属性为空则不会执行分页操作只是基于MyPageData对象返回数据结果。
* @throws RemoteDataBuildException buildRelationForDataList会抛出此异常。
*/
public ResponseResult<List<D>> baseListBy(MyQueryParam queryParam, BaseModelMapper<D, M> modelMapper) {
public ResponseResult<MyPageData<V>> baseListBy(MyQueryParam queryParam, BaseModelMapper<V, M> modelMapper) {
if (CollectionUtils.isNotEmpty(queryParam.getSelectFieldList())) {
for (String fieldName : queryParam.getSelectFieldList()) {
String columnName = MyModelUtil.mapToColumnName(fieldName, modelClass);
@@ -179,22 +178,29 @@ public abstract class BaseController<M, D, K> {
}
}
}
M filter = queryParam.getFilterDto(modelClass);
String whereClause = MyWhereCriteria.makeCriteriaString(queryParam.getCriteriaList(), modelClass);
String orderBy = MyOrderParam.buildOrderBy(queryParam.getOrderParam(), modelClass);
MyPageParam pageParam = queryParam.getPageParam();
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
List<M> resultList = service().getListByCondition(queryParam.getSelectFieldList(), whereClause, orderBy);
List<D> resultDtoList = null;
List<M> resultList = service().getListByCondition(
queryParam.getSelectFieldList(), filter, whereClause, orderBy);
if (CollectionUtils.isEmpty(resultList)) {
return ResponseResult.success(resultDtoList);
return ResponseResult.success(MyPageData.emptyPageData());
}
long totalCount;
if (resultList instanceof Page) {
totalCount = ((Page<M>) resultList).getTotal();
} else {
totalCount = resultList.size();
}
if (queryParam.getWithDict()) {
service().buildRelationForDataList(resultList, MyRelationParam.dictOnly(), null);
}
resultDtoList = convertToDomainList(resultList, modelMapper);
return ResponseResult.success(resultDtoList);
List<V> resultVoList = convertToVoList(resultList, modelMapper);
return ResponseResult.success(new MyPageData<>(resultVoList, totalCount));
}
/**
@@ -203,17 +209,17 @@ public abstract class BaseController<M, D, K> {
*
* @param queryParam 查询参数。
* @param modelMapper 对象映射函数对象。如果为空则使用MyModelUtil中的缺省转换函数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果
* @return 分页数据集合对象。如MyQueryParam参数的分页属性为空则不会执行分页操作只是基于MyPageData对象返回数据结果。
*/
public ResponseResult<List<Map<String, Object>>> baseListMapBy(
MyQueryParam queryParam, BaseModelMapper<D, M> modelMapper) {
ResponseResult<List<D>> result = this.baseListBy(queryParam, modelMapper);
public ResponseResult<MyPageData<Map<String, Object>>> baseListMapBy(
MyQueryParam queryParam, BaseModelMapper<V, M> modelMapper) {
ResponseResult<MyPageData<V>> result = this.baseListBy(queryParam, modelMapper);
if (!result.isSuccess()) {
return ResponseResult.errorFrom(result);
}
List<Map<String, Object>> resultMapList =
result.getData().stream().map(BeanUtil::beanToMap).collect(Collectors.toList());
return ResponseResult.success(resultMapList);
result.getData().getDataList().stream().map(BeanUtil::beanToMap).collect(Collectors.toList());
return ResponseResult.success(new MyPageData<>(resultMapList, result.getData().getTotalCount()));
}
/**
@@ -223,13 +229,13 @@ public abstract class BaseController<M, D, K> {
* @param modelMapper 对象映射函数对象。如果为空则使用MyModelUtil中的缺省转换函数。
* @return 应答结果对象,包含符合查询过滤条件的单条实体对象。
*/
public ResponseResult<D> baseGetBy(MyQueryParam queryParam, BaseModelMapper<D, M> modelMapper) {
ResponseResult<List<D>> result = baseListBy(queryParam, modelMapper);
public ResponseResult<V> baseGetBy(MyQueryParam queryParam, BaseModelMapper<V, M> modelMapper) {
ResponseResult<MyPageData<V>> result = baseListBy(queryParam, modelMapper);
if (!result.isSuccess()) {
return ResponseResult.errorFrom(result);
}
List<D> dataList = result.getData();
D data = null;
List<V> dataList = result.getData().getDataList();
V data = null;
if (CollectionUtils.isNotEmpty(dataList)) {
data = dataList.get(0);
}
@@ -310,77 +316,39 @@ public abstract class BaseController<M, D, K> {
}
/**
* 将查询对象中过滤域对象转换为实体对象。以便作为Service的参数进行数据过滤
* 如果Model存在该实体的ModelMapper就用该ModelMapper转换否则使用缺省的基于字段反射的copy。
*
* @param filterDto 过滤域对象。
* @param modelMapper 从Dto对象到实体对象的映射对象。
* @return 转换后的实体过滤对象。
*/
public M convertFilter(D filterDto, BaseModelMapper<D, M> modelMapper) {
M filter = null;
if (filterDto != null) {
if (modelMapper != null) {
filter = modelMapper.toModel(filterDto);
} else {
filter = MyModelUtil.copyTo(filterDto, modelClass);
}
}
return filter;
}
/**
* 将Model实体对象的集合转换为DomainDto域对象的集合。
* 将Model实体对象的集合转换为DomainVO域对象的集合
* 如果Model存在该实体的ModelMapper就用该ModelMapper转换否则使用缺省的基于字段反射的copy。
*
* @param modelList 实体对象列表。
* @param modelMapper 从实体对象到Dto对象的映射对象。
* @return 转换后的Dto域对象列表。
* @param modelMapper 从实体对象到VO对象的映射对象。
* @return 转换后的VO域对象列表。
*/
private List<D> convertToDomainList(List<M> modelList, BaseModelMapper<D, M> modelMapper) {
List<D> resultDtoList;
private List<V> convertToVoList(List<M> modelList, BaseModelMapper<V, M> modelMapper) {
List<V> resultVoList;
if (modelMapper != null) {
resultDtoList = modelMapper.fromModelList(modelList);
resultVoList = modelMapper.fromModelList(modelList);
} else {
resultDtoList = MyModelUtil.copyCollectionTo(modelList, domainDtoClass);
resultVoList = MyModelUtil.copyCollectionTo(modelList, domainVoClass);
}
return resultDtoList;
return resultVoList;
}
/**
* 将Model实体对象转换为DomainDto域对象。
* 将Model实体对象转换为DomainVO域对象。
* 如果Model存在该实体的ModelMapper就用该ModelMapper转换否则使用缺省的基于字段反射的copy。
*
* @param model 实体对象。
* @param modelMapper 从实体对象到Dto对象的映射对象。
* @return 转换后的Dto域对象。
* @param modelMapper 从实体对象到VO对象的映射对象。
* @return 转换后的VO域对象。
*/
private D convertToDomain(M model, BaseModelMapper<D, M> modelMapper) {
D resultDto;
private V convertToVo(M model, BaseModelMapper<V, M> modelMapper) {
V resultVo;
if (modelMapper != null) {
resultDto = modelMapper.fromModel(model);
resultVo = modelMapper.fromModel(model);
} else {
resultDto = MyModelUtil.copyTo(model, domainDtoClass);
resultVo = MyModelUtil.copyTo(model, domainVoClass);
}
return resultDto;
}
/**
* 将Dto对象转换为Model实体对象。
* 如果Model存在该实体的ModelMapper就用该ModelMapper转换否则使用缺省的基于字段反射的copy。
*
* @param dto Dto对象。
* @param modelMapper 从实体对象到Dto对象的映射对象。
* @return 转换后的Dto域对象。
*/
private M convertToModel(D dto, BaseModelMapper<D, M> modelMapper) {
M result;
if (modelMapper != null) {
result = modelMapper.toModel(dto);
} else {
result = MyModelUtil.copyTo(dto, modelClass);
}
return result;
return resultVo;
}
private VerifyAggregationInfo verifyAndParseAggregationParam(MyAggregationParam param) {

View File

@@ -14,13 +14,12 @@ import java.util.List;
* 目前仅支持基于主键字段的缓存查找,其他条件的查找仍然从数据源获取。
*
* @param <M> Model实体对象的类型。
* @param <D> Model对应的DomainDto域对象类型。
* @param <K> Model对象主键的类型。
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public abstract class BaseDictService<M, D, K> extends BaseService<M, D, K> {
public abstract class BaseDictService<M, K> extends BaseService<M, K> {
/**
* 缓存池对象。
@@ -126,7 +125,7 @@ public abstract class BaseDictService<M, D, K> extends BaseService<M, D, K> {
@SuppressWarnings("unchecked")
public <T> boolean existUniqueKeyList(String inFilterField, Set<T> inFilterValues) {
if (CollectionUtils.isEmpty(inFilterValues)) {
return false;
return true;
}
if (inFilterField.equals(this.idFieldName)) {
List<M> dataList = dictionaryCache.getInList((Set<K>) inFilterValues);

View File

@@ -25,6 +25,7 @@ import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.lang.reflect.Modifier;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
@@ -37,22 +38,17 @@ import static java.util.stream.Collectors.*;
* 所有Service的基类。
*
* @param <M> Model对象的类型。
* @param <D> Model对应的Dto对象类型。
* @param <K> Model对象主键的类型。
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public abstract class BaseService<M, D, K> {
public abstract class BaseService<M, K> {
/**
* 当前Service关联的主Model实体对象的Class。
*/
protected Class<M> modelClass;
/**
* 当前Service关联的主DomainDto域对象的Class。
*/
protected Class<D> domainDtoClass;
/**
* 当前Service关联的主Model对象的实际表名称。
*/
@@ -142,7 +138,6 @@ public abstract class BaseService<M, D, K> {
@SuppressWarnings("unchecked")
public BaseService() {
modelClass = (Class<M>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
domainDtoClass = (Class<D>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
this.tableName = modelClass.getAnnotation(Table.class).name();
Field[] fields = ReflectUtil.getFields(modelClass);
for (Field field : fields) {
@@ -239,7 +234,7 @@ public abstract class BaseService<M, D, K> {
}
Example e = new Example(modelClass);
e.createCriteria().andEqualTo(fieldName, fieldValue);
return mapper().selectByExample(e).size() == 1;
return mapper().selectCountByExample(e) == 1;
}
/**
@@ -325,7 +320,7 @@ public abstract class BaseService<M, D, K> {
*/
public boolean existAllPrimaryKeys(Set<K> idSet) {
if (CollectionUtils.isEmpty(idSet)) {
return false;
return true;
}
return this.existUniqueKeyList(idFieldName, idSet);
}
@@ -339,7 +334,7 @@ public abstract class BaseService<M, D, K> {
*/
public <T> boolean existUniqueKeyList(String inFilterField, Set<T> inFilterValues) {
if (CollectionUtils.isEmpty(inFilterValues)) {
return false;
return true;
}
Example e = this.makeDefaultInListExample(inFilterField, inFilterValues, null);
if (deletedFlagFieldName != null) {
@@ -513,20 +508,21 @@ public abstract class BaseService<M, D, K> {
int modifiers = field.getModifiers();
// transient类型的字段不能作为查询条件
int transientMask = 128;
if ((modifiers & transientMask) == 0) {
if (field.getName().equals(deletedFlagFieldName)) {
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
} else {
ReflectUtil.setAccessible(field);
try {
Object o = field.get(filter);
if (o != null) {
c.andEqualTo(field.getName(), field.get(filter));
}
} catch (IllegalAccessException ex) {
log.error("Failed to call reflection code of BaseService.getListByFilter.", ex);
throw new MyRuntimeException(ex);
if ((modifiers & transientMask) != 0 || Modifier.isStatic(modifiers)) {
return;
}
if (field.getName().equals(deletedFlagFieldName)) {
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
} else {
ReflectUtil.setAccessible(field);
try {
Object o = field.get(filter);
if (o != null) {
c.andEqualTo(field.getName(), field.get(filter));
}
} catch (IllegalAccessException ex) {
log.error("Failed to call reflection code of BaseService.getListByFilter.", ex);
throw new MyRuntimeException(ex);
}
}
}
@@ -556,10 +552,14 @@ public abstract class BaseService<M, D, K> {
*/
public List<M> getListByParentId(String parentIdFieldName, K parentId) {
Example e = new Example(modelClass);
Example.Criteria c = e.createCriteria();
if (parentId != null) {
e.createCriteria().andEqualTo(parentIdFieldName, parentId);
c.andEqualTo(parentIdFieldName, parentId);
} else {
e.createCriteria().andIsNull(parentIdFieldName);
c.andIsNull(parentIdFieldName);
}
if (deletedFlagFieldName != null) {
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
}
return mapper().selectByExample(e);
}
@@ -583,12 +583,14 @@ public abstract class BaseService<M, D, K> {
* 根据指定的显示字段列表、过滤条件字符串和排序字符串,返回查询结果。(基本是内部框架使用,不建议外部接口直接使用)。
*
* @param selectList 选择的Java字段列表。如果为空表示返回全部字段。
* @param filter 过滤对象。
* @param whereClause SQL常量形式的条件从句。
* @param orderBy SQL常量形式排序字段列表逗号分隔。
* @return 查询结果。
*/
public List<M> getListByCondition(List<String> selectList, String whereClause, String orderBy) {
public List<M> getListByCondition(List<String> selectList, M filter, String whereClause, String orderBy) {
Example e = new Example(modelClass);
Example.Criteria c = null;
if (CollectionUtils.isNotEmpty(selectList)) {
String[] selectFields = new String[selectList.size()];
selectList.toArray(selectFields);
@@ -597,8 +599,20 @@ public abstract class BaseService<M, D, K> {
if (StringUtils.isNotBlank(orderBy)) {
e.setOrderByClause(orderBy);
}
if (filter != null) {
c = e.createCriteria();
Field[] fields = ReflectUtil.getFields(modelClass);
for (Field field : fields) {
if (field.getAnnotation(Transient.class) == null) {
this.assembleCriteriaByFilter(filter, field, c);
}
}
}
if (StringUtils.isNotBlank(whereClause)) {
e.createCriteria().andCondition(whereClause);
if (c == null) {
c = e.createCriteria();
}
c.andCondition(whereClause);
}
return mapper().selectByExample(e);
}
@@ -811,9 +825,9 @@ public abstract class BaseService<M, D, K> {
whereCriteria.setCriteria(
relationStruct.relationOneToOne.slaveIdField(), MyWhereCriteria.OPERATOR_IN, masterIdSet);
queryParam.addCriteriaList(whereCriteria);
ResponseResult<List<Object>> result = relationStruct.remoteClient.listBy(queryParam);
ResponseResult<MyPageData<Object>> result = relationStruct.remoteClient.listBy(queryParam);
if (result.isSuccess()) {
List<Object> relationList = result.getData();
List<Object> relationList = result.getData().getDataList();
MyModelUtil.makeOneToOneRelation(
modelClass, resultList, relationList, relationStruct.relationField.getName());
} else {
@@ -889,10 +903,10 @@ public abstract class BaseService<M, D, K> {
whereCriteria.setCriteria(
relationStruct.relationDict.slaveIdField(), MyWhereCriteria.OPERATOR_IN, masterIdSet);
queryParam.addCriteriaList(whereCriteria);
ResponseResult<List<Object>> result = relationStruct.remoteClient.listBy(queryParam);
ResponseResult<MyPageData<Object>> result = relationStruct.remoteClient.listBy(queryParam);
// 成功或者没有数据
if (result.isSuccess()) {
relationList = result.getData();
relationList = result.getData().getDataList();
} else {
logErrorOrThrowException(result.getErrorMessage());
}
@@ -1135,7 +1149,7 @@ public abstract class BaseService<M, D, K> {
if (CollectionUtils.isEmpty(masterIdSet)) {
continue;
}
BaseService<Object, Object, Object> relationService = relationStruct.localService;
BaseService<Object, Object> relationService = relationStruct.localService;
List<Object> relationList =
relationService.getInList(relationStruct.relationOneToOne.slaveIdField(), masterIdSet);
MyModelUtil.makeOneToOneRelation(
@@ -1144,8 +1158,8 @@ public abstract class BaseService<M, D, K> {
if (withDict && relationStruct.relationOneToOne.loadSlaveDict()
&& CollectionUtils.isNotEmpty(relationList)) {
@SuppressWarnings("unchecked")
BaseService<Object, Object, Object> proxyTarget =
(BaseService<Object, Object, Object>) AopTargetUtil.getTarget(relationService);
BaseService<Object, Object> proxyTarget =
(BaseService<Object, Object>) AopTargetUtil.getTarget(relationService);
// 关联常量字典
proxyTarget.buildConstDictForDataList(relationList);
// 关联本地字典。
@@ -1170,14 +1184,14 @@ public abstract class BaseService<M, D, K> {
for (LocalRelationStruct relationStruct : this.localRelationOneToOneStructList) {
Object id = ReflectUtil.getFieldValue(dataObject, relationStruct.masterIdField);
if (id != null) {
BaseService<Object, Object, Object> relationService = relationStruct.localService;
BaseService<Object, Object> relationService = relationStruct.localService;
Object relationObject = relationService.getById(id);
ReflectUtil.setFieldValue(dataObject, relationStruct.relationField, relationObject);
// 仅仅当需要加载从表字典关联时,才去加载。
if (withDict && relationStruct.relationOneToOne.loadSlaveDict() && relationObject != null) {
@SuppressWarnings("unchecked")
BaseService<Object, Object, Object> proxyTarget =
(BaseService<Object, Object, Object>) AopTargetUtil.getTarget(relationService);
BaseService<Object, Object> proxyTarget =
(BaseService<Object, Object>) AopTargetUtil.getTarget(relationService);
// 关联常量字典
proxyTarget.buildConstDictForData(relationObject);
// 关联本地字典。
@@ -1573,7 +1587,7 @@ public abstract class BaseService<M, D, K> {
ReflectUtil.getField(modelClass, relationDict.equalOneToOneRelationField());
}
Object client = ApplicationContextHolder.getBean(relationDict.slaveClientClass());
relationStruct.remoteClient = (BaseClient<Object, Object>) client;
relationStruct.remoteClient = (BaseClient<Object, Object, Object>) client;
remoteRelationDictStructList.add(relationStruct);
}
}
@@ -1590,7 +1604,7 @@ public abstract class BaseService<M, D, K> {
relationStruct.masterIdField = ReflectUtil.getField(modelClass, relationOneToOne.masterIdField());
relationStruct.relationOneToOne = relationOneToOne;
Object client = ApplicationContextHolder.getBean(relationOneToOne.slaveClientClass());
relationStruct.remoteClient = (BaseClient<Object, Object>) client;
relationStruct.remoteClient = (BaseClient<Object, Object, Object>) client;
remoteRelationOneToOneStructList.add(relationStruct);
}
}
@@ -1608,7 +1622,7 @@ public abstract class BaseService<M, D, K> {
relationStruct.masterIdField = ReflectUtil.getField(modelClass, relationOneToManyAggregation.masterIdField());
relationStruct.relationOneToManyAggregation = relationOneToManyAggregation;
Object client = ApplicationContextHolder.getBean(relationOneToManyAggregation.slaveClientClass());
relationStruct.remoteClient = (BaseClient<Object, Object>) client;
relationStruct.remoteClient = (BaseClient<Object, Object, Object>) client;
remoteRelationOneToManyAggrStructList.add(relationStruct);
return;
}
@@ -1624,7 +1638,7 @@ public abstract class BaseService<M, D, K> {
modelClass, relationManyToManyAggregation.masterIdField());
relationStruct.relationManyToManyAggregation = relationManyToManyAggregation;
Object client = ApplicationContextHolder.getBean(relationManyToManyAggregation.slaveClientClass());
relationStruct.remoteClient = (BaseClient<Object, Object>) client;
relationStruct.remoteClient = (BaseClient<Object, Object, Object>) client;
remoteRelationManyToManyAggrStructList.add(relationStruct);
}
}
@@ -1856,7 +1870,7 @@ public abstract class BaseService<M, D, K> {
List<String> slaveSelectList = new LinkedList<>();
slaveSelectList.add(relation.slaveIdField());
queryParam.setSelectFieldList(slaveSelectList);
ResponseResult<List<Map<String, Object>>> result = relationStruct.remoteClient.listMapBy(queryParam);
ResponseResult<MyPageData<Map<String, Object>>> result = relationStruct.remoteClient.listMapBy(queryParam);
if (!result.isSuccess()) {
this.logErrorOrThrowException(result.getErrorMessage());
return;
@@ -1865,7 +1879,8 @@ public abstract class BaseService<M, D, K> {
// 并计算最终聚合结果。
List<Object> slaveList = null;
if (result.getData() != null) {
slaveList = result.getData().stream().map(m -> m.get(relation.slaveIdField())).collect(toList());
slaveList = result.getData().getDataList()
.stream().map(m -> m.get(relation.slaveIdField())).collect(toList());
}
if (CollectionUtils.isNotEmpty(slaveList)) {
// 中间表的最终过滤条件是从表返回的id列表将作为关联表slaveIdColumn的inlist-filter
@@ -2101,7 +2116,7 @@ public abstract class BaseService<M, D, K> {
static class LocalRelationStruct extends RelationStruct {
private Field equalOneToOneRelationField;
private BaseService<Object, Object, Object> localService;
private BaseService<Object, Object> localService;
private BaseDaoMapper<Object> manyToManyMapper;
private Map<Object, String> dictMap;
private RelationDict relationDict;
@@ -2113,7 +2128,7 @@ public abstract class BaseService<M, D, K> {
static class RemoteRelationStruct extends RelationStruct {
private Field equalOneToOneRelationField;
private BaseClient<Object, Object> remoteClient;
private BaseClient<Object, Object, Object> remoteClient;
private RelationDict relationDict;
private RelationOneToOne relationOneToOne;
private RelationOneToManyAggregation relationOneToManyAggregation;

View File

@@ -35,6 +35,9 @@ public enum ErrorCodeEnum {
INVALID_USERNAME_PASSWORD("用户名或密码错误,请重试!"),
INVALID_ACCESS_TOKEN("无效的用户访问令牌!"),
INVALID_USER_STATUS("用户状态错误,请刷新后重试!"),
INVALID_TENANT_CODE("指定的租户编码并不存在,请刷新后重试!"),
INVALID_TENANT_STATUS("当前租户为不可用状态,请刷新后重试!"),
INVALID_USER_TENANT("当前用户并不属于当前租户,请刷新后重试!"),
HAS_CHILDREN_DATA("数据验证失败,子数据存在,请刷新后重试!"),
DATA_VALIDATED_FAILED("数据验证失败,请核对!"),

View File

@@ -1,7 +1,10 @@
package com.orange.demo.common.core.object;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.LinkedList;
import java.util.List;
/**
@@ -11,6 +14,8 @@ import java.util.List;
* @date 2020-08-08
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MyPageData<T> {
/**
* 数据列表。
@@ -20,4 +25,12 @@ public class MyPageData<T> {
* 数据总数量。
*/
private Long totalCount;
/**
* 为了保持前端的数据格式兼容性,在没有数据的时候,需要返回空分页对象。
* @return 空分页对象。
*/
public static <T> MyPageData<T> emptyPageData() {
return new MyPageData<>(new LinkedList<>(), 0L);
}
}

View File

@@ -91,7 +91,7 @@ public class MyQueryParam {
if (filterMap == null) {
return null;
}
return BeanUtil.mapToBean(this.filterMap, filterClazz, true);
return BeanUtil.toBeanIgnoreError(this.filterMap, filterClazz);
}
/**

View File

@@ -19,6 +19,7 @@ import javax.persistence.Column;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@@ -427,6 +428,9 @@ public class MyModelUtil {
Function<R, Object> thatIdGetterFunc,
String thisRelationField,
boolean orderByThatList) {
if (CollectionUtils.isEmpty(thisModelList)) {
return;
}
Field thisTargetField = ReflectUtil.getField(thisClazz, thisRelationField);
boolean isMap = thisTargetField.getType().equals(Map.class);
if (orderByThatList) {
@@ -476,12 +480,12 @@ public class MyModelUtil {
Example.Criteria c = e.createCriteria();
Field[] fields = ReflectUtil.getFields(modelClass);
for (Field field : fields) {
if (field.getAnnotation(Transient.class) != null) {
continue;
}
int modifiers = field.getModifiers();
// transient类型的字段不能作为查询条件
if ((modifiers & 128) == 0) {
if (field.getAnnotation(Transient.class) == null) {
int modifiers = field.getModifiers();
// transient类型的字段不能作为查询条件
if ((modifiers & 128) != 0 || Modifier.isStatic(modifiers)) {
continue;
}
ReflectUtil.setAccessible(field);
try {
Object o = field.get(filterModel);

View File

@@ -2,11 +2,11 @@ package com.orange.demo.common.core.util;
import cn.jimmyshi.beanquery.BeanQuery;
import com.alibaba.fastjson.JSONObject;
import com.orange.demo.common.core.object.MyPageData;
import com.github.pagehelper.Page;
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
import com.orange.demo.common.core.object.Tuple2;
import org.apache.commons.collections4.CollectionUtils;
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
import com.orange.demo.common.core.object.MyPageData;
import com.orange.demo.common.core.object.Tuple2;
import java.util.List;
@@ -75,18 +75,17 @@ public class MyPageUtil {
* 用户构建带有分页信息的数据列表。
*
* @param dataList 实体对象数据列表。
* @param modelMapper 实体对象到Dto对象的数据映射器。
* @param <D> Dto对象类型。
* @param modelMapper 实体对象到DomainVO对象的数据映射器。
* @param <D> DomainVO对象类型。
* @param <T> 实体对象类型。
* @return 返回分页数据对象。
*/
public static <D, T> MyPageData<D> makeResponseData(List<T> dataList, BaseModelMapper<D, T> modelMapper) {
MyPageData<D> pageData = new MyPageData<>();
long totalCount = 0L;
if (CollectionUtils.isEmpty(dataList)) {
// 这里需要构建分页数据对象,统一前端数据格式
return pageData;
return MyPageData.emptyPageData();
}
long totalCount = 0L;
if (dataList instanceof Page) {
totalCount = ((Page<T>) dataList).getTotal();
}

View File

@@ -63,10 +63,12 @@ public class SessionCacheHelper {
/**
* 清除当前session的所有缓存数据。
*
* @param sessionId 当前会话的SessionId。
*/
public void removeAllSessionCache() {
public void removeAllSessionCache(String sessionId) {
for (RedissonCacheConfig.CacheEnum c : RedissonCacheConfig.CacheEnum.values()) {
cacheManager.getCache(c.name()).clear();
cacheManager.getCache(c.name()).evict(sessionId);
}
}
}

View File

@@ -1,231 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-micro-spring-boot-starter:2.0.5" level="project" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-autoconfigure:2.0.5" level="project" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring:2.0.5" level="project" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-annotations:2.0.5" level="project" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-core:2.0.5" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.25.0-GA" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.22" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.22" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-core:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.9.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.4.5" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.74" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.8.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.1.0" level="project" />
<orderEntry type="library" name="Maven: cn.jimmyshi:bean-query:1.1.5" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-all:1.3" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:8.0.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.22" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.2.13" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.2.13" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.1.11" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
<orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-log4j2:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.12.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-core:2.12.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-jul:2.12.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-actuator:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.2" level="project" />
<orderEntry type="library" name="Maven: io.micrometer:micrometer-core:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.hdrhistogram:HdrHistogram:2.1.11" level="project" />
<orderEntry type="library" name="Maven: org.latencyutils:LatencyUtils:2.0.3" level="project" />
<orderEntry type="library" name="Maven: de.codecentric:spring-boot-admin-starter-client:2.2.3" level="project" />
<orderEntry type="library" name="Maven: de.codecentric:spring-boot-admin-client:2.2.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2.2.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.spring:spring-context-support:1.0.6" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-client:1.2.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-common:1.2.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-api:1.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient:0.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.59" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.59" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:10.7.4" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:10.7.4" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-hystrix:10.7.4" level="project" />
<orderEntry type="library" name="Maven: com.netflix.archaius:archaius-core:0.7.6" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-httpclient:10.7.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.13" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-netflix-hystrix:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-netflix-hystrix:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-netflix-ribbon:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-netflix-archaius:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-netflix-archaius:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: commons-configuration:commons-configuration:1.8" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" name="Maven: com.netflix.hystrix:hystrix-core:1.5.18" level="project" />
<orderEntry type="library" name="Maven: io.reactivex:rxjava:1.3.8" level="project" />
<orderEntry type="library" name="Maven: com.netflix.hystrix:hystrix-serialization:1.5.18" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.fasterxml.jackson.module:jackson-module-afterburner:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.netflix.hystrix:hystrix-metrics-event-stream:1.5.18" level="project" />
<orderEntry type="library" name="Maven: com.netflix.hystrix:hystrix-javanica:1.5.18" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" name="Maven: io.reactivex:rxjava-reactive-streams:1.2.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.3.1.Final" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.mapstruct:mapstruct-processor:1.3.1.Final" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.12" level="project" />
<orderEntry type="library" name="Maven: org.apache.curator:curator-recipes:4.3.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.curator:curator-framework:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.curator:curator-client:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.zookeeper:zookeeper:3.5.3-beta" level="project" />
<orderEntry type="library" name="Maven: commons-cli:commons-cli:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.kafka:kafka-clients:2.4.0" level="project" />
<orderEntry type="library" name="Maven: com.github.luben:zstd-jni:1.4.3-1" level="project" />
<orderEntry type="library" name="Maven: org.lz4:lz4-java:1.6.0" level="project" />
<orderEntry type="library" name="Maven: org.xerial.snappy:snappy-java:1.1.7.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.scala-lang:scala-library:2.12.10" level="project" />
<orderEntry type="library" name="Maven: com.lmax:disruptor:3.4.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.2.5.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.2.5.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.vintage:junit-vintage-engine:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:3.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.13.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest:2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:3.1.0" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.8" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.10.8" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.2.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.3" level="project" />
</component>
</module>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common</artifactId>
<groupId>com.orange.demo</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-swagger</artifactId>
<version>1.0.0</version>
<name>common-swagger</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>com.orange.demo</groupId>
<artifactId>common-core</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>

View File

@@ -1,44 +0,0 @@
package com.orange.demo.common.swagger.config;
import com.orange.demo.common.core.annotation.MyRequestBody;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* 自动加载bean的配置对象。
*
* @author Jerry
* @date 2020-08-08
*/
@EnableSwagger2
@EnableKnife4j
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "swagger", name = "enabled")
public class SwaggerAutoConfiguration {
@Bean
public Docket rotbotDocket(SwaggerProperties properties) {
return new Docket(DocumentationType.SWAGGER_2)
.ignoredParameterTypes(MyRequestBody.class)
.apiInfo(apiInfo(properties))
.select()
.apis(RequestHandlerSelectors.basePackage(properties.getBasePackage()))
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo(SwaggerProperties properties) {
return new ApiInfoBuilder()
.title(properties.getTitle())
.description(properties.getDescription())
.version(properties.getVersion()).build();
}
}

View File

@@ -1,40 +0,0 @@
package com.orange.demo.common.swagger.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 配置参数对象。
*
* @author Jerry
* @date 2020-08-08
*/
@Data
@ConfigurationProperties("swagger")
public class SwaggerProperties {
/**
* 是否开启Swagger。
*/
private Boolean enabled;
/**
* Swagger解析的基础包路径。
**/
private String basePackage = "";
/**
* ApiInfo中的标题。
**/
private String title = "";
/**
* ApiInfo中的描述信息。
**/
private String description = "";
/**
* ApiInfo中的版本信息。
**/
private String version = "";
}

View File

@@ -1,85 +0,0 @@
package com.orange.demo.common.swagger.plugin;
import cn.hutool.core.lang.Assert;
import com.orange.demo.common.core.annotation.MyRequestBody;
import com.github.xiaoymin.knife4j.core.conf.Consts;
import javassist.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import springfox.documentation.service.ResolvedMethodParameter;
import java.util.List;
/**
* 通过字节码方式动态创建接口参数封装对象。
*
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public class ByteBodyUtils {
private static final ClassPool CLASS_POOL = ClassPool.getDefault();
public static Class<?> createDynamicModelClass(String name, List<ResolvedMethodParameter> parameters) {
String clazzName = Consts.BASE_PACKAGE_PREFIX + name;
try {
CtClass tmp = CLASS_POOL.getCtClass(clazzName);
if (tmp != null) {
tmp.detach();
}
} catch (NotFoundException e) {
// 需要吃掉这个异常。
}
CtClass ctClass = CLASS_POOL.makeClass(clazzName);
try {
int fieldCount = 0;
for (ResolvedMethodParameter dynamicParameter : parameters) {
// 因为在调用这个方法之前这些参数都包含MyRequestBody注解。
MyRequestBody myRequestBody =
dynamicParameter.findAnnotation(MyRequestBody.class).orNull();
Assert.notNull(myRequestBody);
String fieldName = dynamicParameter.defaultName().isPresent()
? dynamicParameter.defaultName().get() : "parameter";
if (StringUtils.isNotBlank(myRequestBody.value())) {
fieldName = myRequestBody.value();
}
ctClass.addField(createField(dynamicParameter, fieldName, ctClass));
fieldCount++;
}
if (fieldCount > 0) {
return ctClass.toClass();
}
} catch (Throwable e) {
log.error(e.getMessage());
}
return null;
}
private static CtField createField(ResolvedMethodParameter parameter, String parameterName, CtClass ctClass)
throws NotFoundException, CannotCompileException {
CtField field = new CtField(getFieldType(parameter.getParameterType().getErasedType()), parameterName, ctClass);
field.setModifiers(Modifier.PUBLIC);
return field;
}
private static CtClass getFieldType(Class<?> propetyType) {
CtClass fieldType = null;
try {
if (!propetyType.isAssignableFrom(Void.class)) {
fieldType = CLASS_POOL.get(propetyType.getName());
} else {
fieldType = CLASS_POOL.get(String.class.getName());
}
} catch (NotFoundException e) {
// 抛异常
ClassClassPath path = new ClassClassPath(propetyType);
CLASS_POOL.insertClassPath(path);
try {
fieldType = CLASS_POOL.get(propetyType.getName());
} catch (NotFoundException e1) {
log.error(e1.getMessage(), e1);
}
}
return fieldType;
}
}

View File

@@ -1,61 +0,0 @@
package com.orange.demo.common.swagger.plugin;
import com.orange.demo.common.core.annotation.MyRequestBody;
import com.fasterxml.classmate.TypeResolver;
import com.google.common.base.CaseFormat;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationModelsProviderPlugin;
import springfox.documentation.spi.service.contexts.RequestMappingContext;
import java.util.List;
import java.util.stream.Collectors;
/**
* 生成参数包装类的插件。
*
* @author Jerry
* @date 2020-08-08
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 200)
@ConditionalOnProperty(prefix = "swagger", name = "enabled")
public class DynamicBodyModelPlugin implements OperationModelsProviderPlugin {
private final TypeResolver typeResolver;
public DynamicBodyModelPlugin(TypeResolver typeResolver) {
this.typeResolver = typeResolver;
}
@Override
public void apply(RequestMappingContext context) {
List<ResolvedMethodParameter> parameterTypes = context.getParameters();
if (CollectionUtils.isEmpty(parameterTypes)) {
return;
}
List<ResolvedMethodParameter> bodyParameter = parameterTypes.stream()
.filter(p -> p.hasParameterAnnotation(MyRequestBody.class)).collect(Collectors.toList());
if (CollectionUtils.isEmpty(bodyParameter)) {
return;
}
String groupName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, context.getGroupName());
String clazzName = groupName + StringUtils.capitalize(context.getName());
Class<?> clazz = ByteBodyUtils.createDynamicModelClass(clazzName, bodyParameter);
if (clazz != null) {
context.operationModelsBuilder().addInputParam(typeResolver.resolve(clazz));
}
}
@Override
public boolean supports(DocumentationType delimiter) {
// 支持2.0版本
return delimiter == DocumentationType.SWAGGER_2;
}
}

View File

@@ -1,64 +0,0 @@
package com.orange.demo.common.swagger.plugin;
import com.orange.demo.common.core.annotation.MyRequestBody;
import com.google.common.base.CaseFormat;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.Parameter;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spi.service.contexts.ParameterContext;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 构建操作接口参数对象的插件。
*
* @author Jerry
* @date 2020-08-08
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 102)
@ConditionalOnProperty(prefix = "swagger", name = "enabled")
public class DynamicBodyParameterBuilder implements OperationBuilderPlugin {
@Override
public void apply(OperationContext context) {
List<ResolvedMethodParameter> methodParameters = context.getParameters();
List<Parameter> parameters = new ArrayList<>();
if (CollectionUtils.isNotEmpty(methodParameters)) {
List<ResolvedMethodParameter> bodyParameter = methodParameters.stream()
.filter(p -> p.hasParameterAnnotation(MyRequestBody.class)).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(bodyParameter)) {
// 构造model
String groupName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, context.getGroupName());
String clazzName = groupName + StringUtils.capitalize(context.getName());
ResolvedMethodParameter methodParameter = bodyParameter.get(0);
ParameterContext parameterContext = new ParameterContext(methodParameter,
new ParameterBuilder(),
context.getDocumentationContext(),
context.getGenericsNamingStrategy(),
context);
Parameter parameter = parameterContext.parameterBuilder()
.parameterType("body").modelRef(new ModelRef(clazzName)).name(clazzName).build();
parameters.add(parameter);
}
}
context.operationBuilder().parameters(parameters);
}
@Override
public boolean supports(DocumentationType delimiter) {
return delimiter == DocumentationType.SWAGGER_2;
}
}

View File

@@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.orange.demo.common.swagger.config.SwaggerAutoConfiguration

View File

@@ -15,6 +15,5 @@
<module>common-core</module>
<module>common-redis</module>
<module>common-sequence</module>
<module>common-swagger</module>
</modules>
</project>