Authored by wujiexiang

优惠券优化 -- 券条件新增

@@ -168,8 +168,14 @@ public class ChargeService { @@ -168,8 +168,14 @@ public class ChargeService {
168 168
169 switch (chargeParam.getChargeStage()) { 169 switch (chargeParam.getChargeStage()) {
170 case PAYMENT: { 170 case PAYMENT: {
  171 + if (CollectionUtils.isEmpty(couponCodes)) {
  172 + //场景:砍价活动不需要推荐
  173 + return;
  174 + }
  175 + //在推荐情况是否需要自动使用券,根据apiVersion来使用
  176 + boolean useCoupon = new Payment.AUTO_RECOMMEND_AND_USE_COUPON().apply(Payment.of(chargeParam.getApiVersion()));
171 //自动匹配 177 //自动匹配
172 - calculateRecommendedCoupons(chargeContext); 178 + calculateRecommendedCoupons(useCoupon, chargeContext);
173 break; 179 break;
174 } 180 }
175 case SELECT_COUPON: 181 case SELECT_COUPON:
@@ -190,15 +196,15 @@ public class ChargeService { @@ -190,15 +196,15 @@ public class ChargeService {
190 196
191 /** 197 /**
192 * 推荐券 198 * 推荐券
  199 + * @param useCoupon
193 * @param chargeContext 200 * @param chargeContext
194 */ 201 */
195 - private void calculateRecommendedCoupons(ChargeContext chargeContext) { 202 + private void calculateRecommendedCoupons(boolean useCoupon, ChargeContext chargeContext) {
196 List<CouponMatchResult> usableCouponMatchResults = couponService.getRecommendedCoupons(chargeContext); 203 List<CouponMatchResult> usableCouponMatchResults = couponService.getRecommendedCoupons(chargeContext);
197 //可用张数 204 //可用张数
198 chargeContext.getChargeResult().getCouponPayResultList().setUsableCouponCount(usableCouponMatchResults.size()); 205 chargeContext.getChargeResult().getCouponPayResultList().setUsableCouponCount(usableCouponMatchResults.size());
199 206
200 - //在推荐情况是否需要自动使用券,根据apiVersion来使用  
201 - if (new Payment.AUTO_RECOMMEND_AND_USE_COUPON().apply(Payment.of(chargeContext.getChargeParam().getApiVersion()))) { 207 + if (useCoupon) {
202 doCalculateCoupons(usableCouponMatchResults, chargeContext); 208 doCalculateCoupons(usableCouponMatchResults, chargeContext);
203 } 209 }
204 } 210 }
@@ -7,6 +7,7 @@ import com.yohobuy.ufo.model.promotion.constant.CouponUseLimitTypeEnum; @@ -7,6 +7,7 @@ import com.yohobuy.ufo.model.promotion.constant.CouponUseLimitTypeEnum;
7 import com.yohoufo.order.charge.model.ChargeGoods; 7 import com.yohoufo.order.charge.model.ChargeGoods;
8 import com.yohoufo.order.charge.model.CouponMatchResult; 8 import com.yohoufo.order.charge.model.CouponMatchResult;
9 import com.yohoufo.order.utils.LoggerUtils; 9 import com.yohoufo.order.utils.LoggerUtils;
  10 +import org.apache.commons.collections.CollectionUtils;
10 import org.slf4j.Logger; 11 import org.slf4j.Logger;
11 import org.springframework.stereotype.Component; 12 import org.springframework.stereotype.Component;
12 13
@@ -103,9 +104,15 @@ public class CouponRuleMatcher { @@ -103,9 +104,15 @@ public class CouponRuleMatcher {
103 public boolean match(ChargeGoods chargeGoods, UserCouponsBo couponsBo) { 104 public boolean match(ChargeGoods chargeGoods, UserCouponsBo couponsBo) {
104 final CouponProductLimitTypeEnum limitTypeEnum = CouponProductLimitTypeEnum.of(couponsBo.getProductLimitType()).orElse(null); 105 final CouponProductLimitTypeEnum limitTypeEnum = CouponProductLimitTypeEnum.of(couponsBo.getProductLimitType()).orElse(null);
105 if (limitTypeEnum == CouponProductLimitTypeEnum.SPECIFIC_PRODUCT) { 106 if (limitTypeEnum == CouponProductLimitTypeEnum.SPECIFIC_PRODUCT) {
106 - return couponsBo.getProductIdInclude().contains(chargeGoods.getProductId()); 107 + //包含商品
  108 + return CollectionUtils.isNotEmpty(couponsBo.getProductIdInclude())
  109 + && couponsBo.getProductIdInclude().contains(chargeGoods.getProductId());
107 } else if (limitTypeEnum == CouponProductLimitTypeEnum.NON) { 110 } else if (limitTypeEnum == CouponProductLimitTypeEnum.NON) {
108 return true; 111 return true;
  112 + } else if (limitTypeEnum == CouponProductLimitTypeEnum.EXCLUDE_PRODUCT) {
  113 + //排除商品
  114 + return CollectionUtils.isNotEmpty(couponsBo.getProductIdExclude())
  115 + && !couponsBo.getProductIdExclude().contains(chargeGoods.getProductId());
109 } else { 116 } else {
110 //目前不存在 117 //目前不存在
111 return false; 118 return false;
@@ -17,6 +17,11 @@ public class RecommendedCouponInfo { @@ -17,6 +17,11 @@ public class RecommendedCouponInfo {
17 @JSONField(name = "usable_coupon_count") 17 @JSONField(name = "usable_coupon_count")
18 private int usableCouponCount; 18 private int usableCouponCount;
19 19
  20 + //使用券张数
  21 + @JSONField(name = "used_coupon_count")
  22 + private int usedCouponCount;
  23 +
  24 + //多个用,分隔
20 @JSONField(name = "coupon_code") 25 @JSONField(name = "coupon_code")
21 private String couponCode; 26 private String couponCode;
22 27
@@ -26,7 +31,7 @@ public class RecommendedCouponInfo { @@ -26,7 +31,7 @@ public class RecommendedCouponInfo {
26 private String couponAmountStr; 31 private String couponAmountStr;
27 32
28 /** 33 /**
29 - * 34 + * 描述
30 */ 35 */
31 private String desc; 36 private String desc;
32 } 37 }
@@ -206,17 +206,21 @@ public class ShoppingSupport { @@ -206,17 +206,21 @@ public class ShoppingSupport {
206 int usableCouponCount = couponPayResultList.getUsableCouponCount(); 206 int usableCouponCount = couponPayResultList.getUsableCouponCount();
207 List<CouponPayResult> couponPayResults = couponPayResultList.getCouponPayResults(); 207 List<CouponPayResult> couponPayResults = couponPayResultList.getCouponPayResults();
208 if (CollectionUtils.isNotEmpty(couponPayResults)) { 208 if (CollectionUtils.isNotEmpty(couponPayResults)) {
  209 + int usedCouponCount = couponPayResults.size();
209 String couponPayAmountStr = MathUtils.formatCurrencyStr(couponPayResults.stream().mapToDouble(coupon -> coupon.getCouponAmount()).sum()); 210 String couponPayAmountStr = MathUtils.formatCurrencyStr(couponPayResults.stream().mapToDouble(coupon -> coupon.getCouponAmount()).sum());
210 String couponCodes = CouponCodeUtils.asString(couponPayResults.stream().map(coupon -> coupon.getCouponCode()).collect(Collectors.toList())); 211 String couponCodes = CouponCodeUtils.asString(couponPayResults.stream().map(coupon -> coupon.getCouponCode()).collect(Collectors.toList()));
211 return RecommendedCouponInfo.builder() 212 return RecommendedCouponInfo.builder()
212 .usableCouponCount(usableCouponCount) 213 .usableCouponCount(usableCouponCount)
  214 + .usedCouponCount(usedCouponCount)
213 .couponAmountStr(couponPayAmountStr) 215 .couponAmountStr(couponPayAmountStr)
214 .couponCode(couponCodes) 216 .couponCode(couponCodes)
215 - .desc(MessageFormat.format(CouponConstants.COUPON_AUTO_RECOMMENDED_DESC_FORMAT, usableCouponCount, couponPayResults.size())).build(); 217 + .desc(MessageFormat.format(CouponConstants.COUPON_AUTO_RECOMMENDED_DESC_FORMAT, usableCouponCount, usedCouponCount)).build();
  218 + } else {
  219 + return RecommendedCouponInfo.builder()
  220 + .usableCouponCount(usableCouponCount)
  221 + .usedCouponCount(0)
  222 + .desc(MessageFormat.format(CouponConstants.USABLE_COUPON_DESC_FORMAT, usableCouponCount))
  223 + .build();
216 } 224 }
217 - return RecommendedCouponInfo.builder()  
218 - .usableCouponCount(usableCouponCount)  
219 - .desc(MessageFormat.format(CouponConstants.USABLE_COUPON_DESC_FORMAT,usableCouponCount))  
220 - .build();  
221 } 225 }
222 } 226 }
@@ -7,16 +7,28 @@ import com.yohobuy.ufo.model.promotion.constant.CouponUseLimitTypeEnum; @@ -7,16 +7,28 @@ import com.yohobuy.ufo.model.promotion.constant.CouponUseLimitTypeEnum;
7 import com.yohobuy.ufo.model.promotion.constant.UserCouponsStatusEnum; 7 import com.yohobuy.ufo.model.promotion.constant.UserCouponsStatusEnum;
8 import com.yohobuy.ufo.model.promotion.response.CouponInfo; 8 import com.yohobuy.ufo.model.promotion.response.CouponInfo;
9 import com.yohoufo.common.utils.DateUtil; 9 import com.yohoufo.common.utils.DateUtil;
10 -import com.yohoufo.dal.promotion.model.*; 10 +import com.yohoufo.dal.promotion.model.Coupon;
  11 +import com.yohoufo.dal.promotion.model.CouponAndType;
  12 +import com.yohoufo.dal.promotion.model.CouponType;
  13 +import com.yohoufo.dal.promotion.model.UserCoupon;
11 import org.apache.commons.lang3.StringUtils; 14 import org.apache.commons.lang3.StringUtils;
12 15
13 import java.text.MessageFormat; 16 import java.text.MessageFormat;
14 import java.util.Arrays; 17 import java.util.Arrays;
  18 +import java.util.List;
15 19
16 public class CouponConvert { 20 public class CouponConvert {
17 21
18 22
19 - public static UserCouponsBo covertCouponBo(UserCoupon userCoupon, Coupon coupon, CouponType couponType){ 23 + /**
  24 + * 订单默认使用
  25 + * @param userCoupon
  26 + * @param coupon
  27 + * @param couponType
  28 + * @param productIds
  29 + * @return
  30 + */
  31 + public static UserCouponsBo covertCouponBo(UserCoupon userCoupon, Coupon coupon, CouponType couponType, List<Integer> productIds){
20 32
21 UserCouponsBo couponBo = new UserCouponsBo(); 33 UserCouponsBo couponBo = new UserCouponsBo();
22 34
@@ -46,12 +58,20 @@ public class CouponConvert { @@ -46,12 +58,20 @@ public class CouponConvert {
46 couponBo.setCouponType(couponType.getId()); 58 couponBo.setCouponType(couponType.getId());
47 couponBo.setCouponTypeName(couponType.getCaption()); 59 couponBo.setCouponTypeName(couponType.getCaption());
48 } 60 }
  61 +
  62 + CouponProductLimitTypeEnum productLimitTypeEnum = CouponProductLimitTypeEnum.of(String.valueOf(coupon.getProductLimitType())).orElse(null);
  63 + if (productLimitTypeEnum == CouponProductLimitTypeEnum.SPECIFIC_PRODUCT) {
  64 + couponBo.setProductIdInclude(productIds);
  65 + } else if (productLimitTypeEnum == CouponProductLimitTypeEnum.EXCLUDE_PRODUCT) {
  66 + couponBo.setProductIdExclude(productIds);
  67 + }
  68 +
49 return couponBo; 69 return couponBo;
50 } 70 }
51 71
52 72
53 /** 73 /**
54 - * 用户优惠券信息 74 + * 用户优惠券信息 用户中心展示
55 * @param userCoupon 用户优惠券 75 * @param userCoupon 用户优惠券
56 * @param coupon 优惠券 76 * @param coupon 优惠券
57 * @param couponType 优惠券类型 77 * @param couponType 优惠券类型
@@ -32,10 +32,7 @@ import java.time.LocalDate; @@ -32,10 +32,7 @@ import java.time.LocalDate;
32 import java.time.LocalDateTime; 32 import java.time.LocalDateTime;
33 import java.time.LocalTime; 33 import java.time.LocalTime;
34 import java.time.ZoneOffset; 34 import java.time.ZoneOffset;
35 -import java.util.ArrayList;  
36 -import java.util.List;  
37 -import java.util.Map;  
38 -import java.util.Objects; 35 +import java.util.*;
39 import java.util.function.Function; 36 import java.util.function.Function;
40 import java.util.stream.Collectors; 37 import java.util.stream.Collectors;
41 38
@@ -279,9 +276,10 @@ public class CouponServiceImpl implements ICouponService { @@ -279,9 +276,10 @@ public class CouponServiceImpl implements ICouponService {
279 } 276 }
280 277
281 // 批量获取coupon 278 // 批量获取coupon
282 - List<String> couponIdList = list.stream().map(UserCoupon::getCouponToken).collect(Collectors.toList());  
283 - List<Coupon> couponList = couponCacheService.getCouponsWithCache(couponIdList);  
284 - Map<Integer, Coupon> couponMap = couponList.stream().filter(coupon -> { 279 + List<String> couponTokens = list.stream().map(UserCoupon::getCouponToken).collect(Collectors.toList());
  280 + List<Coupon> couponList = couponCacheService.getCouponsWithCache(couponTokens);
  281 +
  282 + final Map<Integer, Coupon> couponMap = couponList.stream().filter(coupon -> {
285 if (coupon.getStatus() != null && coupon.getStatus().intValue() == CouponsStatusEnum.VALID.getCode()) { 283 if (coupon.getStatus() != null && coupon.getStatus().intValue() == CouponsStatusEnum.VALID.getCode()) {
286 return true; 284 return true;
287 } else { 285 } else {
@@ -290,34 +288,28 @@ public class CouponServiceImpl implements ICouponService { @@ -290,34 +288,28 @@ public class CouponServiceImpl implements ICouponService {
290 }).collect(Collectors.toMap(Coupon::getId, Function.identity())); 288 }).collect(Collectors.toMap(Coupon::getId, Function.identity()));
291 289
292 // 优惠券商品限制 key=couponId, value=ProductId集合 290 // 优惠券商品限制 key=couponId, value=ProductId集合
293 - Map<Integer, List<Integer>> couponProductIdMap = getProductIdListMap(couponList);  
294 -  
295 - List<UserCouponsBo> couponBoList = list.stream().filter(userCoupon -> {  
296 - return couponMap.containsKey(userCoupon.getCouponId());  
297 - }).map(userCoupon -> {  
298 -  
299 - Coupon coupon = couponMap.get(userCoupon.getCouponId());  
300 - List<Integer> productIds = couponProductIdMap.get(userCoupon.getCouponId());  
301 -  
302 - // 单个获取couponType  
303 - CouponType couponType = couponCacheService.getCouponTypeWithCache(userCoupon.getCouponType() != null ? userCoupon.getCouponType().intValue() : null);  
304 -  
305 - UserCouponsBo couponBo = CouponConvert.covertCouponBo(userCoupon, coupon, couponType);  
306 - couponBo.setProductIdInclude(productIds);  
307 -  
308 - return couponBo;  
309 - }).collect(Collectors.toList()); 291 + final Map<Integer, List<Integer>> couponProductIdMap = getAssociatedProductIdListMap(couponList);
310 292
  293 + //包装返回结果
  294 + List<UserCouponsBo> couponBoList = list.stream()
  295 + .filter(userCoupon -> couponMap.containsKey(userCoupon.getCouponId()))
  296 + .map(userCoupon -> wrapperUserCoupon(userCoupon, couponMap.get(userCoupon.getCouponId()), couponProductIdMap.get(userCoupon.getCouponId())))
  297 + .collect(Collectors.toList());
311 298
312 return UserCouponsListBo.builder().coupons(couponBoList).build(); 299 return UserCouponsListBo.builder().coupons(couponBoList).build();
313 } 300 }
314 301
315 - private Map<Integer, List<Integer>> getProductIdListMap(List<Coupon> couponList) {  
316 - // 批量获取 coupon_product_limt 过滤出商品限制的优惠券id 302 + /**
  303 + * 关联的商品id
  304 + * @param couponList
  305 + * @return
  306 + */
  307 + private Map<Integer, List<Integer>> getAssociatedProductIdListMap(List<Coupon> couponList) {
  308 + // 批量获取 coupon_product_limit 过滤出商品限制的优惠券id
317 List<Integer> productLimitCouponIds = couponList.stream().filter(coupon -> { 309 List<Integer> productLimitCouponIds = couponList.stream().filter(coupon -> {
318 - if (coupon.getProductLimitType()!=null && CouponProductLimitTypeEnum.SPECIFIC_PRODUCT.getLimitType().equals(String.valueOf(coupon.getProductLimitType()))){ 310 + if (coupon.getProductLimitType() != null && !StringUtils.equals(CouponProductLimitTypeEnum.NON.getLimitType(),String.valueOf(coupon.getProductLimitType()))) {
319 return true; 311 return true;
320 - }else{ 312 + } else {
321 return false; 313 return false;
322 } 314 }
323 }).map(Coupon::getId).collect(Collectors.toList()); 315 }).map(Coupon::getId).collect(Collectors.toList());
@@ -326,6 +318,84 @@ public class CouponServiceImpl implements ICouponService { @@ -326,6 +318,84 @@ public class CouponServiceImpl implements ICouponService {
326 318
327 } 319 }
328 320
  321 + @Override
  322 + public UserCouponsListBo checkAndGetCoupons(int uid, List<String> couponCodes) {
  323 + //数据校验
  324 + if (uid <= 0 || CollectionUtils.isEmpty(couponCodes)) {
  325 + logger.warn("check coupon use param error:{}, {}", uid, couponCodes);
  326 + throw new ServiceException(ServiceError.PROMOTION_PARAM_IS_ERROR);
  327 + }
  328 +
  329 + // 获取用户券记录
  330 + List<UserCoupon> userCoupons = userCouponMapper.selectByUidAndCouponCodes(uid, couponCodes);
  331 +
  332 + // 批量获取coupon
  333 + List<String> couponTokens = userCoupons.stream().map(UserCoupon::getCouponToken).collect(Collectors.toList());
  334 +
  335 + List<Coupon> couponList = couponCacheService.getCouponsWithCache(couponTokens);
  336 +
  337 + final Map<Integer, Coupon> couponMap = couponList.stream().filter(coupon -> {
  338 + if (coupon.getStatus() != null && coupon.getStatus().intValue() == CouponsStatusEnum.VALID.getCode()) {
  339 + return true;
  340 + } else {
  341 + return false;
  342 + }
  343 + }).collect(Collectors.toMap(Coupon::getId, Function.identity()));
  344 +
  345 + // 优惠券商品限制 key=couponId, value=ProductId集合
  346 + Map<Integer, List<Integer>> couponProductIdMap = getAssociatedProductIdListMap(couponList);
  347 +
  348 +
  349 + int time = DateUtil.getCurrentTimeSecond();
  350 + List<UserCouponsBo> couponBoList = couponCodes.stream().map(couponCode -> {
  351 +
  352 + UserCoupon userCoupon = userCoupons.stream().filter(e -> couponCode.equals(e.getCouponCode())).findAny().orElse(null);
  353 + logger.info("user coupon {},{},{}", uid, couponCode, userCoupon);
  354 + if (userCoupon == null) {
  355 + logger.warn("not find user coupon by{},{}", uid, couponCode);
  356 + throw new ServiceException(ServiceError.PROMOTION_COUPON_IS_NOT_YOUS);
  357 + }
  358 + //判断券状态
  359 + if (userCoupon.getStatus().intValue() != CouponUseStatusEnum.NOT_USED.getCode()) {
  360 + logger.warn("user this coupon is used:{},{}", userCoupon.getUid(), userCoupon.getCouponCode());
  361 + throw new ServiceException(ServiceError.PROMOTION_COUPON_NOT_USE_DOUBLE);
  362 + }
  363 +
  364 + //判断生失效时间
  365 + if (userCoupon.getStartTime() > time || userCoupon.getEndTime() < time) {
  366 + logger.warn("coupon has expire or not arrive time:{},{},{}", userCoupon.getStartTime(), userCoupon.getEndTime(), time);
  367 + throw new ServiceException(ServiceError.PROMOTION_COUPON_NOT_ALLOW_OR_EXPIRE);
  368 + }
  369 +
  370 + //券模板的状态
  371 + Coupon coupon = couponMap.get(userCoupon.getCouponId());
  372 + if (coupon == null) {
  373 + logger.warn("not find coupon by couponId:{}",userCoupon.getCouponId());
  374 + throw new ServiceException(ServiceError.PROMOTION_COUPON_NOT_EXISTS);
  375 + }
  376 + if (coupon.getStatus() != CouponsStatusEnum.VALID.getCode()) {
  377 + logger.warn("coupon status can't be use:{},{}", coupon.getId(), coupon.getStatus());
  378 + throw new ServiceException(ServiceError.PROMOTION_COUPON_IS_NOT_VAILD);
  379 + }
  380 +
  381 + //所有的校验都通过了,生成bo
  382 + return wrapperUserCoupon(userCoupon, coupon, couponProductIdMap.get(userCoupon.getCouponId()));
  383 +
  384 + }).collect(Collectors.toList());
  385 +
  386 + return UserCouponsListBo.builder().coupons(couponBoList).build();
  387 + }
  388 +
  389 + private UserCouponsBo wrapperUserCoupon(final UserCoupon userCoupon, final Coupon coupon, final List<Integer> productIds) {
  390 +
  391 + // 单个获取couponType
  392 + CouponType couponType = couponCacheService.getCouponTypeWithCache(userCoupon.getCouponType() != null ? userCoupon.getCouponType().intValue() : null);
  393 +
  394 + UserCouponsBo couponBo = CouponConvert.covertCouponBo(userCoupon, coupon, couponType, productIds);
  395 +
  396 + return couponBo;
  397 + }
  398 +
329 399
330 400
331 @Override 401 @Override
@@ -429,63 +499,4 @@ public class CouponServiceImpl implements ICouponService { @@ -429,63 +499,4 @@ public class CouponServiceImpl implements ICouponService {
429 .size(req.getLimit()) 499 .size(req.getLimit())
430 .build(); 500 .build();
431 } 501 }
432 -  
433 - @Override  
434 - public UserCouponsListBo checkAndGetCoupons(int uid, List<String> couponCodes) {  
435 - //数据校验  
436 - if (uid <= 0 || CollectionUtils.isEmpty(couponCodes)) {  
437 - logger.warn("check coupon use param error:{}, {}", uid, couponCodes);  
438 - throw new ServiceException(ServiceError.PROMOTION_PARAM_IS_ERROR);  
439 - }  
440 -  
441 - // 获取用户券记录  
442 - List<UserCoupon> userCoupons = userCouponMapper.selectByUidAndCouponCodes(uid, couponCodes);  
443 -  
444 - int time = DateUtil.getCurrentTimeSecond();  
445 -  
446 - List<UserCouponsBo> couponBoList = couponCodes.stream().map(couponCode -> {  
447 -  
448 - UserCoupon userCoupon = userCoupons.stream().filter(e -> couponCode.equals(e.getCouponCode())).findAny().orElse(null);  
449 - logger.info("user coupon {},{},{}", uid, couponCode, userCoupon);  
450 - if (userCoupon == null) {  
451 - logger.warn("not find user coupon by{},{}", uid, couponCode);  
452 - throw new ServiceException(ServiceError.PROMOTION_COUPON_IS_NOT_YOUS);  
453 - }  
454 - //判断券状态  
455 - if (userCoupon.getStatus().intValue() != CouponUseStatusEnum.NOT_USED.getCode()) {  
456 - logger.warn("user this coupon is used:{},{}", userCoupon.getUid(), userCoupon.getCouponCode());  
457 - throw new ServiceException(ServiceError.PROMOTION_COUPON_NOT_USE_DOUBLE);  
458 - }  
459 -  
460 - //判断生失效时间  
461 - if (userCoupon.getStartTime() > time || userCoupon.getEndTime() < time) {  
462 - logger.warn("coupon has expire or not arrive time:{},{},{}", userCoupon.getStartTime(), userCoupon.getEndTime(), time);  
463 - throw new ServiceException(ServiceError.PROMOTION_COUPON_NOT_ALLOW_OR_EXPIRE);  
464 - }  
465 -  
466 - //券模板的状态  
467 - Coupon coupon = couponCacheService.getCouponWithCache(userCoupon.getCouponToken());  
468 - if (coupon == null) {  
469 - logger.warn("coupons is null");  
470 - throw new ServiceException(ServiceError.PROMOTION_COUPON_NOT_EXISTS);  
471 - }  
472 - if (coupon.getStatus() != CouponsStatusEnum.VALID.getCode()) {  
473 - logger.warn("coupon status can't be use:{},{}", coupon.getId(), coupon.getStatus());  
474 - throw new ServiceException(ServiceError.PROMOTION_COUPON_IS_NOT_VAILD);  
475 - }  
476 - //所有的校验都通过了,生成bo  
477 - Map<Integer, List<Integer>> couponProductIdMap = getProductIdListMap(Lists.newArrayList(coupon));  
478 - List<Integer> productIds = couponProductIdMap.get(userCoupon.getCouponId());  
479 -  
480 - // 单个获取couponType  
481 - CouponType couponType = couponCacheService.getCouponTypeWithCache(userCoupon.getCouponType() != null ? userCoupon.getCouponType().intValue() : null);  
482 -  
483 - UserCouponsBo couponBo = CouponConvert.covertCouponBo(userCoupon, coupon, couponType);  
484 - couponBo.setProductIdInclude(productIds);  
485 -  
486 - return couponBo;  
487 -  
488 - }).collect(Collectors.toList());  
489 - return UserCouponsListBo.builder().coupons(couponBoList).build();  
490 - }  
491 } 502 }