Authored by TANLING

商品详情页过滤掉优惠券限制条件

... ... @@ -58,11 +58,12 @@ public class ConditionLimitValueProcessor implements InitializingBean {
/**
* 该商品是否满足所有的限制条件
* @param shoppingProductInfo
* @param conditionLimitValues
* @param couponMark 券标识
* @param shoppingProductInfo 商品信息
* @param conditionLimitValues 券的全部限制条件
* @return
*/
public boolean match(String couponCode,
public boolean match(String couponMark,
ShoppingProductInfo shoppingProductInfo, List<ConditionLimitValue> conditionLimitValues){
for (ConditionLimitValue conditionLimitValue : conditionLimitValues){
... ... @@ -74,12 +75,12 @@ public class ConditionLimitValueProcessor implements InitializingBean {
if (!limitValueHandler.isMatch(shoppingProductInfo, conditionLimitValue)){
logger.info("[{}] ProductLimitRuleMatcher Condition <<< {},{}; Result <<< [{}] not matched",
couponCode, shoppingProductInfo, conditionLimitValue, limitValueHandler.getLimitValue());
couponMark, shoppingProductInfo, conditionLimitValue, limitValueHandler.getLimitValue());
return false;
}
}
logger.info("[{}] ProductLimitRuleMatcher Condition <<< {},{}; Result <<< matched", couponCode, shoppingProductInfo, conditionLimitValues);
logger.info("[{}] ProductLimitRuleMatcher Condition <<< {},{}; Result <<< matched", couponMark, shoppingProductInfo, conditionLimitValues);
return true;
}
... ...
... ... @@ -47,15 +47,15 @@
from coupon cpn
LEFT JOIN `coupon_display` cdp ON cpn.`id` = cdp.coupon_id
WHERE cpn.status = 1
AND cpn.id IN
(<include refid="query_prd_limit"/> )
<!--AND cpn.id IN-->
<!--(<include refid="query_prd_limit"/> )-->
AND cpn.`coupon_num` > cpn.`send_num`
AND cdp.position_type= #{positionType} AND cdp.`visibility`=1
AND (#{currentTime} <![CDATA[ < ]]> `end_time` OR #{currentTime} <![CDATA[ < ]]> `receive_end_time`)
and receive_start_time <![CDATA[ <= ]]> #{currentTime}
AND `business_client` LIKE CONCAT('%',#{businessClient},'%')
ORDER BY coupon_type,use_limit_type,`coupon_amount` DESC
limit #{offset},#{limit}
<!-- limit #{offset},#{limit} -->
</select>
<select id="selectCntByAssociatedPrd" resultType="int">
... ... @@ -83,25 +83,25 @@
from coupon cpn
LEFT JOIN `coupon_display` cdp ON cpn.`id` = cdp.coupon_id
WHERE cpn.status = 1
AND cpn.id IN
(<include refid="query_prd_limit_coupon_use_limit_type"/> )
<!--AND cpn.id IN-->
<!--(<include refid="query_prd_limit_coupon_use_limit_type"/> )-->
AND cpn.`coupon_num` > cpn.`send_num`
AND cdp.position_type= #{positionType} AND cdp.`visibility`=1
AND (#{currentTime} <![CDATA[ < ]]> `end_time` OR #{currentTime} <![CDATA[ < ]]> `receive_end_time`)
and receive_start_time <![CDATA[ <= ]]> #{currentTime}
AND `business_client` LIKE CONCAT('%',#{businessClient},'%')
ORDER BY `coupon_amount` DESC
limit #{offset},#{limit}
</select>
<!-- limit #{offset},#{limit} -->
</select>
<sql id="query_prd_limit_coupon_use_limit_type">
SELECT DISTINCT cpn.id FROM coupon cpn
LEFT JOIN `coupon_product_limit` cpl ON cpl.`coupon_id` = cpn.id
WHERE coupon_type = #{couponType}
<if test="useLimitType != null">
and use_limit_type = #{useLimitType}
</if>
and ((cpn.`product_limit_type` = 1 AND cpl.`product_id` = #{productId}) OR (cpn.`product_limit_type` = 3 AND cpl.`product_id` != #{productId}) OR cpn.`product_limit_type` =2)
</sql>
<sql id="query_prd_limit_coupon_use_limit_type">
SELECT DISTINCT cpn.id FROM coupon cpn
LEFT JOIN `coupon_product_limit` cpl ON cpl.`coupon_id` = cpn.id
WHERE coupon_type = #{couponType}
<if test="useLimitType != null">
and use_limit_type = #{useLimitType}
</if>
and ((cpn.`product_limit_type` = 1 AND cpl.`product_id` = #{productId}) OR (cpn.`product_limit_type` = 3 AND cpl.`product_id` != #{productId}) OR cpn.`product_limit_type` =2)
</sql>
</mapper>
\ No newline at end of file
</mapper>
\ No newline at end of file
... ...
... ... @@ -50,6 +50,10 @@
<groupId>com.yoho.ufo.model</groupId>
<artifactId>promotion-ufo-model</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.ufo.model</groupId>
<artifactId>product-ufo-model</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
... ...
package com.yohoufo.promotion.service;
import com.yohobuy.ufo.model.ProductInfo;
import com.yohobuy.ufo.model.order.bo.ShoppingProductInfo;
import com.yohobuy.ufo.model.promotion.ConditionLimitValue;
import com.yohoufo.common.helper.ConditionLimitValueProcessor;
import com.yohoufo.dal.promotion.model.Coupon;
import com.yohoufo.promotion.helper.ConditionLimitValueBuilder;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
public class ProductLimitValueFilter {
@Autowired
ProxyService proxyService;
@Autowired
ICouponCacheService couponCacheService;
@Autowired
ConditionLimitValueProcessor conditionLimitValueProcessor;
/**
* 根据商品过滤可用的优惠券
* @param couponList
* @param productId
* @return
*/
public List<Coupon> filter(List<Coupon> couponList, Integer productId){
if (CollectionUtils.isEmpty(couponList)){
return couponList;
}
// 获取商品的品牌、品类、系列信息
ProductInfo productInfo = proxyService.getProductInfo(productId);
ShoppingProductInfo shoppingProductInfo = ShoppingProductInfo.builder()
.productId(productInfo.getProductId())
.brandId(productInfo.getBrandId())
.seriesId(productInfo.getSeriesId())
.categoryId(productInfo.getMidSortId())
.build();
// 查询商品限制条件
Map<Integer, List<ConditionLimitValue>> productLimitMap =
couponCacheService.getLimitProductValueWithCache(couponList.stream().map(Coupon::getId).collect(Collectors.toList()));
couponList = couponList.stream()
.filter(coupon -> conditionLimitValueProcessor.match(
String.valueOf(coupon.getId()), shoppingProductInfo, ConditionLimitValueBuilder.getAllConditionLimit(productLimitMap.get(coupon.getId()),coupon)))
.limit(20)
.collect(Collectors.toList());
return couponList;
}
}
... ...
package com.yohoufo.promotion.service;
import com.yohobuy.ufo.model.ProductInfo;
import com.yohoufo.common.caller.UfoServiceCaller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProxyService {
final Logger logger = LoggerFactory.getLogger(getClass());
//skn维度的商品信息
private static final String PRODUCT_INFO_DATA = "ufo.product.info.data";
@Autowired
UfoServiceCaller ufoServiceCaller;
public ProductInfo getProductInfo(int productId){
final String api = PRODUCT_INFO_DATA;
ProductInfo prd = null;
try {
prd = ufoServiceCaller.call(api, productId);
}catch (Exception ex){
logger.warn("call {} fail, productId {}, {}", api, productId, ex);
}finally {
return prd;
}
}
}
... ...
... ... @@ -14,6 +14,7 @@ import com.yohoufo.dal.promotion.model.Coupon;
import com.yohoufo.dal.promotion.model.CouponQueryParamOfUseLimitType;
import com.yohoufo.dal.promotion.model.UserCoupon;
import com.yohoufo.promotion.convert.CouponConvert;
import com.yohoufo.promotion.service.ProductLimitValueFilter;
import com.yohoufo.promotion.service.cache.CollectiveCouponCacheService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
... ... @@ -43,6 +44,10 @@ public class CollectiveCouponService {
@Autowired
private UserCouponMapper userCouponMapper;
@Autowired
ProductLimitValueFilter productLimitValueFilter;
/**
* TODO use cache
* @param req
... ... @@ -79,10 +84,14 @@ public class CollectiveCouponService {
List<Coupon> datas= couponViewMapper.selectByAssociatedPrd(req.getBusinessClient(),prdId, positionType,currentDT,offset,limit);
//when user login, show user coupon
// 对商品进行过滤
datas = productLimitValueFilter.filter(datas, prdId);
final Integer uid = req.getUid();
boolean showUserReceive = req.isShowReceive() && Objects.nonNull(uid);
List<Coupon> finalDatas = datas;
Supplier<Map<Integer, UserCoupon>> couponMapSupplier = ()-> {
Set<Integer> couponIds = datas.stream().map(Coupon::getId).collect(Collectors.toSet());
Set<Integer> couponIds = finalDatas.stream().map(Coupon::getId).collect(Collectors.toSet());
return buildCouponIdUserCouponMap(uid, couponIds);
};
final Map<Integer, UserCoupon> couponIdUserCouponMap = showUserReceive ? couponMapSupplier.get()
... ... @@ -216,6 +225,10 @@ public class CollectiveCouponService {
break;
}
}
return datas;
return productLimitValueFilter.filter(datas, req.getProductId());
}
}
... ...