Authored by TANLING

优惠券限制

package com.yohoufo.common.helper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yohobuy.ufo.model.order.bo.ShoppingProductInfo;
import com.yohobuy.ufo.model.promotion.ConditionLimitValue;
import com.yohobuy.ufo.model.promotion.ConditionLimitValueReplacement;
import com.yohobuy.ufo.model.promotion.constant.CouponProductLimitTypeEnum;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Component
public class ConditionLimitValueProcessor implements InitializingBean {
private final static Logger logger = LoggerFactory.getLogger(ConditionLimitValueProcessor.class);
// key=限制类型,value=处理器
Map<String, LimitValueHandler> handlerMapOfType = Maps.newHashMap();
/**
* 将限制条件对象list展开
* @param conditionLimitValues
* @return
*/
public ConditionLimitValueReplacement flattenCondLimitValues(List<ConditionLimitValue> conditionLimitValues){
ConditionLimitValueReplacement productLimitInfo = new ConditionLimitValueReplacement();
if (CollectionUtils.isEmpty(conditionLimitValues)){
return productLimitInfo;
}
for (ConditionLimitValue conditionLimitValue : conditionLimitValues){
LimitValueHandler limitValueHandler = handlerMapOfType.get(String.valueOf(conditionLimitValue.getLimitType()));
if (limitValueHandler!=null){
limitValueHandler.setProductLimitValue(productLimitInfo, conditionLimitValue);
}
}
return productLimitInfo;
}
/**
* 该商品是否满足所有的限制条件
* @param shoppingProductInfo
* @param conditionLimitValues
* @return
*/
public boolean match(String couponCode,
ShoppingProductInfo shoppingProductInfo, List<ConditionLimitValue> conditionLimitValues){
for (ConditionLimitValue conditionLimitValue : conditionLimitValues){
LimitValueHandler limitValueHandler = handlerMapOfType.get(String.valueOf(conditionLimitValue.getLimitType()));
if (limitValueHandler == null){
continue;
}
if (!limitValueHandler.isMatch(shoppingProductInfo, conditionLimitValue)){
logger.info("[{}] ProductLimitRuleMatcher Condition <<< {},{}; Result <<< [{}] not matched",
couponCode, shoppingProductInfo, conditionLimitValue, limitValueHandler.getLimitValue());
return false;
}
}
logger.info("[{}] ProductLimitRuleMatcher Condition <<< {},{}; Result <<< matched", couponCode, shoppingProductInfo, conditionLimitValues);
return true;
}
@Override
public void afterPropertiesSet() throws Exception {
List<LimitValueHandler> limitValueHandlers = Lists.newArrayList();
limitValueHandlers.add(new BrandLimitValueHandler());
limitValueHandlers.add(new CategoryLimitValueHandler());
limitValueHandlers.add(new SeriesLimitValueHandler());
limitValueHandlers.add(new ProductExcludeLimitValueHandler());
limitValueHandlers.add(new ProductIncludeLimitValueHandler());
handlerMapOfType = limitValueHandlers.stream().collect(Collectors.toMap(LimitValueHandler::getLimitValue, Function.identity()));
}
public interface LimitValueHandler {
/**
* 商品限制类型
* @return
*/
String getLimitValue();
/**
* 商品限制的值
*/
void setProductLimitValue(ConditionLimitValueReplacement productLimitInfo, ConditionLimitValue conditionLimitValue);
/**
* 是否满足使用条件
* @return
*/
boolean isMatch(ShoppingProductInfo shoppingProductInfo, ConditionLimitValue conditionLimitValue);
}
private class BrandLimitValueHandler implements LimitValueHandler {
@Override
public String getLimitValue() {
return CouponProductLimitTypeEnum.SPECIFIC_BRAND.getLimitType();
}
@Override
public void setProductLimitValue(ConditionLimitValueReplacement productLimitInfo, ConditionLimitValue conditionLimitValue) {
productLimitInfo.setBrandInclude(conditionLimitValue.getLimitValues());
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ConditionLimitValue conditionLimitValue) {
return CollectionUtils.isNotEmpty(conditionLimitValue.getLimitValues())
&& conditionLimitValue.getLimitValues().contains(shoppingProductInfo.getBrandId());
}
}
private class CategoryLimitValueHandler implements LimitValueHandler {
@Override
public String getLimitValue() {
return CouponProductLimitTypeEnum.SPECIFIC_CATEGORY.getLimitType();
}
@Override
public void setProductLimitValue(ConditionLimitValueReplacement productLimitInfo, ConditionLimitValue conditionLimitValue) {
productLimitInfo.setCategoryInclude(conditionLimitValue.getLimitValues());
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ConditionLimitValue conditionLimitValue) {
return CollectionUtils.isNotEmpty(conditionLimitValue.getLimitValues())
&& conditionLimitValue.getLimitValues().contains(shoppingProductInfo.getCategoryId());
}
}
private class SeriesLimitValueHandler implements LimitValueHandler {
@Override
public String getLimitValue() {
return CouponProductLimitTypeEnum.SPECIFIC_SERIES.getLimitType();
}
@Override
public void setProductLimitValue(ConditionLimitValueReplacement productLimitInfo, ConditionLimitValue conditionLimitValue) {
productLimitInfo.setSeriesInclude((conditionLimitValue.getLimitValues()));
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ConditionLimitValue conditionLimitValue) {
return (CollectionUtils.isNotEmpty(conditionLimitValue.getLimitValues())
&& conditionLimitValue.getLimitValues().contains(shoppingProductInfo.getSeriesId()));
}
}
private class ProductIncludeLimitValueHandler implements LimitValueHandler {
@Override
public String getLimitValue() {
return CouponProductLimitTypeEnum.SPECIFIC_PRODUCT.getLimitType();
}
@Override
public void setProductLimitValue(ConditionLimitValueReplacement productLimitInfo, ConditionLimitValue conditionLimitValue) {
productLimitInfo.setProductIdInclude(conditionLimitValue.getLimitValues());
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ConditionLimitValue conditionLimitValue) {
//包含商品
return CollectionUtils.isNotEmpty(conditionLimitValue.getLimitValues())
&& conditionLimitValue.getLimitValues().contains(shoppingProductInfo.getProductId());
}
}
private class ProductExcludeLimitValueHandler implements LimitValueHandler {
@Override
public String getLimitValue() {
return CouponProductLimitTypeEnum.EXCLUDE_PRODUCT.getLimitType();
}
@Override
public void setProductLimitValue(ConditionLimitValueReplacement productLimitInfo, ConditionLimitValue conditionLimitValue) {
productLimitInfo.setProductIdExclude(conditionLimitValue.getLimitValues());
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ConditionLimitValue conditionLimitValue) {
//排除商品
return CollectionUtils.isNotEmpty(conditionLimitValue.getLimitValues())
&& !conditionLimitValue.getLimitValues().contains(shoppingProductInfo.getProductId());
}
}
}
... ...
package com.yohoufo.common.helper;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.order.bo.ShoppingProductInfo;
import com.yohobuy.ufo.model.promotion.constant.CouponProductLimitTypeEnum;
import com.yohobuy.ufo.model.promotion.request.ProductLimitValueBo;
import com.yohobuy.ufo.model.promotion.response.ProductLimitInfo;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class ProductLimitCollector {
private final static Logger logger = LoggerFactory.getLogger(ProductLimitCollector.class);
private static List<LimitValueHandler> LIMIT_VALUES_LIST = Lists.newArrayList();
static{
LIMIT_VALUES_LIST.add(new NoLimitValueHandler());
LIMIT_VALUES_LIST.add(new BrandLimitValueHandler());
LIMIT_VALUES_LIST.add(new CategoryLimitValueHandler());
LIMIT_VALUES_LIST.add(new SeriesLimitValueHandler());
LIMIT_VALUES_LIST.add(new ProductIncludeLimitValueHandler());
LIMIT_VALUES_LIST.add(new ProductExcludeLimitValueHandler());
}
public static ProductLimitInfo getProductLimitInfo(List<ProductLimitValueBo> productLimitValueBo, Integer productLimitType, String productLimitValue ){
ProductLimitInfo productLimitInfo = new ProductLimitInfo();
// 处理 排除&指定的商品
if (CollectionUtils.isNotEmpty(productLimitValueBo)){
for (ProductLimitValueBo item : productLimitValueBo){
Optional<LimitValueHandler> handler = LIMIT_VALUES_LIST.stream().filter(x->Integer.valueOf(x.getLimitValue().getLimitType()) == item.getLimitType()).findFirst();
if (handler.isPresent()){
handler.get().setProductLimitValue(productLimitInfo, item.getProductIds(), productLimitValue);
}
}
}
Optional<LimitValueHandler> limitValueHandler = LIMIT_VALUES_LIST.stream().filter(x->Integer.valueOf(x.getLimitValue().getLimitType()) == productLimitType).findFirst();
limitValueHandler.ifPresent(x->x.setProductLimitValue(productLimitInfo, null, productLimitValue));
return productLimitInfo;
}
/**
*
* @param shoppingProductInfo
* @param productLimitInfo
* @return
*/
public static boolean match(String couponCode,
ShoppingProductInfo shoppingProductInfo, ProductLimitInfo productLimitInfo){
for (LimitValueHandler limitValueHandler : LIMIT_VALUES_LIST){
if (!limitValueHandler.isMatch(shoppingProductInfo, productLimitInfo)){
logger.info("[{}] ProductLimitRuleMatcher Condition <<< {},{}; Result <<< [{}] not matched",
couponCode, shoppingProductInfo, productLimitInfo, limitValueHandler.getLimitValue());
return false;
}
}
logger.info("[{}] ProductLimitRuleMatcher Condition <<< {},{}; Result <<< matched", couponCode, shoppingProductInfo, productLimitInfo);
return true;
}
private static List<Integer> covertProductLimitValueList(String productLimitValue) {
List<Integer> limitValues = Lists.newArrayList();
try{
limitValues = Arrays.stream(productLimitValue.split(",")).map(Integer::valueOf).collect(Collectors.toList());
}catch (Exception e){
logger.warn("error happened. productLimitValue {}", productLimitValue);
}
return limitValues;
}
public interface LimitValueHandler {
/**
* 商品限制类型
* @return
*/
CouponProductLimitTypeEnum getLimitValue();
/**
* 商品限制的值
* @param productIds
* @param productLimitValue
*/
void setProductLimitValue(ProductLimitInfo productLimitInfo, List<Integer> productIds, String productLimitValue);
/**
* 是否满足使用条件
* @param productLimitInfo
* @return
*/
boolean isMatch(ShoppingProductInfo shoppingProductInfo, ProductLimitInfo productLimitInfo);
}
private static class NoLimitValueHandler implements LimitValueHandler {
@Override
public CouponProductLimitTypeEnum getLimitValue() {
return CouponProductLimitTypeEnum.NON;
}
@Override
public void setProductLimitValue(ProductLimitInfo productLimitInfo, List<Integer> productIds, String productLimitValue) {
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ProductLimitInfo productLimitInfo) {
return true;
}
}
private static class BrandLimitValueHandler implements LimitValueHandler {
@Override
public CouponProductLimitTypeEnum getLimitValue() {
return CouponProductLimitTypeEnum.SPECIFIC_BRAND;
}
@Override
public void setProductLimitValue(ProductLimitInfo productLimitInfo, List<Integer> productIds, String productLimitValue) {
productLimitInfo.setBrandInclude(covertProductLimitValueList(productLimitValue));
}
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ProductLimitInfo productLimitInfo) {
return CollectionUtils.isEmpty(productLimitInfo.getBrandInclude()) || (CollectionUtils.isNotEmpty(productLimitInfo.getBrandInclude())
&& productLimitInfo.getBrandInclude().contains(shoppingProductInfo.getBrandId()));
}
}
private static class CategoryLimitValueHandler implements LimitValueHandler {
@Override
public CouponProductLimitTypeEnum getLimitValue() {
return CouponProductLimitTypeEnum.SPECIFIC_CATEGORY;
}
@Override
public void setProductLimitValue(ProductLimitInfo productLimitInfo, List<Integer> productIds, String productLimitValue) {
productLimitInfo.setCategoryInclude(covertProductLimitValueList(productLimitValue));
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ProductLimitInfo productLimitInfo) {
return CollectionUtils.isEmpty(productLimitInfo.getCategoryInclude()) ||
(CollectionUtils.isNotEmpty(productLimitInfo.getCategoryInclude())
&& productLimitInfo.getCategoryInclude().contains(shoppingProductInfo.getCategoryId()));
}
}
private static class SeriesLimitValueHandler implements LimitValueHandler {
@Override
public CouponProductLimitTypeEnum getLimitValue() {
return CouponProductLimitTypeEnum.SPECIFIC_SERIES;
}
@Override
public void setProductLimitValue(ProductLimitInfo productLimitInfo, List<Integer> productIds, String productLimitValue) {
productLimitInfo.setSeriesInclude((covertProductLimitValueList(productLimitValue)));
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ProductLimitInfo productLimitInfo) {
return CollectionUtils.isEmpty(productLimitInfo.getSeriesInclude())
|| (CollectionUtils.isNotEmpty(productLimitInfo.getSeriesInclude())
&& productLimitInfo.getSeriesInclude().contains(shoppingProductInfo.getSeriesId()));
}
}
private static class ProductIncludeLimitValueHandler implements LimitValueHandler {
@Override
public CouponProductLimitTypeEnum getLimitValue() {
return CouponProductLimitTypeEnum.SPECIFIC_PRODUCT;
}
@Override
public void setProductLimitValue(ProductLimitInfo productLimitInfo, List<Integer> productIds, String productLimitValue) {
productLimitInfo.setProductIdInclude(productIds);
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ProductLimitInfo productLimitInfo) {
//包含商品
return CollectionUtils.isEmpty(productLimitInfo.getProductIdInclude())
|| (CollectionUtils.isNotEmpty(productLimitInfo.getProductIdInclude())
&& productLimitInfo.getProductIdInclude().contains(shoppingProductInfo.getProductId()));
}
}
private static class ProductExcludeLimitValueHandler implements LimitValueHandler {
@Override
public CouponProductLimitTypeEnum getLimitValue() {
return CouponProductLimitTypeEnum.EXCLUDE_PRODUCT;
}
@Override
public void setProductLimitValue(ProductLimitInfo productLimitInfo, List<Integer> productIds, String productLimitValue) {
productLimitInfo.setProductIdExclude(productIds);
}
@Override
public boolean isMatch(ShoppingProductInfo shoppingProductInfo, ProductLimitInfo productLimitInfo) {
//排除商品
return CollectionUtils.isEmpty(productLimitInfo.getProductIdExclude())
|| (CollectionUtils.isNotEmpty(productLimitInfo.getProductIdExclude())
&& !productLimitInfo.getProductIdExclude().contains(shoppingProductInfo.getProductId()));
}
}
}
... ... @@ -5,18 +5,20 @@ import com.yohobuy.ufo.model.order.constants.OrderConstant;
import com.yohobuy.ufo.model.order.constants.RegionEnum;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohobuy.ufo.model.promotion.UserCouponsBo;
import com.yohobuy.ufo.model.promotion.constant.CouponProductLimitTypeEnum;
import com.yohobuy.ufo.model.promotion.constant.CouponTypeEnum;
import com.yohobuy.ufo.model.promotion.constant.CouponUseLimitTypeEnum;
import com.yohoufo.common.helper.ProductLimitCollector;
import com.yohoufo.common.helper.ConditionLimitValueProcessor;
import com.yohoufo.order.charge.model.ChargeGoods;
import com.yohoufo.order.charge.model.CouponMatchResult;
import com.yohoufo.order.utils.LoggerUtils;
import org.apache.commons.collections.CollectionUtils;
import net.sf.oval.guard.Post;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.*;
... ... @@ -25,25 +27,15 @@ import java.util.*;
* 券匹配
*/
@Component
public class CouponRuleMatcher {
public class CouponRuleMatcher implements InitializingBean {
private final Logger logger = LoggerUtils.getBuyerOrderLogger();
private static List<IRuleMatcher> RULE_MATCHERS = new LinkedList<>();
private List<IRuleMatcher> RULE_MATCHERS = new LinkedList<>();
static {
// 商品匹配
RULE_MATCHERS.add(new ProductLimitRuleMatcher());
// 金额匹配
RULE_MATCHERS.add(new UseLimitRuleMatcher());
// skup type 匹配
RULE_MATCHERS.add(new SkupTypeRuleMatcher());
@Autowired
ConditionLimitValueProcessor conditionLimitValueProcessor;
// 是否寄存决定运费券
RULE_MATCHERS.add(new DepositRequirementRuleMatcher());
}
/**
* 匹配
... ... @@ -83,6 +75,21 @@ public class CouponRuleMatcher {
return matchResult;
}
@Override
public void afterPropertiesSet() throws Exception {
// 商品匹配
RULE_MATCHERS.add(new ProductLimitRuleMatcher());
// 金额匹配
RULE_MATCHERS.add(new UseLimitRuleMatcher());
// skup type 匹配
RULE_MATCHERS.add(new SkupTypeRuleMatcher());
// 是否寄存决定运费券
RULE_MATCHERS.add(new DepositRequirementRuleMatcher());
}
private interface IRuleMatcher {
/**
* 规则名称
... ... @@ -101,7 +108,7 @@ public class CouponRuleMatcher {
boolean match(ChargeGoods chargeGoods, UserCouponsBo couponsBo);
}
private static class ProductLimitRuleMatcher implements IRuleMatcher {
private class ProductLimitRuleMatcher implements IRuleMatcher {
@Override
public String ruleName() {
return "ProductLimit";
... ... @@ -110,12 +117,12 @@ public class CouponRuleMatcher {
@Override
public boolean match(ChargeGoods chargeGoods, UserCouponsBo couponsBo) {
return ProductLimitCollector.match(couponsBo.getCouponCode() ,chargeGoods.getShoppingProductInfo(), couponsBo.getProductLimitInfo());
return conditionLimitValueProcessor.match(couponsBo.getCouponCode() ,chargeGoods.getShoppingProductInfo(), couponsBo.getConditionLimitValues());
}
}
private static class UseLimitRuleMatcher implements IRuleMatcher {
private class UseLimitRuleMatcher implements IRuleMatcher {
@Override
public String ruleName() {
return "UseLimit";
... ... @@ -137,7 +144,7 @@ public class CouponRuleMatcher {
}
}
private static class SkupTypeRuleMatcher implements IRuleMatcher {
private class SkupTypeRuleMatcher implements IRuleMatcher {
private SkupForbidRuleMatcher skupForbidRuleMatcher = new SkupForbidRuleMatcher();
private SkupAllowRuleMatcher skupAllowRuleMatcher = new SkupAllowRuleMatcher();
... ... @@ -159,7 +166,7 @@ public class CouponRuleMatcher {
}
}
private static class SkupForbidRuleMatcher implements IRuleMatcher {
private class SkupForbidRuleMatcher implements IRuleMatcher {
@Override
public String ruleName() {
return "SkupForbid";
... ... @@ -185,7 +192,7 @@ public class CouponRuleMatcher {
}
}
private static class SkupAllowRuleMatcher implements IRuleMatcher{
private class SkupAllowRuleMatcher implements IRuleMatcher{
@Override
public String ruleName() {
... ... @@ -231,7 +238,7 @@ public class CouponRuleMatcher {
}
}
private static class DepositRequirementRuleMatcher implements IRuleMatcher{
private class DepositRequirementRuleMatcher implements IRuleMatcher{
@Override
... ...
... ... @@ -8,7 +8,7 @@ import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.core.rest.exception.ServiceNotAvaibleException;
import com.yohobuy.ufo.model.enums.StorageTypeEnum;
import com.yohobuy.ufo.model.promotion.response.CouponInfo;
import com.yohobuy.ufo.model.promotion.response.ProductLimitInfo;
import com.yohobuy.ufo.model.promotion.ConditionLimitValueReplacement;
import com.yohoufo.common.helper.ImageUrlAssist;
import com.yohoufo.common.utils.ArrayListUtil;
import com.yohoufo.common.utils.MathUtil;
... ... @@ -284,7 +284,7 @@ public class ProductSearchAssistService {
return;
}
ProductLimitInfo pLimitInfo = info.getProductLimitInfo();
ConditionLimitValueReplacement pLimitInfo = info.getProductLimitInfo();
req.setId(StringUtils.isEmpty(info.getContainsProductIds()) ? ArrayListUtil.listToStr(pLimitInfo.getProductIdInclude(), ",") : info.getContainsProductIds())
.setNot_id(StringUtils.isEmpty(info.getExcludeProductIds()) ? ArrayListUtil.listToStr(pLimitInfo.getProductIdExclude(), ",") : info.getExcludeProductIds())
... ...
package com.yohoufo.promotion.convert;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.promotion.ConditionLimitValue;
import com.yohobuy.ufo.model.promotion.CouponSimpleBo;
import com.yohobuy.ufo.model.promotion.UserCouponsBo;
import com.yohobuy.ufo.model.promotion.constant.*;
import com.yohobuy.ufo.model.promotion.request.ProductLimitValueBo;
import com.yohobuy.ufo.model.promotion.response.CouponInfo;
import com.yohobuy.ufo.model.promotion.response.ProductLimitInfo;
import com.yohoufo.common.helper.ProductLimitCollector;
import com.yohoufo.common.utils.BigDecimalHelper;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.promotion.model.Coupon;
import com.yohoufo.dal.promotion.model.CouponAndType;
import com.yohoufo.dal.promotion.model.CouponType;
import com.yohoufo.dal.promotion.model.UserCoupon;
import com.yohoufo.promotion.helper.ConditionLimitValueBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -22,7 +21,6 @@ import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class CouponConvert {
//3天的秒数
... ... @@ -31,15 +29,17 @@ public class CouponConvert {
private final static Logger logger = LoggerFactory.getLogger(CouponConvert.class);
/**
* 订单默认使用
* @param userCoupon
* @param coupon
* @param couponType
* @param productLimitValueBo
* @param conditionLimitValueBo
* @return
*/
public static UserCouponsBo covertCouponBo(UserCoupon userCoupon, Coupon coupon, CouponType couponType, List<ProductLimitValueBo> productLimitValueBo){
public static UserCouponsBo covertCouponBo(UserCoupon userCoupon, Coupon coupon, CouponType couponType, List<ConditionLimitValue> conditionLimitValues){
UserCouponsBo couponBo = new UserCouponsBo();
... ... @@ -47,7 +47,7 @@ public class CouponConvert {
couponBo.setCouponAmount(coupon.getCouponAmount());
couponBo.setCouponName(coupon.getCouponName());
couponBo.setProductLimitType(coupon.getProductLimitType()!=null ? String.valueOf(coupon.getProductLimitType()):"");
// couponBo.setProductLimitType(coupon.getProductLimitType()!=null ? String.valueOf(coupon.getProductLimitType()):"");
couponBo.setUseLimitType(coupon.getUseLimitType()!=null ? String.valueOf(coupon.getUseLimitType()) : "");
couponBo.setUseLimitValue(coupon.getUseLimitValue()!=null ? String.valueOf(coupon.getUseLimitValue()) : "");
... ... @@ -74,9 +74,7 @@ public class CouponConvert {
couponBo.setCouponTypeName(couponType.getCaption());
}
ProductLimitInfo productLimitInfo = ProductLimitCollector.getProductLimitInfo(productLimitValueBo, coupon.getProductLimitType(), coupon.getProductLimitValue());
couponBo.setProductLimitInfo(productLimitInfo);
couponBo.setConditionLimitValues(ConditionLimitValueBuilder.getAllConditionLimit(conditionLimitValues, coupon));
couponBo.setBusinessClient(coupon.getBusinessClient());
... ...
package com.yohoufo.promotion.helper;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.promotion.ConditionLimitValue;
import com.yohoufo.dal.promotion.model.Coupon;
import org.apache.commons.collections.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ConditionLimitValueBuilder {
/**
* 获取所有的限制
* @param conditionLimitValue
* @param coupon
*/
public static List<ConditionLimitValue> getAllConditionLimit(List<ConditionLimitValue> conditionLimitValue, Coupon coupon){
if (CollectionUtils.isEmpty(conditionLimitValue)){
conditionLimitValue = Lists.newArrayList();
}
List<Integer> conditionLimitType = conditionLimitValue.stream().map(ConditionLimitValue::getLimitType).collect(Collectors.toList());
if (conditionLimitType.contains(coupon.getProductLimitType())){
return conditionLimitValue;
}
// 不存在的限制类型才能继续添加到 限制条件集合中
conditionLimitValue.add(new ConditionLimitValue(coupon.getProductLimitType(),
Arrays.stream(coupon.getProductLimitValue().split(",")).map(Integer::valueOf).collect(Collectors.toList())));
return conditionLimitValue;
}
}
... ...
package com.yohoufo.promotion.service;
import com.yohobuy.ufo.model.promotion.request.ProductLimitValueBo;
import com.yohobuy.ufo.model.promotion.ConditionLimitValue;
import com.yohoufo.dal.promotion.model.Coupon;
import com.yohoufo.dal.promotion.model.CouponAndType;
import com.yohoufo.dal.promotion.model.CouponType;
... ... @@ -45,5 +45,5 @@ public interface ICouponCacheService {
* @param productLimitCouponIds
* @return
*/
public Map<Integer, List<ProductLimitValueBo>> getLimitProductValueWithCache(List<Integer> productLimitCouponIds);
public Map<Integer, List<ConditionLimitValue>> getLimitProductValueWithCache(List<Integer> productLimitCouponIds);
}
... ...
... ... @@ -4,7 +4,7 @@ package com.yohoufo.promotion.service.impl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yohobuy.ufo.model.promotion.request.ProductLimitValueBo;
import com.yohobuy.ufo.model.promotion.ConditionLimitValue;
import com.yohoufo.common.cache.CacheClient;
import com.yohoufo.dal.promotion.CouponMapper;
import com.yohoufo.dal.promotion.CouponProductLimitMapper;
... ... @@ -118,18 +118,18 @@ public class CouponCacheServiceImpl implements ICouponCacheService {
* @param productLimitCouponIds
* @return
*/
public Map<Integer, List<ProductLimitValueBo>> getLimitProductValueWithCache(List<Integer> productLimitCouponIds) {
Map<Integer, List<ProductLimitValueBo>> result = Maps.newHashMap();
public Map<Integer, List<ConditionLimitValue>> getLimitProductValueWithCache(List<Integer> productLimitCouponIds) {
Map<Integer, List<ConditionLimitValue>> result = Maps.newHashMap();
List<Integer> missCouponIdList = Lists.newArrayList();
for (Integer couponId : productLimitCouponIds){
List<ProductLimitValueBo> productIds = cacheClient.range(KeyBuilder.buildCouponLimitProductValueCacheKey(couponId), ProductLimitValueBo.class,0, -1);
List<ConditionLimitValue> limitValues = cacheClient.range(KeyBuilder.buildCouponLimitProductValueCacheKey(couponId), ConditionLimitValue.class,0, -1);
if (CollectionUtils.isEmpty(productIds)){
if (CollectionUtils.isEmpty(limitValues)){
missCouponIdList.add(couponId);
}else{
result.put(couponId, productIds);
result.put(couponId, limitValues);
}
}
... ... @@ -137,7 +137,7 @@ public class CouponCacheServiceImpl implements ICouponCacheService {
return result;
}
Map<Integer, List<ProductLimitValueBo>> resultCache = getAssociatedProductLimitValueMap(missCouponIdList);
Map<Integer, List<ConditionLimitValue>> resultCache = getAssociatedProductLimitValueMap(missCouponIdList);
result.putAll(resultCache);
for (Integer key : resultCache.keySet()){
... ... @@ -154,7 +154,7 @@ public class CouponCacheServiceImpl implements ICouponCacheService {
* @param couponIdList
* @return
*/
private Map<Integer, List<ProductLimitValueBo>> getAssociatedProductLimitValueMap(List<Integer> couponIdList){
private Map<Integer, List<ConditionLimitValue>> getAssociatedProductLimitValueMap(List<Integer> couponIdList){
List<CouponProductLimit> couponProductLimitList = couponProductLimitMapper.selectByCouponIds(couponIdList);
... ... @@ -162,21 +162,19 @@ public class CouponCacheServiceImpl implements ICouponCacheService {
Map<Integer, List<CouponProductLimit>> map = couponProductLimitList.stream().collect(Collectors.groupingBy(CouponProductLimit::getCouponId));
// key=couponId, value=
Map<Integer, List<ProductLimitValueBo>> productLimitValueBoMap = Maps.newHashMap();
Map<Integer, List<ConditionLimitValue>> productLimitValueBoMap = Maps.newHashMap();
for (Integer couponId : map.keySet()){
List<ProductLimitValueBo> productLimitValueBos = Lists.newArrayList();
List<ConditionLimitValue> conditionLimitValues = Lists.newArrayList();
// key=limitType, value=
Map<Integer, List<CouponProductLimit>> typeToItem = map.get(couponId).stream().collect(Collectors.groupingBy(CouponProductLimit::getLimitType));
for (Integer type : typeToItem.keySet()){
productLimitValueBos.add(ProductLimitValueBo.builder()
.limitType(type)
.productIds(typeToItem.get(type).stream().map(CouponProductLimit::getProductId).collect(Collectors.toList())).build());
conditionLimitValues.add(new ConditionLimitValue(type, typeToItem.get(type).stream().map(CouponProductLimit::getProductId).collect(Collectors.toList())));
}
productLimitValueBoMap.put(couponId, productLimitValueBos);
productLimitValueBoMap.put(couponId, conditionLimitValues);
}
... ...
... ... @@ -12,17 +12,17 @@ import com.yohobuy.ufo.model.promotion.UserCouponsListBo;
import com.yohobuy.ufo.model.promotion.constant.CouponProductLimitTypeEnum;
import com.yohobuy.ufo.model.promotion.constant.CouponUseStatusEnum;
import com.yohobuy.ufo.model.promotion.constant.CouponsStatusEnum;
import com.yohobuy.ufo.model.promotion.request.ProductLimitValueBo;
import com.yohobuy.ufo.model.promotion.ConditionLimitValue;
import com.yohoufo.dal.promotion.CouponProductLimitMapper;
import com.yohoufo.promotion.helper.ConditionLimitValueBuilder;
import com.yohoufo.promotion.model.CouponReceiveChannel;
import com.yohobuy.ufo.model.promotion.request.CouponSendType;
import com.yohobuy.ufo.model.promotion.request.UserCouponListReq;
import com.yohobuy.ufo.model.promotion.response.CouponInfo;
import com.yohobuy.ufo.model.promotion.response.CouponInfoListBo;
import com.yohobuy.ufo.model.promotion.response.CouponSendBo;
import com.yohobuy.ufo.model.promotion.response.ProductLimitInfo;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.common.helper.ProductLimitCollector;
import com.yohoufo.common.helper.ConditionLimitValueProcessor;
import com.yohoufo.common.lock.RedisLock;
import com.yohoufo.common.lock.RedisLockFactory;
import com.yohoufo.common.utils.DateUtil;
... ... @@ -40,7 +40,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.Array;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
... ... @@ -74,6 +73,9 @@ public class CouponServiceImpl implements ICouponService {
@Autowired
private RedisLockFactory redisLockFactory;
@Autowired
ConditionLimitValueProcessor conditionLimitValueProcessor;
private final Logger logger = LoggerFactory.getLogger(getClass());
... ... @@ -103,14 +105,12 @@ public class CouponServiceImpl implements ICouponService {
// info.setExcludeProductIds(productIds);
// }
List<ProductLimitValueBo> productLimitValueBo = null;
Map<Integer, List<ProductLimitValueBo>> productLimitValueBoMap = getAssociatedProductIdMap(Arrays.asList(coupon));
if (productLimitValueBoMap != null){
productLimitValueBo = productLimitValueBoMap.get(coupon.getId());
}
Map<Integer, List<ConditionLimitValue>> productLimitValueBoMap = getConditionLimitMap(Arrays.asList(coupon));
List<ConditionLimitValue> conditionLimitValue = ConditionLimitValueBuilder.getAllConditionLimit(productLimitValueBoMap.get(coupon.getId()), coupon);
CouponInfo info = new CouponInfo();
info.setProductLimitInfo(ProductLimitCollector.getProductLimitInfo(productLimitValueBo, coupon.getProductLimitType(), coupon.getProductLimitValue()));
info.setProductLimitInfo(conditionLimitValueProcessor.flattenCondLimitValues(conditionLimitValue));
return info;
}
... ... @@ -433,7 +433,7 @@ public class CouponServiceImpl implements ICouponService {
// 优惠券商品限制 key=couponId, value=ProductId集合
// final Map<Integer, List<Integer>> couponProductIdMap = getAssociatedProductIdListMap(couponList);
Map<Integer, List<ProductLimitValueBo>> productLimitValueBoMap = getAssociatedProductIdMap(couponList);
Map<Integer, List<ConditionLimitValue>> productLimitValueBoMap = getConditionLimitMap(couponList);
//包装返回结果
List<UserCouponsBo> couponBoList = list.stream()
... ... @@ -449,7 +449,7 @@ public class CouponServiceImpl implements ICouponService {
* @param couponList
* @return
*/
private Map<Integer, List<ProductLimitValueBo>> getAssociatedProductIdMap(List<Coupon> couponList){
private Map<Integer, List<ConditionLimitValue>> getConditionLimitMap(List<Coupon> couponList){
if (CollectionUtils.isEmpty(couponList)){
return Maps.newHashMap();
... ... @@ -504,7 +504,7 @@ public class CouponServiceImpl implements ICouponService {
// 优惠券商品限制 key=couponId, value=ProductId集合
// Map<Integer, List<Integer>> couponProductIdMap = getAssociatedProductIdListMap(couponList);
Map<Integer, List<ProductLimitValueBo>> productLimitValueBoMap = getAssociatedProductIdMap(couponList);
Map<Integer, List<ConditionLimitValue>> productLimitValueBoMap = getConditionLimitMap(couponList);
int time = DateUtil.getCurrentTimeSecond();
... ... @@ -547,12 +547,12 @@ public class CouponServiceImpl implements ICouponService {
return UserCouponsListBo.builder().coupons(couponBoList).build();
}
private UserCouponsBo wrapperUserCoupon(final UserCoupon userCoupon, final Coupon coupon, final List<ProductLimitValueBo> productLimitValueBo) {
private UserCouponsBo wrapperUserCoupon(final UserCoupon userCoupon, final Coupon coupon, final List<ConditionLimitValue> conditionLimitValue) {
// 单个获取couponType
CouponType couponType = couponCacheService.getCouponTypeWithCache(userCoupon.getCouponType() != null ? userCoupon.getCouponType().intValue() : null);
UserCouponsBo couponBo = CouponConvert.covertCouponBo(userCoupon, coupon, couponType, productLimitValueBo);
UserCouponsBo couponBo = CouponConvert.covertCouponBo(userCoupon, coupon, couponType, conditionLimitValue);
return couponBo;
}
... ...