Authored by caoyan

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

# Conflicts:
#	product/src/main/java/com/yohoufo/product/controller/ProductSearchController.java
Showing 19 changed files with 613 additions and 416 deletions
package com.yohoufo.common.utils;
/**
* Created by li.ma on 2019/11/19.
*/
public class MathUtil {
//获取取整的价格
public static Integer getIntCeilPrice(Double price){
if(null == price) {
return 0;
}
return Double.valueOf(Math.ceil(price)).intValue();
}
}
... ...
... ... @@ -134,11 +134,14 @@ public class SellerGoodsController {
@ResponseBody
public ApiResponse computeChangePriceOfSingleGoods(@RequestParam(name = "uid") int uid,
@RequestParam(name = "skup") int skup,
@RequestParam(name="price", required = true)String price
@RequestParam(name="price", required = true)String price,
@RequestParam(name="business_client", required = false, defaultValue = "ufo")String businessClient
) {
SingleGoodsChangePriceReq req = SingleGoodsChangePriceReq.builder().uid(uid)
.skup(skup)
.price(price).build();
.price(price)
.businessClient(businessClient)
.build();
logger.info("in ufo.notEntrySeller.computeChangePricece, req {}", req);
try {
SoldPrdComputeBo computeBo = changePriceService.computeChangePrice(req);
... ... @@ -160,9 +163,15 @@ public class SellerGoodsController {
@ResponseBody
public ApiResponse changePriceOfSingleGoods(@RequestParam(name = "uid") int uid,
@RequestParam(name = "skup") int skup,
@RequestParam(name="price", required = true)String price) throws GatewayException {
@RequestParam(name="price", required = true)String price,
@RequestParam(name="business_client", required = false, defaultValue = "ufo")String businessClient) {
SingleGoodsChangePriceReq req = SingleGoodsChangePriceReq.builder()
.uid(uid).skup(skup).num(1).price(price).build();
.uid(uid)
.skup(skup)
.num(1)
.price(price)
.businessClient(businessClient)
.build();
logger.info("in ufo.notEntrySeller.changePrice, req {}", req);
try {
OrderSubmitResp result = changePriceService.changePrice(req);
... ... @@ -179,6 +188,7 @@ public class SellerGoodsController {
@ResponseBody
public ApiResponse getImperfectGoodsList(@RequestParam("type") int type,
@RequestParam("uid") int uid,
@RequestParam(name="business_client", required = false, defaultValue = "ufo")String businessClient,
@RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "limit", required = false, defaultValue = "10") int limit) {
OrderListRequest orderListRequest = OrderListRequest.builder()
... ... @@ -186,6 +196,7 @@ public class SellerGoodsController {
.type(type)
.page(page)
.limit(limit)
.businessClient(businessClient)
.build();
logger.info("ufo.seller.imperfectGoodsList orderListRequest {}", orderListRequest);
PageResp<OrderListInfo> orderListInfoRsp;
... ...
... ... @@ -11,6 +11,8 @@ import java.util.List;
*/
@Data
public class SellerOrderComputeResult {
Integer uid;
Integer storageId;
BigDecimal prdPrice;
EarnestMoney earnestMoney;
... ...
... ... @@ -5,7 +5,6 @@ import com.google.common.collect.Lists;
import com.yoho.core.rabbitmq.YhProducer;
import com.yohobuy.ufo.model.order.bo.CustomsClearanceResult;
import com.yohobuy.ufo.model.order.bo.MerchantOrderAttachInfo;
import com.yohobuy.ufo.model.order.common.MetaConfigKey;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohobuy.ufo.model.order.common.SellerOrderStatus;
import com.yohobuy.ufo.model.order.common.SkupStatus;
... ... @@ -20,7 +19,6 @@ import com.yohoufo.common.alarm.UfoInfluxdbVo;
import com.yohoufo.common.constant.InfluxdbFieldEnum;
import com.yohoufo.common.constant.InfluxdbMeasurementEnum;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.common.utils.BigDecimalHelper;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.*;
import com.yohoufo.dal.order.model.*;
... ... @@ -32,7 +30,6 @@ import com.yohoufo.order.constants.ClearanceFailType;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.event.*;
import com.yohoufo.order.model.PayRefundBo;
import com.yohoufo.order.model.dto.BuyerPenalty;
import com.yohoufo.order.model.dto.BuyerPenaltyCalResult;
import com.yohoufo.order.model.request.PaymentRequest;
import com.yohoufo.order.model.request.TranseferCellNode;
... ... @@ -56,6 +53,7 @@ import lombok.Setter;
import lombok.val;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
... ... @@ -64,7 +62,6 @@ import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
... ... @@ -173,9 +170,10 @@ public class BuyerOrderCancelService {
logger.info("in buyer cancel BeforeSellerDeliver, event {} BuyerPenaltyCalResult {}", bsdEvent, bpcr);
//买家实付金额(货款+运费)小于赔偿金的额度,不够赔偿的,则不允许取消
BigDecimal penaltyAmount;
if(bsdEvent.getAmount()==null||bsdEvent.getAmount().compareTo(penaltyAmount=bpcr.getPenaltyAmount()) < 0){
Pair<Boolean,UfoServiceException> penaltyAmountIsEnough = checkPenaltyAmount(bsdEvent.getAmount(), penaltyAmount=bpcr.getPenaltyAmount());
if(!penaltyAmountIsEnough.getLeft()){
logger.warn("in buyer cancel BeforeSellerDeliver not allow cancel cause of buyer amount lower than BuyerCompensateMoney, event {} compensate {}", bsdEvent, bpcr);
throw new com.yohoufo.common.exception.UfoServiceException(400,"买家赔偿金低于商品售价,不允许取消");
throw penaltyAmountIsEnough.getRight();
}
... ... @@ -301,6 +299,14 @@ public class BuyerOrderCancelService {
.cancel();
}
private Pair<Boolean,UfoServiceException> checkPenaltyAmount(BigDecimal actualPaidAmount, BigDecimal penaltyAmount){
boolean isEnough = (actualPaidAmount !=null && actualPaidAmount.compareTo(penaltyAmount) >= 0);
UfoServiceException ex = null;
if(!isEnough){
ex = new com.yohoufo.common.exception.UfoServiceException(400,"实付金额低于订单违约金,不允许取消");
}
return Pair.of(isEnough, ex);
}
public void cancel(BeforeDepotReceiveEvent bdrEvent){
int buyerUid = bdrEvent.getBuyerUid();
... ... @@ -315,12 +321,12 @@ public class BuyerOrderCancelService {
logger.info("in buyer cancel BeforeDepotReceive, event {} compensate {}", bdrEvent, bpcr);
//买家实付金额(货款+运费)小于赔偿金的额度,不够赔偿的,则不允许取消
BigDecimal penaltyAmount;
if(bdrEvent.getAmount()==null||bdrEvent.getAmount().compareTo(penaltyAmount=bpcr.getPenaltyAmount()) < 0){
Pair<Boolean,UfoServiceException> amountIsEnough = checkPenaltyAmount(bdrEvent.getAmount(), penaltyAmount=bpcr.getPenaltyAmount());
if(!amountIsEnough.getLeft()){
logger.warn("in buyer cancel BeforeDepotReceive not allow cancel cause of buyer amount lower than BuyerCompensateMoney, event {} compensate {}", bdrEvent, bpcr);
throw new com.yohoufo.common.exception.UfoServiceException(400,"买家赔偿金低于商品售价,不允许取消");
throw amountIsEnough.getRight();
}
OrderStatus expected = bdrEvent.getExpected();
int currentTime = DateUtil.getCurrentTimeSecond();
int rows = buyerOrderMapper.updateStatusByOrderCode(orderCode, buyerUid, expected.getCode(), targetOrderStatus.getCode(), currentTime);
... ...
... ... @@ -131,7 +131,7 @@ public class SellerBidPublishService {
.storageId(storageId).prdPrice(saleableBidSkup.getPrice()).build();
priceComputePrepareProcessor.checkPulishAuthNPriceRange(pqr, true);
SellerOrderComputeResult pcc = getSellerBidGoodsFeeRate(uid, skupType);
SellerOrderComputeResult pcc = getSellerBidGoodsFeeRate(uid, storageId, skupType);
OrderComputeHandler computeHandler = orderComputeProvider.findBySkupType(skupType);
SellerOrderComputeResult computeResult = computeHandler.compute(saleableBidSkup.getPrice(), pcc);
... ... @@ -227,13 +227,15 @@ public class SellerBidPublishService {
return Pair.of(noHiddenBackAddress, hiddenBackAddress);
}
public SellerOrderComputeResult getSellerBidGoodsFeeRate(int uid, SkupType skupType) {
public SellerOrderComputeResult getSellerBidGoodsFeeRate(int uid, int storageId, SkupType skupType) {
logger.info("in getSellerBidGoodsFeeRate uid {}, skupType {}",
uid, skupType);
ServiceFeeRate rate = getSellerBidGoodsFeeRate(skupType);
List<ServiceFeeRate> allConfig = Lists.newArrayList(rate);
SellerOrderComputeResult socr = new SellerOrderComputeResult();
socr.setServiceFeeRates(allConfig);
socr.setUid(uid);
socr.setStorageId(storageId);
return socr;
}
... ...
... ... @@ -347,11 +347,13 @@ public class SellerOrderListService extends AbsOrderListService implements IOrde
@Override
int getTotal(int uid, List<Integer> statusQuery, List<Integer> orderTypes) {
return buyerOrderMapper.selectCntBySellerUidStatus(uid, statusQuery, orderTypes);
//
return buyerOrderMapper.selectCntBySellerUidStatus(uid, statusQuery, null);
}
@Override
List<BuyerOrder> getOrderList(int uid, Long orderCode, List<Integer> statusQuery, List<Integer> orderTypes, int offset, int limit){
orderTypes = null;
List<BuyerOrder> buyerOrderList = buyerOrderMapper.selectListBySellerUidStatus(uid, orderCode, statusQuery, orderTypes, offset, limit);
return buyerOrderList;
}
... ...
... ... @@ -5,8 +5,6 @@ import com.yohoufo.common.utils.BigDecimalHelper;
import com.yohoufo.order.model.dto.*;
import com.yohoufo.order.service.impl.MetaConfigService;
import com.yohoufo.order.service.impl.OrderDynamicConfig;
import com.yohoufo.order.service.seller.fee.GoodsServiceFeeRateDimension;
import com.yohoufo.order.service.seller.fee.GoodsServiceFeeRateWrapper;
import com.yohoufo.order.utils.LoggerUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
... ... @@ -50,21 +48,23 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
@Override
public SellerOrderComputeResult compute(BigDecimal prdPrice,
SellerOrderComputeResult personalComputeConfig){
final boolean personalComputeConfigExist;
Integer uid = (personalComputeConfigExist= Objects.nonNull(personalComputeConfig)) ? personalComputeConfig.getUid() : null;
Integer storageId = personalComputeConfigExist ? personalComputeConfig.getStorageId() : null;
//计算保证金(28-200(按照卖家发布商品的货款金额5%计算,最低28,封顶200))
EarnestMoney earnestMoney = calEarnestMoney(prdPrice);
//init fee rate
List<ServiceFeeRate> psfr = personalComputeConfig!=null ? personalComputeConfig.getServiceFeeRates() : null;
List<ServiceFeeRate> psfr = personalComputeConfigExist ? personalComputeConfig.getServiceFeeRates() : null;
//目前根据商品类型匹配费率,未来的趋势是有多维度配置,根据策略择优
PlatformFeeDto ppf = personalComputeConfig!=null ? personalComputeConfig.getPlatformFee() : null;
PlatformFeeDto ppf = personalComputeConfigExist ? personalComputeConfig.getPlatformFee() : null;
//计算平台费用:1.鉴定费 2.包装费 3.货款抽成
Pair<ServiceFeeRate,PlatformFeeDto> calPlatformFee = calPlatformFee(prdPrice, psfr, ppf);
Pair<ServiceFeeRate,PlatformFeeDto> calPlatformFee = calPlatformFee(uid, storageId, prdPrice, psfr, ppf);
ServiceFeeRate serviceFeeRate = calPlatformFee.getLeft();
PlatformFeeDto platformFeeDto = calPlatformFee.getRight();
//计算支付服务费
BigDecimal bankTransferFee = calBankTransferFee(prdPrice, serviceFeeRate.getPayChannelRate());
logger.info("in SellerOrder Compute, prdPrice {}, platformFee {}, bankTransferFee {}",
prdPrice, platformFeeDto, bankTransferFee);
logger.info("in SellerOrder Compute,uid {} storageId {}, prdPrice {}, platformFee {}, bankTransferFee {}",
uid, storageId, prdPrice, platformFeeDto, bankTransferFee);
//计算收入
BigDecimal income = calIncome(prdPrice, platformFeeDto.getTotal(), bankTransferFee);
//目前只有预售有买家和卖家阶梯处罚
... ... @@ -151,7 +151,11 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
* 服务费参与计算后需要考虑精度问题(四舍五入)
* @return
*/
protected Pair<ServiceFeeRate,PlatformFeeDto> calPlatformFee(BigDecimal price, List<ServiceFeeRate> serviceFeeRates, PlatformFeeDto ppf){
protected Pair<ServiceFeeRate,PlatformFeeDto> calPlatformFee(Integer uid,
Integer storageId,
BigDecimal price,
List<ServiceFeeRate> serviceFeeRates,
PlatformFeeDto ppf){
PlatformFeeDto platformFee = new PlatformFeeDto();
... ... @@ -173,7 +177,7 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
}
//目前而言,商品抽成的阈值只有公共配置
PriceRange defaultGoodsServiceFeeRange = pfc.getGoodsServiceFeeRange();
ChooseServiceReeRateAndCalServiceFeeModel chooseServiceReeRateAndCalServiceFee = new ChooseServiceReeRateAndCalServiceFeeModel(price, serviceFeeRates, defaultGoodsServiceFeeRange)
ChooseServiceReeRateAndCalServiceFeeModel chooseServiceReeRateAndCalServiceFee = new ChooseServiceReeRateAndCalServiceFeeModel(uid, storageId, price, serviceFeeRates, defaultGoodsServiceFeeRange)
.invoke();
ServiceFeeRate serviceFeeRate = chooseServiceReeRateAndCalServiceFee.getServiceFeeRate();
BigDecimal serviceFee = chooseServiceReeRateAndCalServiceFee.getServiceFee();
... ... @@ -231,13 +235,21 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
protected abstract Collection<BuyerPenalty.Fee> buildStagedCollection();
private class ChooseServiceReeRateAndCalServiceFeeModel {
private Integer uid;
private Integer storageId;
private BigDecimal price;
private List<ServiceFeeRate> serviceFeeRates;
private PriceRange defaultGoodsServiceFeeRange;
private ServiceFeeRate serviceFeeRate;
private BigDecimal serviceFee;
public ChooseServiceReeRateAndCalServiceFeeModel(BigDecimal price, List<ServiceFeeRate> serviceFeeRates, PriceRange defaultGoodsServiceFeeRange) {
public ChooseServiceReeRateAndCalServiceFeeModel(Integer uid,
Integer storageId,
BigDecimal price,
List<ServiceFeeRate> serviceFeeRates,
PriceRange defaultGoodsServiceFeeRange) {
this.uid = uid;
this.storageId = storageId;
this.price = price;
this.serviceFeeRates = serviceFeeRates;
this.defaultGoodsServiceFeeRange = defaultGoodsServiceFeeRange;
... ... @@ -256,16 +268,42 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
serviceFeeRate = buildDefaultServiceFeeRate();
serviceFee = calServiceFee(price, serviceFeeRate, defaultGoodsServiceFeeRange);
} else {
for (ServiceFeeRate e : serviceFeeRates) {
PriceRange priceRange = Objects.nonNull(e.getGoodsPaymentPriceRange()) ? e.getGoodsPaymentPriceRange() : defaultGoodsServiceFeeRange;
BigDecimal tmp = calServiceFee(price, e, priceRange);
if (Objects.isNull(serviceFee) || serviceFee.compareTo(tmp) > 0) {
serviceFeeRate = e;
serviceFee = tmp;
ServiceFeeRate minSFR = matchMinRate(serviceFeeRates);
logger.info("compute CalServiceFee uid {} storageId {} price {} serviceFeeRates {} defaultGoodsServiceFeeRange {} minSFR{}",
uid, storageId, price, serviceFeeRates, defaultGoodsServiceFeeRange, minSFR);
PriceRange priceRange = Objects.nonNull(minSFR.getGoodsPaymentPriceRange()) ? minSFR.getGoodsPaymentPriceRange() : defaultGoodsServiceFeeRange;
BigDecimal minSF = calServiceFee(price, minSFR, priceRange);
serviceFeeRate = minSFR;
serviceFee = minSF;
//may by not min if calculate result by range
//eg : {rate : 0.01,range:[10,20]}, {rate : 0.02,range:[5,9]}
for (ServiceFeeRate sfr : serviceFeeRates) {
//pass min
if (minSFR.equals(sfr)){
continue;
}
PriceRange priceRange0 = Objects.nonNull(sfr.getGoodsPaymentPriceRange()) ? sfr.getGoodsPaymentPriceRange() : defaultGoodsServiceFeeRange;
BigDecimal tmp0 = calServiceFee(price, sfr, priceRange0);
if (Objects.isNull(serviceFee) || serviceFee.compareTo(tmp0) > 0) {
serviceFeeRate = sfr;
serviceFee = tmp0;
}
}
}
return this;
}
private ServiceFeeRate matchMinRate(List<ServiceFeeRate> serviceFeeRates){
ServiceFeeRate min = null;
for (ServiceFeeRate e : serviceFeeRates) {
if (Objects.isNull(min) || min.getGoodsPaymentRate().compareTo(e.getGoodsPaymentRate()) > 0) {
min = e;
}
}
return min;
}
}
}
... ...
... ... @@ -17,10 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Service
public class GoodsAmountService {
... ... @@ -60,6 +58,8 @@ public class GoodsAmountService {
SellerOrderComputeResult socr = new SellerOrderComputeResult();
socr.setServiceFeeRates(allConfig);
socr.setUid(uid);
socr.setStorageId(storageId);
return socr;
}
... ...
package com.yohoufo.order.service.seller;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.order.bo.SoldPrdComputeBo;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.order.BaseWebTest;
import com.yohoufo.order.convert.SellerOrderConvertor;
import com.yohoufo.order.model.dto.PriceRange;
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
import com.yohoufo.order.model.dto.ServiceFeeRate;
import com.yohoufo.order.service.proxy.ResourcesProxyService;
import com.yohoufo.order.service.seller.fee.GoodsServiceFeeRateDimension;
import com.yohoufo.order.service.seller.fee.GoodsServiceFeeRateWrapper;
import com.yohoufo.order.service.seller.inStock.SellerOrderComputeHandler;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
/**
* Created by chenchao on 2018/9/14.
*/
public class SellerOrderServiceTest {
public class SellerOrderServiceTest extends BaseWebTest {
@Autowired
private OrderComputeProvider orderComputeProvider;
@Test
public void testBuildSoldPrdComputeBo(){
SellerOrderComputeHandler sos = new SellerOrderComputeHandler();
BigDecimal prdPrice = new BigDecimal(100D);
SellerOrderComputeResult bo = sos.compute(prdPrice, null);
SkupType skupType = SkupType.IN_STOCK;
OrderComputeHandler sos = orderComputeProvider.findBySkupType(skupType);
BigDecimal prdPrice = new BigDecimal(5009D);
PriceRange goodsPaymentPriceRange;
ServiceFeeRate serviceFeeRateOnDB = new ServiceFeeRate();
serviceFeeRateOnDB.setPayChannelRate(new BigDecimal(0.01D));
serviceFeeRateOnDB.setGoodsPaymentRate(new BigDecimal(0.03D));
//
goodsPaymentPriceRange = new PriceRange();
goodsPaymentPriceRange.setMin(0D);
goodsPaymentPriceRange.setMax(100D);
serviceFeeRateOnDB.setGoodsPaymentPriceRange(goodsPaymentPriceRange);
//
List<ServiceFeeRate> allConfig = Lists.newArrayListWithCapacity(3);
//
BigDecimal feeRateOfOUOGT = new BigDecimal(0.05);
GoodsServiceFeeRateWrapper gsfrwOfOUOGT = new GoodsServiceFeeRateWrapper(GoodsServiceFeeRateDimension.ONE_USER_ONE_GOODS_TYPE, serviceFeeRateOnDB);
gsfrwOfOUOGT.setGoodsPaymentRate(feeRateOfOUOGT);
//
allConfig.add(gsfrwOfOUOGT);
//
allConfig.add(new GoodsServiceFeeRateWrapper(GoodsServiceFeeRateDimension.GOODS_TYPE, serviceFeeRateOnDB));
SellerOrderComputeResult socr = new SellerOrderComputeResult();
socr.setServiceFeeRates(allConfig);
SellerOrderComputeResult computeResult = sos.compute(prdPrice, socr);
System.out.println("in testBuildSoldPrdComputeBo :"+ JSONObject.toJSONString(computeResult));
System.out.println("in testBuildSoldPrdComputeBo :"+ JSONObject.toJSONString(bo));
Supplier<Map<String,String>> tipsConfigSupplier = () -> {
Map<String,String> tipsConfigMap = new HashMap<>();
tipsConfigMap.put(ResourcesProxyService.KEY_SERVICETIPSDESC,"5%");
tipsConfigMap.put(ResourcesProxyService.KEY_SERVICETIPSSUMARY,"5%");
return tipsConfigMap;
};
SoldPrdComputeBo spc;
spc = SellerOrderConvertor.computeResult2SoldPrdComputeBo(computeResult, tipsConfigSupplier);
System.out.println("computeResult2SoldPrdComputeBo computeResult ->"+ JSONObject.toJSONString(spc));
}
}
... ...
... ... @@ -126,7 +126,9 @@ rabbit_user=yoho
rabbit_password=yoho
#二次发货提醒 24*60 minutes
mq.seller.deliverNotice.second=1440
mq.seller.deliverNotice.second=40
mq.seller.deliverNotice.totalTime=60
mq.seller.deliverNotice.lastTime=20
#发货失败提醒 36*60 minutes
mq.seller.deliverNotice.third=15
... ... @@ -155,3 +157,5 @@ ufo.certification.timesLimit=3
# Unionpay
unionpay.env=00
unionpay.notifyurl=http://testapi.yohops.com/payment/ufo_unionpay_notify
ufo.alipay.sendPaymentInfo.switch=false
... ...
package com.yohoufo.product.constants;
/**
* Created by li.ma on 2019/11/19.
*/
public interface ProductSearchConstants {
String PRODUCT_LIST_URL = "/yohosearch/ufo/productList.json";
String FILTER_LIST_URL = "/yohosearch/ufo/selectionList.json";
String BRAND_LIST_URL = "/yohosearch/ufo/brandList.json";
String SERIES_LIST_URL = "/yohosearch/ufo/seriesList.json";
String SOON_SALE_PRODUCT_LIST_URL = "/yohosearch/ufo/soonSaleProductList.json";
String FAVORITE_PRODUCT_LIST_URL = "/yohosearch/ufo/favoriteProductList.json";
String PRODUCT_RECOMMEND_LIST_URL = "/yohosearch/ufo/recommendList.json";
String SALE_CALENDAR_LIST_URL = "/yohosearch/ufo/saleCalendarProductList.json";
String SALE_CALENDAR_COUNT_URL = "/yohosearch/ufo/SaleDateCountList.json";
String NEW_SALE_CALENDAR_LIST_URL = "/yohosearch/ufo/saleCalendarNewProductList.json";
String NEW_SALE_CALENDAR_COUNT_URL = "/yohosearch/ufo/saleDateNewCountList.json";
String HOT_SALE_LIST_URL = "/yohosearch/ufo/hotSaleProductList.json";
String PRODUCT_POOL_URL = "/yohosearch/ufo/pool/productList.json";
String PRODUCT_SEARCH_QUERY_URL = "/yohosearch/ufo/fuzzy/productList.json";
String PRODUCT_UVSCORE_LIST_URL = "/yohosearch/ufo/uvscore/productList.json";
String SUGGEST_URL = "/yohosearch/ufo/suggest.json";
String PRODUCT_RECOMMEND_BY_SERIESBRAND_LIST_URL = "/yohosearch/ufo/recommendBySeriesBrandList.json";
String SECONDHAND_SKUP_QUERY_URL = "/yohosearch/ufo/secondHand/skupList.json"; // 二手列表
}
... ...
... ... @@ -7,6 +7,7 @@ import java.util.UUID;
import com.yohobuy.ufo.model.enums.PoolIDConfigEnum;
import com.yohoufo.common.utils.StringUtil;
import com.yohoufo.product.service.impl.ProductSearchAssistService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -41,6 +42,8 @@ public class ProductSearchController {
private SearchHelpService searchHelpService;
@Autowired
private UfoServiceCaller ufoServiceCaller;
@Autowired
private ProductSearchAssistService productSearchAssistService;
@ApiOperation(name = "ufo.product.search.list", desc="首页商品推荐")
@RequestMapping(params = "method=ufo.product.search.list")
... ... @@ -84,7 +87,8 @@ public class ProductSearchController {
}
SortIdLevel sortIdLevel = productSearchService.getSortLevelById(sort);
ProductSearchReq req = new ProductSearchReq().setOrder(order).setId(id).setNot_id(notId).setPool(productPool).setBrand(brand)
.setSeries(series).setGender(gender).setSize(size).setIsSoonSale(isSoonSale).setCouponToken(couponToken).setViewNum(limit).setPage(page).setIsIdFilter(type).setSearchType(type).setBusinessClient(businessClient);
.setSeries(series).setGender(gender).setSize(size).setIsSoonSale(isSoonSale).setCouponToken(couponToken).setViewNum(limit).setPage(page)
.setIsIdFilter(type).setSearchType(type).setBusinessClient(businessClient);
searchHelpService.setQuery(query, req);
//设置是否包含有货商品
searchHelpService.setContainYoho(appVersion, req);
... ... @@ -106,14 +110,10 @@ public class ProductSearchController {
@RequestMapping(params = "method=ufo.product.data.search.recommend")
@IgnoreSession
@Cachable(expire = 180)
public ApiResponse searchProductRecommendById(@RequestParam(value = "product_id") Integer productId) {
if (null == productId) {
LOG.info("in method=ufo.product.data.search.recommend product_id is null");
return new ApiResponse(400, "product_id Is Null", null);
}
public ApiResponse searchProductRecommendById(@RequestParam(value = "product_id") Integer productId,
@RequestParam(value = "business_client", required = false) String businessClient) {
LOG.info("in method=ufo.product.data.search.recommend product_id={}", productId);
SearchProductRecommendResp resp = productSearchService.searchProductRecommendById(productId);
SearchProductRecommendResp resp = productSearchService.searchProductRecommendById(productId, businessClient);
return new ApiResponse.ApiResponseBuilder().code(200).message("product.data.search.recommend").data(resp).build();
}
... ... @@ -156,9 +156,8 @@ public class ProductSearchController {
@IgnoreSession
@Cachable(expire = 180)
public ApiResponse searchBrandList(@RequestParam(value = "business_client", required = false) String businessClient) {
LOG.info("in method=ufo.product.search.brandList businessClient is {}", businessClient);
SearchBrandListResp resp = productSearchService.searchBrandList(businessClient);
return new ApiResponse.ApiResponseBuilder().code(200).message("product.search.brandList").data(resp).build();
}
... ... @@ -172,8 +171,8 @@ public class ProductSearchController {
return new ApiResponse.ApiResponseBuilder().code(400).message("参数错误!").data(null).build();
}
LOG.info("in method=ufo.product.search.saleCalendar uid={}, start_time={}, end_time={}", uid, startTime, endTime);
Integer start = getValidTimestamp(startTime, true);
Integer end = getValidTimestamp(endTime, false);
Integer start = productSearchAssistService.getValidTimestamp(startTime, true);
Integer end = productSearchAssistService.getValidTimestamp(endTime, false);
if (start == null || end == null) {
return new ApiResponse.ApiResponseBuilder().code(400).message("参数错误!").data(null).build();
}
... ... @@ -203,8 +202,8 @@ public class ProductSearchController {
return new ApiResponse.ApiResponseBuilder().code(400).message("参数错误!").data(null).build();
}
LOG.info("in method=ufo.product.search.newSaleCalendar uid={}, start_time={}, end_time={}, type={}", uid, startTime, endTime, type);
Integer start = getValidTimestamp(startTime, true);
Integer end = getValidTimestamp(endTime, false);
Integer start = productSearchAssistService.getValidTimestamp(startTime, true);
Integer end = productSearchAssistService.getValidTimestamp(endTime, false);
if (start == null || end == null) {
return new ApiResponse.ApiResponseBuilder().code(400).message("参数错误!").data(null).build();
}
... ... @@ -229,15 +228,17 @@ public class ProductSearchController {
@IgnoreSession
@Cachable(expire = 180)
public ApiResponse searchHotSale(@RequestParam(value = "page", required = false)Integer page,
@RequestParam(value = "limit", required = false)Integer limit) {
@RequestParam(value = "limit", required = false)Integer limit,
@RequestParam(value = "business_client", required = false) String businessClient
) {
if (page == null || page < 1) {
page = 1;
}
if (limit == null || limit < 1) {
limit = 10;
}
LOG.info("in method=ufo.product.search.hotSale page={}, limit={}", page, limit);
JSONObject resp = productSearchService.searchHotSale(page, limit);
LOG.info("in method=ufo.product.search.hotSale page={}, limit={}, businessClient is {}", page, limit, businessClient);
JSONObject resp = productSearchService.searchHotSale(page, limit, businessClient);
return new ApiResponse.ApiResponseBuilder().code(200).message("product.search.hotSale").data(resp).build();
}
... ... @@ -260,9 +261,11 @@ public class ProductSearchController {
@RequestParam(value = "rankType", required = false, defaultValue = "a") String rankType,
@RequestParam(value = "limit", required = false, defaultValue = "20")Integer limit,
@RequestParam(value = "page", required = false)Integer page,
@RequestParam(value = "regularize", required = false)Integer regularize) {
@RequestParam(value = "regularize", required = false)Integer regularize,
@RequestParam(value = "business_client", required = false) String businessClient) {
ProductSearchReq req = new ProductSearchReq().setViewNum(limit).setPage(page).setRankType(rankType);
ProductSearchReq req = new ProductSearchReq().setViewNum(limit).setPage(page).setRankType(rankType)
.setBusinessClient(businessClient);
LOG.info("in method=ufo.product.search.uvscoreProductList req={}", req.toString());
JSONObject resp = productSearchService.searchUvscoreProductList(req, regularize);
... ... @@ -314,32 +317,9 @@ public class ProductSearchController {
return new ApiResponse.ApiResponseBuilder().code(200).message("Product List.").data(resp).build();
}
private Integer getValidTimestamp(String dateStr, boolean start) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
Calendar c = Calendar.getInstance();
String yearMonthStr = dateStr.substring(0, 7);
String dayStr = dateStr.substring(8);
c.setTime(sdf.parse(yearMonthStr));
int lastDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
int day = Math.min(lastDay, Integer.parseInt(dayStr));
c.set(Calendar.DAY_OF_MONTH, day);
if (start) {
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
} else {
c.set(Calendar.HOUR_OF_DAY, 23);
c.set(Calendar.MINUTE, 59);
c.set(Calendar.SECOND, 59);
}
return (int) (c.getTimeInMillis() / 1000);
} catch (Exception e) {
return null;
}
}
@ApiOperation(name = "ufo.product.search.appraise.list", desc="首页商品推荐")
@ApiOperation(name = "ufo.product.search.appraise.list", desc="鉴定实物的列表接口")
@RequestMapping(params = "method=ufo.product.search.appraise.list")
@IgnoreSession
@Cachable(expire = 180)
... ... @@ -347,9 +327,11 @@ public class ProductSearchController {
@RequestParam(value = "query", required = false)String query,
@RequestParam(value = "limit", required = false)Integer limit,
@RequestParam(value = "page", required = false)Integer page,
@RequestParam(value = "app_version", required = false)String appVersion
@RequestParam(value = "app_version", required = false)String appVersion,
@RequestParam(value = "business_client", required = false) String businessClient
) {
ProductSearchReq req = new ProductSearchReq().setViewNum(limit).setPage(page).setExcludeLimit("Y");
ProductSearchReq req = new ProductSearchReq().setViewNum(limit).setPage(page).setExcludeLimit("Y")
.setBusinessClient(businessClient);
searchHelpService.setQuery(query, req);
//设置是否包含有货商品
LOG.info("in method=ufo.product.search.appraise.list req={}", req.toString());
... ... @@ -364,9 +346,10 @@ public class ProductSearchController {
@RequestMapping(params = "method=ufo.product.data.search.recommendBySeriesBrand")
@IgnoreSession
@Cachable(expire = 600)
public ApiResponse searchProductRecommendBySeriesBrand(@RequestParam(value = "product_id") Integer productId) {
LOG.info("in method=ufo.product.data.search.recommendBySeriesBrand product_id={}", productId);
SearchProductRecommendResp resp = productSearchService.searchProductRecommendByIdAndSeriesBrand(productId);
public ApiResponse searchProductRecommendBySeriesBrand(@RequestParam(value = "product_id") Integer productId,
@RequestParam(value = "business_client", required = false) String businessClient) {
LOG.info("in method=ufo.product.data.search.recommendBySeriesBrand product_id={}, businessClient = {}", productId, businessClient);
SearchProductRecommendResp resp = productSearchService.searchProductRecommendByIdAndSeriesBrand(productId, businessClient);
return new ApiResponse.ApiResponseBuilder().code(200).message("product.data.search.recommendBySeriesBrand").data(resp).build();
}
... ... @@ -377,9 +360,10 @@ public class ProductSearchController {
public ApiResponse searchSecondhandSkupList(@RequestParam(value = "preSale_flag", required = false)Integer preSaleFlag,
@RequestParam(value = "productPool", required = false) String productPool,
@RequestParam(value = "limit", required = false)Integer limit,
@RequestParam(value = "page", required = false)Integer page) {
LOG.info("in method=ufo.product.search.secondhand.skupList preSale_flag={}", preSaleFlag);
ProductSearchReq req = new ProductSearchReq().setViewNum(limit).setPage(page).setPreSaleFlag(preSaleFlag).setPool(productPool);
@RequestParam(value = "page", required = false)Integer page,
@RequestParam(value = "business_client", required = false) String businessClient) {
ProductSearchReq req = new ProductSearchReq().setViewNum(limit).setPage(page).setPreSaleFlag(preSaleFlag).setBusinessClient(businessClient).setPool(productPool);
LOG.info("in method=ufo.product.search.secondhand.skupList req={}", req);
JSONObject resp = productSearchService.searchSecondhandSkupList(req);
return new ApiResponse.ApiResponseBuilder().code(200).message("secondhand skupList.").data(resp).build();
}
... ...
... ... @@ -100,7 +100,7 @@ public final class SearchConstants {
String EXCLUDE_LIMIT = "isFilterLimitSale";
String showChannel = "showChannel";
String SHOW_CHANNEL = "showChannel";
}
... ... @@ -117,5 +117,9 @@ public final class SearchConstants {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return value;
}
}
}
... ...
... ... @@ -247,6 +247,17 @@ public class SearchParam {
return this;
}
public SearchParam setShowChannel(String businessClient) {
if (StringUtils.isNotBlank(businessClient) && BusinessClientEnum.isXianYu(businessClient)) {
param.put(SearchConstants.IndexNameConstant.SHOW_CHANNEL,
SearchConstants.ShowChannelEnum.SHOW_CHANNEL_XIANYU.getValue());
} else {
param.put(SearchConstants.IndexNameConstant.SHOW_CHANNEL,
SearchConstants.ShowChannelEnum.SHOW_CHANNEL_UFO.getValue());
}
return this;
}
/**
* 每次查询的条数
*
... ...
... ... @@ -24,9 +24,9 @@ public class ProductSearchReq {
private Integer endTime;
private Integer searchType;
private String containYoho;//是否包含有货商品
private String rankType;
private String rankType; // a、b版本
private String couponToken;
private String excludeLimit;
private String excludeLimit; // 过滤限售的商品
private String not_brand;
private String businessClient;
private Integer preSaleFlag;
... ...
... ... @@ -21,14 +21,14 @@ public interface ProductSearchService {
SearchBrandListResp searchBrandList(String businessClient);
SearchProductRecommendResp searchProductRecommendById(Integer productId);
SearchProductRecommendResp searchProductRecommendById(Integer productId, String businessClient);
List<ProductBrandSeriesResp> searchSeriesList();
JSONObject searchSaleCalendar(Integer startTime, Integer endTime);
JSONObject searchNewSaleCalendar(Integer startTime, Integer endTime, String type);
JSONObject searchHotSale(Integer page, Integer limit);
JSONObject searchHotSale(Integer page, Integer limit, String businessClient);
void processUserFavoriteProductList(JSONObject productJSON, Integer uid);
... ... @@ -41,8 +41,8 @@ public interface ProductSearchService {
JSONObject searchAppraiseProductList(ProductSearchReq req);
SearchProductRecommendResp searchProductRecommendByIdAndSeriesBrand(Integer productId);
SearchProductRecommendResp searchProductRecommendByIdAndSeriesBrand(Integer productId, String businessClient);
JSONObject searchSecondhandSkupList(ProductSearchReq req);
}
... ...
package com.yohoufo.product.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.yoho.core.common.utils.DateUtil;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.core.rest.exception.ServiceNotAvaibleException;
import com.yohoufo.common.helper.ImageUrlAssist;
import com.yohoufo.common.utils.MathUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Created by li.ma on 2019/11/19.
*/
@Service
public class ProductSearchAssistService {
private static Logger logger = LoggerFactory.getLogger(ProductSearchAssistService.class);
@Autowired
ProductSalesService productSalesService;
@Value("${ip.port.search.server}")
private String searchServerIpAndPort;
@Autowired
private ServiceCaller serviceCaller;
public JSONObject search(Map<String, Object> searchParams, String url) {
logger.info("begin invoke search.productList, param is:{}, url is :{}", searchParams, url);
String resultJsonStr = null;
try {
resultJsonStr = serviceCaller.get("search.productList", "http://" + searchServerIpAndPort + url, searchParams, String.class, null).get(1);
} catch (Exception e) {
logger.warn("The result of search product list find wrong. url {}: ", url, e);
throw new ServiceNotAvaibleException("search server!!!", e);
}
JSONObject searchResult = null;
try {
searchResult = JSONObject.parseObject(resultJsonStr);
} catch (Exception e) {
logger.warn("The result of search product list is not string of json. result:{}", resultJsonStr, e);
return null;
}
if (null == searchResult) {
logger.warn("searchResult is null. params : {} ", searchParams);
return null;
}
// 取出搜索接口真实查询的列表结果
JSONObject data;
try {
data = searchResult.getJSONObject("data");
} catch (Exception e) {
logger.warn("The result of search product list is not string of json. searchResult:{}", searchResult, e);
return null;
}
if (null == data) {
logger.info("The data field of search product list is null. params : {} ", searchParams);
return null;
}
return data;
}
public Integer getValidTimestamp(String dateStr, boolean start) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
Calendar c = Calendar.getInstance();
String yearMonthStr = dateStr.substring(0, 7);
String dayStr = dateStr.substring(8);
c.setTime(sdf.parse(yearMonthStr));
int lastDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
int day = Math.min(lastDay, Integer.parseInt(dayStr));
c.set(Calendar.DAY_OF_MONTH, day);
if (start) {
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
} else {
c.set(Calendar.HOUR_OF_DAY, 23);
c.set(Calendar.MINUTE, 59);
c.set(Calendar.SECOND, 59);
}
return (int) (c.getTimeInMillis() / 1000);
} catch (Exception e) {
return null;
}
}
// NFC详情分享页列表要保证 3的倍数,这里做最后的保证
public void regularize(JSONArray productList) {
if(CollectionUtils.isEmpty(productList)){
return;
}
logger.info("method regularize in. productList.size() is {}", productList.size());
if (productList.size() % 3 == 1) {
productList.remove(productList.size() - 1);
} else if (productList.size() % 3 == 2) {
productList.remove(productList.size() - 1);
productList.remove(productList.size() - 2);
}
}
// 增加销量字段
protected void processProductSales(JSONArray productList) {
if(CollectionUtils.isEmpty(productList)){
return;
}
List<Integer> productIdList = new ArrayList<>();
// 遍历商品列表
for (int i = 0; i < productList.size(); i++) {
JSONObject product = productList.getJSONObject(i);
if(null == product){
continue;
}
productIdList.add(product.getInteger("id"));
}
Map<Integer, Integer> salesMap = productSalesService.selectAmountByProductIdList(productIdList);
// 遍历商品列表
for (int i = 0; i < productList.size(); i++) {
JSONObject product = productList.getJSONObject(i);
if (null == product) {
continue;
}
Integer amount = salesMap.get(product.getInteger("id"));
if (null == amount) {
continue;
}
product.put("sales", amount);
}
}
public void handlerPrice(JSONObject product) {
product.put("price", MathUtil.getIntCeilPrice(product.getDouble("price")));
JSONArray planList = product.getJSONArray("product_price_plan_list");
if(CollectionUtils.isEmpty(planList)){
return;
}
JSONObject effectPlan = getEffectProductPricePlan(planList);
//没有符合的价格计划,直接返回
if(null==effectPlan){
return;
}
if(null!=effectPlan.get("current_saleprice")){
product.replace("sales_price", MathUtil.getIntCeilPrice(effectPlan.getDouble("current_saleprice")));
}
if(null!=effectPlan.get("vip1_price")){
product.replace("vip1_price", effectPlan.getDouble("vip1_price"));
}
if(null!=effectPlan.get("vip2_price")){
product.replace("vip2_price", effectPlan.getDouble("vip2_price"));
}
if(null!=effectPlan.get("vip3_price")){
product.replace("vip3_price", effectPlan.getDouble("vip3_price"));
}
if(null!=effectPlan.get("vip_discount_type")){
product.replace("vip_discount_type", effectPlan.getInteger("vip_discount_type"));
}
if(null!=effectPlan.get("student_price") && !"Y".equalsIgnoreCase(product.getString("is_student_price"))){
product.replace("student_price", product.getBigDecimal("sales_price").multiply(new BigDecimal("0.9")));
}
}
/**
* 获取一个生效的变价计划
* @param list
* @return
*/
private JSONObject getEffectProductPricePlan(JSONArray planList){
if(CollectionUtils.isEmpty(planList)){
return null;
}
//先计算匹配到的价格计划,然后根据匹配到的价格计划求优先级
int currentTime= DateUtil.getCurrentTimeSecond();
logger.info("currentTime: {}", currentTime);
List<JSONObject> fitProductPricePlanList= Lists.newArrayList();
for (int i=0; i < planList.size(); i++) {
JSONObject item = planList.getJSONObject(i);
//当前时间大于等于生效时间且当前时间小于结束时间或没有结束时间的
if(currentTime>=item.getIntValue("effect_time") && (currentTime<=item.getIntValue("end_time")||item.getIntValue("end_time")==0)){
fitProductPricePlanList.add(item);
}
}
if(!CollectionUtils.isEmpty(fitProductPricePlanList)){
//在多个价格计划都满足的情况下,生效时间越大越靠前
Collections.sort(fitProductPricePlanList, new Comparator<JSONObject>() {
@Override
public int compare(JSONObject o1, JSONObject o2) {
if (o2.getInteger("effect_time").compareTo(o1.getInteger("effect_time")) == 0
&& null != o2.getInteger("create_time") && null != o1.getInteger("create_time")) {
return o2.getInteger("create_time").compareTo(o1.getInteger("create_time"));
}
return o2.getInteger("effect_time").compareTo(o1.getInteger("effect_time"));
}
});
return fitProductPricePlanList.get(0);
}
return null;
}
public String fillProductImgUrl(String imgUrl) {
if (StringUtils.isBlank(imgUrl)) {
return imgUrl;
}
if (imgUrl.startsWith("http://")) {
return imgUrl;
}
if (imgUrl.startsWith("https://")) {
return imgUrl;
}
return ImageUrlAssist.getAllProductPicUrl(imgUrl, "goodsimg", "center", "d2hpdGU=");
}
/**
* 对商品列表的信息进行修改,商品图片地址URL补全
*
*/
public void processProductList(JSONArray productList) {
if(CollectionUtils.isEmpty(productList)){
return;
}
// 遍历商品列表
for (int i = 0; i < productList.size(); i++) {
JSONObject product = productList.getJSONObject(i);
if(null == product){
continue;
}
// 处理图片,封面图设置
String default_images = fillProductImgUrl(MapUtils.getString(product, "default_images", ""));
product.replace("default_images", default_images);
//处理有货价格
if (StringUtils.equals(product.getString("is_yoho"), "Y")) {
handlerPrice(product);
}
}
}
/**
* 对二手商品列表的信息进行修改,商品图片地址URL补全
*
*/
public void processSecondhandSkupList(JSONArray skupList) {
if(CollectionUtils.isEmpty(skupList)){
return;
}
// 遍历商品列表
for (int i = 0; i < skupList.size(); i++) {
JSONObject product = skupList.getJSONObject(i);
if(null == product){
continue;
}
// 处理图片,封面图设置
String secondhand_image = fillProductImgUrl(MapUtils.getString(product, "secondhand_image", ""));
product.replace("secondhand_image", secondhand_image);
}
}
}
... ...
... ... @@ -10,6 +10,13 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.yoho.core.config.ConfigReader;
import com.yohobuy.ufo.model.promotion.response.CouponInfo;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.common.constant.BusinessClientEnum;
import com.yohoufo.common.utils.MathUtil;
import com.yohoufo.dal.product.BrandMapper;
import com.yohoufo.product.constants.ProductSearchConstants;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
... ... @@ -55,15 +62,8 @@ public class ProductSearchServiceImpl implements ProductSearchService {
private static Logger logger = LoggerFactory.getLogger(ProductSearchServiceImpl.class);
// 如果是NFC分享页面列表,则传1
private final static Integer REGULARIZE_NFC = 1;
private final static Integer REGULARIZE_NFC = 1; // 如果是NFC分享页面列表,则传1
@Value("${ip.port.search.server}")
private String searchServerIpAndPort;
@Autowired
private ServiceCaller serviceCaller;
@Autowired
private UfoServiceCaller ufoServiceCaller;
... ... @@ -74,86 +74,13 @@ public class ProductSearchServiceImpl implements ProductSearchService {
private BrandMapper brandMapper;
@Autowired
ProductSalesService productSalesService;
@Autowired
private ProductMapper productMapper;
@Autowired
private ConfigReader configReader;
@Autowired
private ProductHelpService productHelpService;
public static final String PRODUCT_LIST_URL = "/yohosearch/ufo/productList.json";
public static final String FILTER_LIST_URL = "/yohosearch/ufo/selectionList.json";
public static final String BRAND_LIST_URL = "/yohosearch/ufo/brandList.json";
public static final String SERIES_LIST_URL = "/yohosearch/ufo/seriesList.json";
public static final String SOON_SALE_PRODUCT_LIST_URL = "/yohosearch/ufo/soonSaleProductList.json";
public static final String FAVORITE_PRODUCT_LIST_URL = "/yohosearch/ufo/favoriteProductList.json";
public static final String PRODUCT_RECOMMEND_LIST_URL = "/yohosearch/ufo/recommendList.json";
public static final String SALE_CALENDAR_LIST_URL = "/yohosearch/ufo/saleCalendarProductList.json";
public static final String SALE_CALENDAR_COUNT_URL = "/yohosearch/ufo/SaleDateCountList.json";
public static final String NEW_SALE_CALENDAR_LIST_URL = "/yohosearch/ufo/saleCalendarNewProductList.json";
public static final String NEW_SALE_CALENDAR_COUNT_URL = "/yohosearch/ufo/saleDateNewCountList.json";
public static final String HOT_SALE_LIST_URL = "/yohosearch/ufo/hotSaleProductList.json";
public static final String PRODUCT_POOL_URL = "/yohosearch/ufo/pool/productList.json";
public static final String PRODUCT_SEARCH_QUERY_URL = "/yohosearch/ufo/fuzzy/productList.json";
public static final String PRODUCT_UVSCORE_LIST_URL = "/yohosearch/ufo/uvscore/productList.json";
public static final String SUGGEST_URL = "/yohosearch/ufo/suggest.json";
public static final String PRODUCT_RECOMMEND_BY_SERIESBRAND_LIST_URL = "/yohosearch/ufo/recommendBySeriesBrandList.json";
public static final String SECONDHAND_SKUP_QUERY_URL = "/yohosearch/ufo/secondHand/skupList.json";
private JSONObject search(Map<String, Object> searchParams, String url) {
logger.info("begin invoke search.productList, param is:{}, url is :{}", searchParams, url);
String resultJsonStr = null;
try {
resultJsonStr = serviceCaller.get("search.productList", "http://" + searchServerIpAndPort + url, searchParams, String.class, null).get(1);
} catch (Exception e) {
logger.warn("The result of search product list find wrong. url {}: ", url, e);
throw new ServiceNotAvaibleException("search server!!!", e);
}
JSONObject searchResult = null;
try {
searchResult = JSONObject.parseObject(resultJsonStr);
} catch (Exception e) {
logger.warn("The result of search product list is not string of json. result:{}", resultJsonStr, e);
return null;
}
if (null == searchResult) {
logger.warn("searchResult is null. params : {} ", searchParams);
return null;
}
// 取出搜索接口真实查询的列表结果
JSONObject data;
try {
data = searchResult.getJSONObject("data");
} catch (Exception e) {
logger.warn("The result of search product list is not string of json. searchResult:{}", searchResult, e);
return null;
}
if (null == data) {
logger.info("The data field of search product list is null. params : {} ", searchParams);
return null;
}
return data;
}
@Autowired
private ProductSearchAssistService searchAssistService;
@Override
public JSONObject searchProductList(ProductSearchReq req) {
... ... @@ -166,9 +93,9 @@ public class ProductSearchServiceImpl implements ProductSearchService {
// 3,品类; 4,品牌;5,系列;
// 6,搜索
// 7, 收藏 *
String url = PRODUCT_LIST_URL;
String url = ProductSearchConstants.PRODUCT_LIST_URL;
if (req.getSearchType() != null && req.getSearchType() == 8) {
url = PRODUCT_SEARCH_QUERY_URL;
url = ProductSearchConstants.PRODUCT_SEARCH_QUERY_URL;
CouponInfo info = getCouponInfo(req.getCouponToken());
if (info == null) {
JSONObject jo = new JSONObject();
... ... @@ -181,23 +108,26 @@ public class ProductSearchServiceImpl implements ProductSearchService {
req.setId(info.getContainsProductIds());
req.setNot_id(info.getExcludeProductIds());
logger.info("contains {} ex {}",info.getContainsProductIds(), info.getExcludeProductIds());
searchParam = new SearchParam().buildPageSearchParam(req);
searchParam = new SearchParam().buildPageSearchParam(req).setShowChannel(req.getBusinessClient());
} else if (StringUtils.equals("Y", req.getIsSoonSale())) {
url = SOON_SALE_PRODUCT_LIST_URL;
url = ProductSearchConstants.SOON_SALE_PRODUCT_LIST_URL;
} else if (StringUtils.equals("Y", req.getIsIdFilter())) {
url = FAVORITE_PRODUCT_LIST_URL;
url = ProductSearchConstants.FAVORITE_PRODUCT_LIST_URL;
} else if (StringUtils.isNotBlank(req.getQuery())
|| (req.getSearchType() != null && req.getSearchType() == 6)) {
url = PRODUCT_SEARCH_QUERY_URL;
searchParam.setShowChannel(req.getBusinessClient());
url = ProductSearchConstants.PRODUCT_SEARCH_QUERY_URL;
} else if (StringUtils.isNotBlank(req.getPool())
|| (req.getSearchType() != null && (req.getSearchType() == 0 || req.getSearchType() == 1))) {
url = PRODUCT_POOL_URL;
searchParam.setShowChannel(req.getBusinessClient());
url = ProductSearchConstants.PRODUCT_POOL_URL;
}
JSONObject data = search(searchParam.getParam(), url);
JSONObject data = searchAssistService.search(searchParam.getParam(), url);
// 将图片的相对路径转成绝对路径
if (null != data) {
processProductList(data.getJSONArray("product_list"));
processProductSales(data.getJSONArray("product_list"));
searchAssistService.processProductList(data.getJSONArray("product_list"));
searchAssistService.processProductSales(data.getJSONArray("product_list"));
}
return data;
... ... @@ -207,12 +137,12 @@ public class ProductSearchServiceImpl implements ProductSearchService {
public JSONObject searchAppraiseProductList(ProductSearchReq req) {
req.setNotBrand(StringUtils.join(brandMapper.selectExcludeAppraise(), ","));
SearchParam searchParam = new SearchParam().buildPageSearchParam(req);
String url = PRODUCT_SEARCH_QUERY_URL;
JSONObject data = search(searchParam.getParam(), url);
String url = ProductSearchConstants.PRODUCT_SEARCH_QUERY_URL;
JSONObject data = searchAssistService.search(searchParam.getParam(), url);
// 将图片的相对路径转成绝对路径
if (null != data) {
processProductList(data.getJSONArray("product_list"));
processProductSales(data.getJSONArray("product_list"));
searchAssistService.processProductList(data.getJSONArray("product_list"));
searchAssistService.processProductSales(data.getJSONArray("product_list"));
}
return data;
... ... @@ -221,88 +151,12 @@ public class ProductSearchServiceImpl implements ProductSearchService {
@Override
public JSONObject searchSuggest(ProductSearchReq req) {
SearchParam searchParam = new SearchParam().buildPageSearchParam(req);
JSONObject data = search(searchParam.getParam(), SUGGEST_URL);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.SUGGEST_URL);
return data;
}
/**
* 对商品列表的信息进行修改,商品图片地址URL补全
*
*/
protected void processProductList(JSONArray productList) {
if(CollectionUtils.isEmpty(productList)){
return;
}
// 遍历商品列表
for (int i = 0; i < productList.size(); i++) {
JSONObject product = productList.getJSONObject(i);
if(null == product){
continue;
}
// 处理图片,封面图设置
String default_images = fillProductImgUrl(MapUtils.getString(product, "default_images", ""));
product.replace("default_images", default_images);
//处理有货价格
if (StringUtils.equals(product.getString("is_yoho"), "Y")) {
handlerPrice(product);
}
}
}
/**
* 对二手商品列表的信息进行修改,商品图片地址URL补全
*
*/
protected void processSecondhandSkupList(JSONArray skupList) {
if(CollectionUtils.isEmpty(skupList)){
return;
}
// 遍历商品列表
for (int i = 0; i < skupList.size(); i++) {
JSONObject product = skupList.getJSONObject(i);
if(null == product){
continue;
}
// 处理图片,封面图设置
String secondhand_image = fillProductImgUrl(MapUtils.getString(product, "secondhand_image", ""));
product.replace("secondhand_image", secondhand_image);
}
}
public static void main(String[] args) {
System.out.println(fillProductImgUrl("https://img12.static.yhbimg.com/goodsimg/2019/04/17/17/021560b1bd437ded9a66dd15c29c81c53d.jpg"));
}
protected void processProductSales(JSONArray productList) {
if(CollectionUtils.isEmpty(productList)){
return;
}
List<Integer> productIdList = new ArrayList<>();
// 遍历商品列表
for (int i = 0; i < productList.size(); i++) {
JSONObject product = productList.getJSONObject(i);
if(null == product){
continue;
}
productIdList.add(product.getInteger("id"));
}
Map<Integer, Integer> salesMap = productSalesService.selectAmountByProductIdList(productIdList);
// 遍历商品列表
for (int i = 0; i < productList.size(); i++) {
JSONObject product = productList.getJSONObject(i);
if (null == product) {
continue;
}
Integer amount = salesMap.get(product.getInteger("id"));
if (null == amount) {
continue;
}
product.put("sales", amount);
}
}
@SuppressWarnings("unchecked")
@Override
public void processUserFavoriteProductList(JSONObject productJSON, Integer uid) {
... ... @@ -344,19 +198,6 @@ public class ProductSearchServiceImpl implements ProductSearchService {
}
}
private static String fillProductImgUrl(String imgUrl) {
if (StringUtils.isBlank(imgUrl)) {
return imgUrl;
}
if (imgUrl.startsWith("http://")) {
return imgUrl;
}
if (imgUrl.startsWith("https://")) {
return imgUrl;
}
return ImageUrlAssist.getAllProductPicUrl(imgUrl, "goodsimg", "center", "d2hpdGU=");
}
@Override
public SearchProductListFilterResp searchProductListFilter(ProductSearchReq req) {
if (StringUtils.isNotBlank(req.getCouponToken())) {
... ... @@ -367,11 +208,11 @@ public class ProductSearchServiceImpl implements ProductSearchService {
req.setId(info.getContainsProductIds());
req.setNot_id(info.getExcludeProductIds());
}
SearchParam searchParam = new SearchParam().buildSearchParam(req);
SearchParam searchParam = new SearchParam().buildSearchParam(req).setShowChannel(req.getBusinessClient());;
/*if (req.getMaxSort() == null && req.getMidSort() == null) {
searchParam.setXianYuSort(req.getBusinessClient(), configReader);
}*/
JSONObject data = search(searchParam.getParam(), FILTER_LIST_URL);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.FILTER_LIST_URL);
SearchProductListFilterResp resp = new SearchProductListFilterResp();
if (data != null) {
JSONObject filterData = data.getJSONObject("filter");
... ... @@ -470,10 +311,10 @@ public class ProductSearchServiceImpl implements ProductSearchService {
@Override
public SearchBrandListResp searchBrandList(String businessClient) {
SearchBrandListResp resp = new SearchBrandListResp();
SearchParam searchParam = new SearchParam();
SearchParam searchParam = new SearchParam().setShowChannel(businessClient);
//searchParam.setXianYuSort(businessClient, configReader); //闲鱼改成全品类 如果是闲鱼请求,则设置大品类
JSONObject data = search(searchParam.getParam(), BRAND_LIST_URL);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.BRAND_LIST_URL);
if(data != null && !CollectionUtils.isEmpty(data.getJSONArray("brand_list"))) {
resp = JSON.toJavaObject(data, SearchBrandListResp.class);
... ... @@ -488,16 +329,16 @@ public class ProductSearchServiceImpl implements ProductSearchService {
}
@Override
public SearchProductRecommendResp searchProductRecommendById(Integer productId) {
public SearchProductRecommendResp searchProductRecommendById(Integer productId, String businessClient) {
SearchProductRecommendResp resp = new SearchProductRecommendResp();
Product product = productMapper.selectByPrimaryKey(productId);
Product product = productHelpService.selectByIdCache(productId);
if (product != null) {
ProductSearchReq req = new ProductSearchReq().setNot_id(productId + "").setMidSort(product.getMidSortId() + "").setBrand(product.getBrandId() + "").setQuery(product.getProductName());
SearchParam searchParam = new SearchParam().buildSearchParam(req);
JSONObject data = search(searchParam.getParam(), PRODUCT_RECOMMEND_LIST_URL);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.PRODUCT_RECOMMEND_LIST_URL);
if(data != null && !CollectionUtils.isEmpty(data.getJSONArray("product_list"))) {
processProductSales(data.getJSONArray("product_list"));
searchAssistService.processProductSales(data.getJSONArray("product_list"));
resp = JSON.toJavaObject(data, SearchProductRecommendResp.class);
// 对品牌的log 进行相对路径转绝对路径
... ... @@ -537,7 +378,7 @@ public class ProductSearchServiceImpl implements ProductSearchService {
public List<ProductBrandSeriesResp> searchSeriesList() {
List<ProductBrandSeriesResp> respList = new ArrayList<>();
SearchParam searchParam = new SearchParam();
JSONObject data = search(searchParam.getParam(), SERIES_LIST_URL);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.SERIES_LIST_URL);
JSONArray series;
if (data != null && !CollectionUtils.isEmpty(series = data.getJSONArray("series_list"))) {
for (int i = 0; i < series.size(); i++) {
... ... @@ -566,12 +407,12 @@ public class ProductSearchServiceImpl implements ProductSearchService {
@Override
public JSONObject getSaleCalendarCountData() {
return getSaleCalendarCountData(SALE_CALENDAR_COUNT_URL, null);
return getSaleCalendarCountData(ProductSearchConstants.SALE_CALENDAR_COUNT_URL, null);
}
@Override
public JSONObject getNewSaleCalendarCountData(String type) {
return getSaleCalendarCountData(NEW_SALE_CALENDAR_COUNT_URL, type);
return getSaleCalendarCountData(ProductSearchConstants.NEW_SALE_CALENDAR_COUNT_URL, type);
}
private JSONObject getSaleCalendarCountData(String url, String type) {
... ... @@ -583,7 +424,7 @@ public class ProductSearchServiceImpl implements ProductSearchService {
type = "";
}
searchParam.setType(type);
countMap = search(searchParam.getParam(), url).getJSONObject("sale_date_count_list");
countMap = searchAssistService.search(searchParam.getParam(), url).getJSONObject("sale_date_count_list");
} catch (Exception e) {
logger.error("调用销售日历汇总数据出错: " + e.getMessage(), e);
}
... ... @@ -618,10 +459,10 @@ public class ProductSearchServiceImpl implements ProductSearchService {
ProductSearchReq req = new ProductSearchReq();
req.setStartTime(startTime).setEndTime(endTime);
SearchParam searchParam = new SearchParam().buildPageSearchParam(req);
JSONObject data = search(searchParam.getParam(), SALE_CALENDAR_LIST_URL);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.SALE_CALENDAR_LIST_URL);
// 将图片的相对路径转成绝对路径
if (null != data) {
processProductList(data.getJSONArray("product_list"));
searchAssistService.processProductList(data.getJSONArray("product_list"));
}
return data;
}
... ... @@ -636,129 +477,50 @@ public class ProductSearchServiceImpl implements ProductSearchService {
type = "";
}
searchParam.setType(type);
JSONObject data = search(searchParam.getParam(), NEW_SALE_CALENDAR_LIST_URL);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.NEW_SALE_CALENDAR_LIST_URL);
// 将图片的相对路径转成绝对路径
if (null != data) {
processProductList(data.getJSONArray("product_list"));
searchAssistService.processProductList(data.getJSONArray("product_list"));
}
return data;
}
@Override
public JSONObject searchHotSale(Integer page, Integer limit) {
public JSONObject searchHotSale(Integer page, Integer limit, String businessClient) {
ProductSearchReq req = new ProductSearchReq().setViewNum(limit).setPage(page);
SearchParam searchParam = new SearchParam().buildPageSearchParam(req);
JSONObject data = search(searchParam.getParam(), HOT_SALE_LIST_URL);
SearchParam searchParam = new SearchParam().buildPageSearchParam(req).setShowChannel(businessClient);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.HOT_SALE_LIST_URL);
// 将图片的相对路径转成绝对路径
if (null != data) {
processProductList(data.getJSONArray("product_list"));
processProductSales(data.getJSONArray("product_list"));
searchAssistService.processProductList(data.getJSONArray("product_list"));
searchAssistService.processProductSales(data.getJSONArray("product_list"));
}
return data;
}
public void handlerPrice(JSONObject product) {
product.put("price", getIntCeilPrice(product.getDouble("price")));
JSONArray planList = product.getJSONArray("product_price_plan_list");
if(CollectionUtils.isEmpty(planList)){
return;
}
JSONObject effectPlan = getEffectProductPricePlan(planList);
//没有符合的价格计划,直接返回
if(null==effectPlan){
return;
}
if(null!=effectPlan.get("current_saleprice")){
product.replace("sales_price", getIntCeilPrice(effectPlan.getDouble("current_saleprice")));
}
if(null!=effectPlan.get("vip1_price")){
product.replace("vip1_price", effectPlan.getDouble("vip1_price"));
}
if(null!=effectPlan.get("vip2_price")){
product.replace("vip2_price", effectPlan.getDouble("vip2_price"));
}
if(null!=effectPlan.get("vip3_price")){
product.replace("vip3_price", effectPlan.getDouble("vip3_price"));
}
if(null!=effectPlan.get("vip_discount_type")){
product.replace("vip_discount_type", effectPlan.getInteger("vip_discount_type"));
}
if(null!=effectPlan.get("student_price") && !"Y".equalsIgnoreCase(product.getString("is_student_price"))){
product.replace("student_price", product.getBigDecimal("sales_price").multiply(new BigDecimal("0.9")));
}
}
/**
* 获取一个生效的变价计划
* @param list
* @return
*/
private JSONObject getEffectProductPricePlan(JSONArray planList){
if(CollectionUtils.isEmpty(planList)){
return null;
}
//先计算匹配到的价格计划,然后根据匹配到的价格计划求优先级
int currentTime= DateUtil.getCurrentTimeSecond();
logger.info("currentTime: {}", currentTime);
List<JSONObject> fitProductPricePlanList=Lists.newArrayList();
for (int i=0; i < planList.size(); i++) {
JSONObject item = planList.getJSONObject(i);
//当前时间大于等于生效时间且当前时间小于结束时间或没有结束时间的
if(currentTime>=item.getIntValue("effect_time") && (currentTime<=item.getIntValue("end_time")||item.getIntValue("end_time")==0)){
fitProductPricePlanList.add(item);
}
}
if(!CollectionUtils.isEmpty(fitProductPricePlanList)){
//在多个价格计划都满足的情况下,生效时间越大越靠前
Collections.sort(fitProductPricePlanList, new Comparator<JSONObject>() {
@Override
public int compare(JSONObject o1, JSONObject o2) {
if(o2.getInteger("effect_time").compareTo(o1.getInteger("effect_time"))==0
&& null!=o2.getInteger("create_time") && null!=o1.getInteger("create_time")){
return o2.getInteger("create_time").compareTo(o1.getInteger("create_time"));
}
return o2.getInteger("effect_time").compareTo(o1.getInteger("effect_time"));
}
});
return fitProductPricePlanList.get(0);
}
return null;
}
//获取取整的价格
public static Integer getIntCeilPrice(Double price){
if(null == price) {
return 0;
}
return Double.valueOf(Math.ceil(price)).intValue();
}
@Override
public JSONObject searchUvscoreProductList(ProductSearchReq req, Integer regularize) {
if (REGULARIZE_NFC.equals(regularize)) { // NFC分享页列表 需要返回18个商品
req.setViewNum(18);
}
SearchParam searchParam = new SearchParam().buildPageSearchParam(req);
String url = PRODUCT_UVSCORE_LIST_URL;
JSONObject data = search(searchParam.getParam(), url);
SearchParam searchParam = new SearchParam().buildPageSearchParam(req).setShowChannel(req.getBusinessClient());
String url = ProductSearchConstants.PRODUCT_UVSCORE_LIST_URL;
JSONObject data = searchAssistService.search(searchParam.getParam(), url);
// 将图片的相对路径转成绝对路径
if (null != data) {
processProductList(data.getJSONArray("product_list"));
searchAssistService.processProductList(data.getJSONArray("product_list"));
if (REGULARIZE_NFC.equals(regularize)) { // NFC分享页列表 需要返回 3的倍数的列表且不需要销量
regularize(data.getJSONArray("product_list"));
searchAssistService.regularize(data.getJSONArray("product_list"));
} else {
processProductSales(data.getJSONArray("product_list")); // NFC分享页列表不需要销量
searchAssistService.processProductSales(data.getJSONArray("product_list")); // NFC分享页列表不需要销量
}
}
return data;
}
@Override
public SearchProductRecommendResp searchProductRecommendByIdAndSeriesBrand(Integer productId) {
public SearchProductRecommendResp searchProductRecommendByIdAndSeriesBrand(Integer productId, String businessClient) {
SearchProductRecommendResp resp = new SearchProductRecommendResp();
Product product = productHelpService.selectByIdCache(productId);
... ... @@ -769,11 +531,11 @@ public class ProductSearchServiceImpl implements ProductSearchService {
if(null != product.getSeriesId() && product.getSeriesId().intValue() != 0) {
req.setSeries(product.getSeriesId() + "");
}
SearchParam searchParam = new SearchParam().buildSearchParam(req);
SearchParam searchParam = new SearchParam().buildSearchParam(req).setShowChannel(businessClient);
JSONObject data = search(searchParam.getParam(), PRODUCT_RECOMMEND_BY_SERIESBRAND_LIST_URL);
JSONObject data = searchAssistService.search(searchParam.getParam(), ProductSearchConstants.PRODUCT_RECOMMEND_BY_SERIESBRAND_LIST_URL);
if(data != null && !CollectionUtils.isEmpty(data.getJSONArray("product_list"))) {
processProductSales(data.getJSONArray("product_list"));
searchAssistService.processProductSales(data.getJSONArray("product_list"));
resp = JSON.toJavaObject(data, SearchProductRecommendResp.class);
// 对品牌的log 进行相对路径转绝对路径
... ... @@ -789,31 +551,17 @@ public class ProductSearchServiceImpl implements ProductSearchService {
@Override
public JSONObject searchSecondhandSkupList(ProductSearchReq req) {
SearchParam searchParam = new SearchParam().buildPageSearchParam(req);
String url = SECONDHAND_SKUP_QUERY_URL;
JSONObject data = search(searchParam.getParam(), url);
SearchParam searchParam = new SearchParam().buildPageSearchParam(req).setShowChannel(req.getBusinessClient());
String url = ProductSearchConstants.SECONDHAND_SKUP_QUERY_URL;
JSONObject data = searchAssistService.search(searchParam.getParam(), url);
// 将图片的相对路径转成绝对路径
if (null != data) {
processSecondhandSkupList(data.getJSONArray("skup_list"));
searchAssistService.processSecondhandSkupList(data.getJSONArray("skup_list"));
}
return data;
}
// NFC详情分享页列表要保证 3的倍数,这里做最后的保证
private void regularize(JSONArray productList) {
if(CollectionUtils.isEmpty(productList)){
return;
}
logger.info("method regularize in. productList.size() is {}", productList.size());
if (productList.size() % 3 == 1) {
productList.remove(productList.size() - 1);
} else if (productList.size() % 3 == 2) {
productList.remove(productList.size() - 1);
productList.remove(productList.size() - 2);
}
}
private CouponInfo getCouponInfo(String token) {
ApiResponse resp = ufoServiceCaller.call("ufo.coupons.getProductIds", ApiResponse.class, token);
return (CouponInfo) resp.getData();
... ...
... ... @@ -136,7 +136,7 @@ public class ResourcesServiceImpl implements IResourcesService {
}
Stream<Resource> resourceStream = metadata.getResourcesContentDatas().stream().map(contentData -> Resource.builder()
.id(contentData.getPreContentId() == null ? contentData.getResourceContentId() : contentData.getPreContentId())
.id(contentData.getPreContentId() == null || contentData.getPreContentId() == 0 ? contentData.getResourceContentId() : contentData.getPreContentId())
.data(JSONObject.parseObject(contentData.getContentData()))
.gender(gender)
.clientType(clientType)
... ...