Authored by csgyoho

Merge branch 'dev' of http://git.yoho.cn/ufo/yohoufo-fore into dev

... ... @@ -10,11 +10,20 @@ import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
*/
public enum CacheEnum {
/**
* 获取资源位接口,缓存5分钟
*/
RESOURCE_GET("yhufo:resources:resources_get", 5 * 60, "resources.cachetime.resources_get"),
RESOURCE_GET("yh:ufo:resources:resources_get", 5 * 60, "resources.cachetime.resources_get"),
/**
* 商品系列,缓存1分钟
*/
PRODUCT_SERIES_SEARCH("yh:ufo:resources:product_series_search", 1 * 60, "resources.cachetime.product_series_search"),
/**
* 商品品类,缓存1分钟
*/
PRODUCT_CATEGORY_SEARCH("yh:ufo:resources:product_category_search", 1 * 60, "resources.cachetime.product_category_search"),
/*
* end
... ...
package com.yohoufo.order.common;
import com.yohoufo.order.model.bo.ButtonShowBo;
public enum ButtonShow {
CANCEL_ORDER("cancel_order","取消订单"),
... ... @@ -18,9 +20,15 @@ public enum ButtonShow {
String code;
String value;
private ButtonShowBo bo;
ButtonShow(String code,String value) {
this.code = code;
this.value = value;
bo = new ButtonShowBo(name(), code, value);
}
public ButtonShowBo getBo() {
return bo;
}
}
... ...
... ... @@ -2,11 +2,13 @@ package com.yohoufo.order.common;
import com.google.common.collect.Lists;
import com.yohoufo.order.constants.OrderDetailDesc;
import com.yohoufo.order.model.bo.ButtonShowBo;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public enum OrderStatus {
... ... @@ -212,11 +214,11 @@ public enum OrderStatus {
return -1;
}
public List<ButtonShow> getListButtons(TabType actorType) {
public List<ButtonShowBo> getListButtons(TabType actorType) {
return nodes[getIndex(actorType)].listButtons;
}
public List<ButtonShow> getDetailButtons(TabType actorType) {
public List<ButtonShowBo> getDetailButtons(TabType actorType) {
return nodes[getIndex(actorType)].detailButtons;
}
... ... @@ -254,12 +256,12 @@ public enum OrderStatus {
/**
* 订单列表中的按钮
*/
List<ButtonShow> listButtons;
List<ButtonShowBo> listButtons;
/**
* 详情的按钮
*/
List<ButtonShow> detailButtons;
List<ButtonShowBo> detailButtons;
/**
* 详情页状态说明
... ... @@ -271,8 +273,12 @@ public enum OrderStatus {
List<ButtonShow> detailButtons,
String detailDesc) {
this.statusStr = statusStr;
this.listButtons = listButtons;
this.detailButtons = detailButtons;
if (listButtons != null && !listButtons.isEmpty()){
this.listButtons = listButtons.parallelStream().map(ButtonShow::getBo).collect(Collectors.toList());
}
if (detailButtons !=null && !detailButtons.isEmpty()){
this.detailButtons = detailButtons.parallelStream().map(ButtonShow::getBo).collect(Collectors.toList());
};
this.detailDesc = detailDesc;
}
}
... ...
package com.yohoufo.order.common;
import com.yohoufo.order.constants.OrderDetailDesc;
import com.yohoufo.order.model.bo.ButtonShowBo;
import java.util.Arrays;
import java.util.HashMap;
... ... @@ -17,8 +18,8 @@ public enum SkupStatus {
*/
CAN_SELL(1, "可售",
new Node(
Arrays.asList(ButtonShow.NOT_SOLD, ButtonShow.SHOW_DETAIL),
Arrays.asList(ButtonShow.NOT_SOLD),
Arrays.asList(ButtonShow.NOT_SOLD.getBo(), ButtonShow.SHOW_DETAIL.getBo()),
Arrays.asList(ButtonShow.NOT_SOLD.getBo()),
OrderDetailDesc.Seller.PAY_FINISH
)
),
... ... @@ -27,37 +28,37 @@ public enum SkupStatus {
*/
CAN_NOT_SELL(0,"待付保证金",
new Node(
Arrays.asList(ButtonShow.NOT_SOLD, ButtonShow.PAY_EARNESTMONEY),
Arrays.asList(ButtonShow.NOT_SOLD, ButtonShow.PAY_EARNESTMONEY),
Arrays.asList(ButtonShow.NOT_SOLD.getBo(), ButtonShow.PAY_EARNESTMONEY.getBo()),
Arrays.asList(ButtonShow.NOT_SOLD.getBo(), ButtonShow.PAY_EARNESTMONEY.getBo()),
OrderDetailDesc.Seller.WAIT_PAY
)
),
SELF_CANCEL_PAY(20, "上架关闭(卖家取消支付)",
new Node(
Arrays.asList(ButtonShow.SOLD_AGAIN, ButtonShow.DEL_ORDER, ButtonShow.SHOW_DETAIL),
Arrays.asList(ButtonShow.DEL_ORDER, ButtonShow.SOLD_AGAIN),
Arrays.asList(ButtonShow.SOLD_AGAIN.getBo(), ButtonShow.DEL_ORDER.getBo(), ButtonShow.SHOW_DETAIL.getBo()),
Arrays.asList(ButtonShow.DEL_ORDER.getBo(), ButtonShow.SOLD_AGAIN.getBo()),
OrderDetailDesc.Seller.SELF_CANCEL_BEFORE_PAY
)
),
TIMEOUT_CANCEL(21, "上架关闭(卖家支付超时)",
new Node(
Arrays.asList(ButtonShow.SOLD_AGAIN, ButtonShow.DEL_ORDER, ButtonShow.SHOW_DETAIL),
Arrays.asList(ButtonShow.DEL_ORDER, ButtonShow.SOLD_AGAIN),
Arrays.asList(ButtonShow.SOLD_AGAIN.getBo(), ButtonShow.DEL_ORDER.getBo(), ButtonShow.SHOW_DETAIL.getBo()),
Arrays.asList(ButtonShow.DEL_ORDER.getBo(), ButtonShow.SOLD_AGAIN.getBo()),
OrderDetailDesc.Seller.TIME_OUT_CANCEL
)
),
SELLER_CANCEL_SELL(22, "上架关闭(卖家取消出售)",
new Node(
Arrays.asList(ButtonShow.SOLD_AGAIN, ButtonShow.DEL_ORDER, ButtonShow.SHOW_DETAIL),
Arrays.asList(ButtonShow.DEL_ORDER, ButtonShow.SOLD_AGAIN),
Arrays.asList(ButtonShow.SOLD_AGAIN.getBo(), ButtonShow.DEL_ORDER.getBo(), ButtonShow.SHOW_DETAIL.getBo()),
Arrays.asList(ButtonShow.DEL_ORDER.getBo(), ButtonShow.SOLD_AGAIN.getBo()),
OrderDetailDesc.Seller.SELF_CANCEL_BEFORE_EXIST_BUY
)
),
YOHO_CANCEL_SELL(23, "上架关闭(平台取消出售)",
new Node(
Arrays.asList(ButtonShow.SOLD_AGAIN, ButtonShow.DEL_ORDER, ButtonShow.SHOW_DETAIL),
Arrays.asList(ButtonShow.DEL_ORDER, ButtonShow.SOLD_AGAIN),
Arrays.asList(ButtonShow.SOLD_AGAIN.getBo(), ButtonShow.DEL_ORDER.getBo(), ButtonShow.SHOW_DETAIL.getBo()),
Arrays.asList(ButtonShow.DEL_ORDER.getBo(), ButtonShow.SOLD_AGAIN.getBo()),
OrderDetailDesc.Seller.YOHO_CANCEL_BEFORE_EXIST_BUY
)
)
... ... @@ -77,13 +78,13 @@ public enum SkupStatus {
static class Node{
List<ButtonShow> listButtons;
List<ButtonShowBo> listButtons;
List<ButtonShow> detailButtons;
List<ButtonShowBo> detailButtons;
String detailShowDesc;
public Node(List<ButtonShow> listButtons, List<ButtonShow> detailButtons, String desc) {
public Node(List<ButtonShowBo> listButtons, List<ButtonShowBo> detailButtons, String desc) {
this.listButtons = listButtons;
this.detailButtons = detailButtons;
this.detailShowDesc = desc;
... ... @@ -108,15 +109,19 @@ public enum SkupStatus {
}
public List<ButtonShow> getListButtons() {
public List<ButtonShowBo> getListButtons() {
return node.listButtons;
}
public List<ButtonShow> getDetailButtons() {
public List<ButtonShowBo> getDetailButtons() {
return node.detailButtons;
}
public String getDetailShowDesc() {
return node.detailShowDesc;
}
public String getDesc() {
return desc;
}
}
... ...
package com.yohoufo.order.model.bo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Created by chenchao on 2018/9/20.
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ButtonShowBo {
String name;
String code;
String text;
}
... ...
... ... @@ -5,6 +5,7 @@ import com.yoho.service.model.response.UserAddressRspBO;
import com.yohobuy.ufo.model.order.bo.PlatformFee;
import com.yohoufo.order.common.ButtonShow;
import com.yohoufo.order.model.AddressInfo;
import com.yohoufo.order.model.bo.ButtonShowBo;
import lombok.Data;
import lombok.experimental.Builder;
... ... @@ -42,7 +43,7 @@ public class OrderDetailInfo {
/**
* 按钮显示
*/
List<ButtonShow> buttons;
List<ButtonShowBo> buttons;
int payment;
... ...
package com.yohoufo.order.model.response;
import com.yohoufo.order.common.ButtonShow;
import com.yohoufo.order.model.bo.ButtonShowBo;
import lombok.Data;
import java.util.List;
... ... @@ -38,5 +39,5 @@ public class OrderListInfo {
/**
* 按钮显示
*/
List<ButtonShow> buttons;
List<ButtonShowBo> buttons;
}
... ...
... ... @@ -98,7 +98,7 @@ public class SellerOrderListService extends AbsOrderListService implements IOrde
return null;
}
orderListInfo.setStatuStr(orderStatus.getDetailShowDesc());
orderListInfo.setStatuStr(orderStatus.getDesc());
// 按钮显示
orderListInfo.setButtons(orderStatus.getListButtons());
... ... @@ -116,6 +116,7 @@ public class SellerOrderListService extends AbsOrderListService implements IOrde
goodsInfo.setProductName(sellerOrderGoods.getProductName());
goodsInfo.setGoodImg(sellerOrderGoods.getImageUrl());
goodsInfo.setSizeName(sellerOrderGoods.getSizeName());
goodsInfo.setGoodPrice(sellerOrderGoods.getGoodsPrice().toPlainString());
orderListInfo.setGoodsInfo(goodsInfo);
... ...
package com.yohoufo.resource.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
* Created by yoho on 2015/11/25.
*/
public interface IProductQueryService {
JSONArray searchSeries(String params);
JSONObject searchCategory(String params);
}
... ...
package com.yohoufo.resource.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.common.cache.CacheEnum;
import com.yohoufo.common.caller.UfoServiceCaller;
import com.yohoufo.common.redis.NoSyncGracefulRedisTemplate;
import com.yohoufo.resource.service.IProductQueryService;
@Service
public class ProductQueryServiceImpl implements IProductQueryService {
private static Logger logger = LoggerFactory.getLogger(ProductQueryServiceImpl.class);
@javax.annotation.Resource(name="NoSyncGracefulRedisTemplate")
private NoSyncGracefulRedisTemplate resourcesRedisCache;
public static final String CATEGORY_METHOD = "ufo.product.sort.template";
public static final String SERIES_METHOD = "ufo.product.series.template";
@Autowired
private UfoServiceCaller ufoServiceCaller;
public JSONArray searchSeries(String params) {
RedisKeyBuilder cacheKey = CacheEnum.PRODUCT_SERIES_SEARCH.generateKey(params);
JSONArray data = resourcesRedisCache.get(cacheKey, JSONArray.class);
if (data == null) {
logger.info("begin invoke ufo.product.series.template, param is:{}", params);
ApiResponse apiResponse = ufoServiceCaller.call(SERIES_METHOD, ApiResponse.class, params);
if (null != apiResponse && apiResponse.getCode() == 200) {
JSONObject productSeriesJSON = (JSONObject) apiResponse.getData();
if (null != productSeriesJSON && null != productSeriesJSON.get("list")) {
data = productSeriesJSON.getJSONArray("list");
}
}
//获得BackupKey
RedisKeyBuilder cacheBackupKey = CacheEnum.PRODUCT_SERIES_SEARCH.generateBackupKey(params);
if (data == null) {
logger.info("Series search, find Series by {} from backup redis.", cacheKey);
JSONArray backupData = resourcesRedisCache.get(cacheBackupKey, JSONArray.class);
if (backupData == null) {
logger.info("Series search, can not find Series by {} from backup redis.", cacheKey);
return new JSONArray();
} else {
logger.info("Series search, find Series by {} from backup redis success.", cacheKey);
return backupData;
}
}else {
logger.info("Series search, search Series by {} success.", cacheKey);
resourcesRedisCache.setEx(cacheKey, data, CacheEnum.PRODUCT_SERIES_SEARCH.getCacheTime());
resourcesRedisCache.setEx(cacheBackupKey, data, CacheEnum.PRODUCT_SERIES_SEARCH.getBackupCacheTime());
return data;
}
}else {
logger.info("Series search, find Series by {} from redis success.", cacheKey);
return data;
}
}
/**
* 查询品类
*
* @see com.yohoufo.resource.service.IProductQueryService#searchCategory(java.lang.String)
* @author: 胡子成 - ken.hu@yoho.cn
* @date: Created on 2018年9月20日 下午6:27:23
*/
@Override
public JSONObject searchCategory(String params) {
RedisKeyBuilder cacheKey = CacheEnum.PRODUCT_CATEGORY_SEARCH.generateKey(params);
JSONObject data = resourcesRedisCache.get(cacheKey, JSONObject.class);
if (data == null) {
logger.info("begin invoke ufo.product.sort.template, param is:{}", params);
ApiResponse apiResponse = ufoServiceCaller.call(CATEGORY_METHOD, ApiResponse.class, params);
if (null != apiResponse && apiResponse.getCode() == 200) {
JSONObject productCategoryJSON = (JSONObject) apiResponse.getData();
if (null != productCategoryJSON) {
data = productCategoryJSON;
}
}
//获得BackupKey
RedisKeyBuilder cacheBackupKey = CacheEnum.PRODUCT_CATEGORY_SEARCH.generateBackupKey(params);
if (data == null) {
logger.info("Category search, find Category by {} from backup redis.", cacheKey);
JSONObject backupData = resourcesRedisCache.get(cacheBackupKey, JSONObject.class);
if (backupData == null) {
logger.info("Category search, can not find Category by {} from backup redis.", cacheKey);
return new JSONObject();
} else {
logger.info("Category search, find Category by {} from backup redis success.", cacheKey);
return backupData;
}
}else {
logger.info("Category search, search Category by {} success.", cacheKey);
resourcesRedisCache.setEx(cacheKey, data, CacheEnum.PRODUCT_CATEGORY_SEARCH.getCacheTime());
resourcesRedisCache.setEx(cacheBackupKey, data, CacheEnum.PRODUCT_CATEGORY_SEARCH.getBackupCacheTime());
return data;
}
}else {
logger.info("Category search, find Category by {} from redis success.", cacheKey);
return data;
}
}
}
... ...
package com.yohoufo.resource.service.impl.resource;
import java.io.Serializable;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -12,11 +10,8 @@ import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.common.caller.UfoServiceCaller;
import com.yohoufo.product.model.ProductSortTemplate;
import com.yohoufo.product.response.ProductSortTemplateResp;
import com.yohoufo.resource.helper.MakeUrlService;
import com.yohoufo.resource.service.IProductQueryService;
import com.yohoufo.resource.service.IResourceParse;
import com.yohoufo.resource.service.Resource;
... ... @@ -34,7 +29,7 @@ public class CategoryResourceParse implements IResourceParse {
private MakeUrlService makeUrlService;
@Autowired
private UfoServiceCaller ufoServiceCaller;
private IProductQueryService productQueryService;
@Override
public Serializable parse(Resource resource) {
... ... @@ -75,13 +70,7 @@ public class CategoryResourceParse implements IResourceParse {
categoryJSON.put("more_url", makeUrl(jsonMoreUrl, resource.getClientType()));
// 调用品类接口
if (StringUtils.isNotBlank(productIds)) {
ApiResponse apiResponse = ufoServiceCaller.call("ufo.product.sort.template", ApiResponse.class, productIds);
if (null != apiResponse && apiResponse.getCode() == 200) {
JSONObject productSortJSON = (JSONObject) apiResponse.getData();
if (null != productSortJSON ) {
categoryJSON.putAll(productSortJSON);
}
}
categoryJSON.putAll(productQueryService.searchCategory(productIds));
}
returnArray.add(categoryJSON);
}
... ...
package com.yohoufo.resource.service.impl.resource;
import java.io.Serializable;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.common.caller.UfoServiceCaller;
import com.yohoufo.product.model.ProductSeriesTemplate;
import com.yohoufo.product.response.ProductSeriesTemplateResp;
import com.yohoufo.resource.service.IProductQueryService;
import com.yohoufo.resource.service.IResourceParse;
import com.yohoufo.resource.service.Resource;
... ... @@ -30,7 +24,7 @@ public class HotSeriesResourceParse implements IResourceParse {
public static final String TEMPLATE_NAME = "hotSeries";
@Autowired
private UfoServiceCaller ufoServiceCaller;
private IProductQueryService productQueryService;
@Override
public Serializable parse(Resource resource) {
... ... @@ -54,14 +48,7 @@ public class HotSeriesResourceParse implements IResourceParse {
if (StringUtils.isBlank(productIds)) {
return returnJSON;
}
// 调用系列接口
ApiResponse apiResponse = ufoServiceCaller.call("ufo.product.series.template", ApiResponse.class, productIds);
if (null != apiResponse && apiResponse.getCode() == 200) {
JSONObject productSeriesJSON = (JSONObject) apiResponse.getData();
if (null != productSeriesJSON && null != productSeriesJSON.get("list")) {
returnJSON.put("data", productSeriesJSON.get("list"));
}
}
returnJSON.put("data",productQueryService.searchSeries(productIds));
return returnJSON;
}
}
\ No newline at end of file
... ...
... ... @@ -2,6 +2,7 @@ package com.yohoufo.user.controller.favorite;
import com.yoho.error.exception.ServiceException;
import com.yoho.tools.common.beans.ApiResponse;
import com.yohoufo.common.caller.UfoServiceCaller;
import com.yohoufo.user.requestVO.FavoriteRequestVO;
import com.yohoufo.user.service.IFavoriteService;
import org.slf4j.Logger;
... ... @@ -29,6 +30,33 @@ public class FavoriteController {
@Autowired
private IFavoriteService favoriteService;
@Autowired
private UfoServiceCaller serviceCaller;
/**
* 用户收藏list
* @param vo
* @return
* @throws ServiceException
*/
@RequestMapping(params = "method=ufo.user.favoriteList")
public ApiResponse listFavorite(FavoriteRequestVO vo) throws ServiceException {
logger.info("Begin call ufo.user.favoriteList with param is {}", vo);
validateRequest(vo,false);
if (vo.getLimit()>20) {
logger.warn("request page limit can not big than 20");
vo.setLimit(20);
}
//分页获取收藏的商品id,
List<String> productIds= favoriteService.listFavorite(vo);
//调用商品接口返回商品list
ApiResponse productApiResponse = serviceCaller.call("ufo.product.batch.data",
ApiResponse.class, productIds);
return productApiResponse;
}
/**
* 用户收藏商品数量num
* @param vo
... ... @@ -90,22 +118,6 @@ public class FavoriteController {
return new ApiResponse.ApiResponseBuilder().message(CANCEL_FAVORITE_SUCCESS).data(null).build();
}
/**
* 用户收藏list
* @param vo
* @return
* @throws ServiceException
*/
@RequestMapping(params = "method=ufo.user.favoriteList")
public ApiResponse listFavorite(FavoriteRequestVO vo) throws ServiceException {
logger.info("Begin call ufo.user.favoriteList with param is {}", vo);
validateRequest(vo,false);
List<String> productIds= favoriteService.listFavorite(vo);
//组织商品信息返回
return null;
}
private void validateRequest(FavoriteRequestVO vo,boolean checkProduct) {
if (null == vo) {
logger.warn("validateRequest params is null");
... ...
package com.yohoufo.user.requestVO;
import com.yohoufo.user.common.BaseVO;
import lombok.Data;
/**
* 分页获取
*/
@Data
public class FavoriteRequestVO extends BaseVO {
public class FavoriteRequestVO extends PageReqVO {
private Integer uid;
//商品skn 单款
private Integer productId;
... ...
... ... @@ -70,8 +70,10 @@ public class FavoriteServiceImpl implements IFavoriteService {
public List<String> listFavorite(FavoriteRequestVO vo){
List<String> favoriteProducts = new ArrayList<>();
int uid = vo.getUid();
int startIndex=vo.getLimit()*(vo.getPage()-1);
int endIndex=vo.getLimit()*vo.getPage();
// 查询缓存
Set<String> favoriteProductIds = cacheService.queryAllProductFavoriteByUid(uid, 0, -1);
Set<String> favoriteProductIds = cacheService.queryAllProductFavoriteByUid(uid, startIndex, endIndex-1);
if(CollectionUtils.isNotEmpty(favoriteProductIds)){
favoriteProductIds.remove("0");
favoriteProducts.addAll(favoriteProductIds);
... ... @@ -80,8 +82,11 @@ public class FavoriteServiceImpl implements IFavoriteService {
List<UserFavorite> favoriteList = userFavoriteDao.selectValidFavoriteByUid(getTableIndex(uid), uid);
cacheService.batchSetFavoriteProduct(uid, favoriteList);
int count=0;
for (UserFavorite favorite : favoriteList) {
favoriteProducts.add(String.valueOf(favorite.getProductId()));
if(count>=startIndex && count<endIndex){
favoriteProducts.add(String.valueOf(favorite.getProductId()));
}
}
return favoriteProducts;
}
... ...
... ... @@ -47,12 +47,17 @@
<!-- json转换器 application/json -->
<bean id="jsonConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json;charset=UTF-8"/>
<property name="features">
<array value-type="com.alibaba.fastjson.serializer.SerializerFeature">
<value>DisableCircularReferenceDetect</value>
</array>
</property>
<property name="fastJsonConfig" ref="fastJsonConfig" />
</bean>
<bean id="fastJsonConfig" class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="serializerFeatures">
<array value-type="com.alibaba.fastjson.serializer.SerializerFeature">
<value>WriteEnumUsingToString</value>
<value>DisableCircularReferenceDetect</value>
</array>
</property>
</bean>
<bean id="DisableCircularReferenceDetect" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField" value="com.alibaba.fastjson.serializer.SerializerFeature.DisableCircularReferenceDetect"></property>
</bean>
... ...