...
|
...
|
@@ -2,14 +2,17 @@ package com.yoho.ufo.coupon.service.impl; |
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.google.common.base.Joiner;
|
|
|
import com.google.common.base.Splitter;
|
|
|
import com.google.common.collect.Iterables;
|
|
|
import com.google.common.collect.Lists;
|
|
|
import com.yoho.core.rabbitmq.YhProducer;
|
|
|
import com.yoho.core.rest.client.ServiceCaller;
|
|
|
import com.yoho.error.exception.ServiceException;
|
|
|
import com.yoho.ufo.coupon.model.CouponAndProductConditions;
|
|
|
import com.yoho.ufo.coupon.model.ProductCondition;
|
|
|
import com.yoho.ufo.coupon.model.ProductLimitType;
|
|
|
import com.yoho.ufo.coupon.service.ICouponService;
|
|
|
import com.yoho.ufo.coupon.service.builder.CouponAndProductConditionsBuilder;
|
|
|
import com.yoho.ufo.coupon.util.Strings;
|
|
|
import com.yoho.ufo.dal.CouponDisplayMapper;
|
|
|
import com.yoho.ufo.dal.CouponMapper;
|
|
|
import com.yoho.ufo.dal.CouponProductLimitMapper;
|
...
|
...
|
@@ -30,7 +33,6 @@ import com.yoho.ufo.service.impl.UserHelper; |
|
|
import com.yoho.ufo.service.model.ApiResponse;
|
|
|
import com.yohobuy.ufo.coupon.req.*;
|
|
|
import com.yohobuy.ufo.model.common.PageResponseBO;
|
|
|
import com.yohobuy.ufo.model.order.constants.SkupType;
|
|
|
import com.yohobuy.ufo.model.promotion.CouponDisplayBo;
|
|
|
import com.yohobuy.ufo.model.promotion.constant.CouponTypeEnum;
|
|
|
import com.yohobuy.ufo.model.promotion.constant.PositionType;
|
...
|
...
|
@@ -157,6 +159,7 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{ |
|
|
resp.setCouponToken(userCoupon.getCouponToken());
|
|
|
resp.setUid(userCoupon.getUid());
|
|
|
resp.setCouponId(userCoupon.getCouponId());
|
|
|
resp.setUserType(userCoupon.getUserType());
|
|
|
resp.setCouponType(userCoupon.getCouponType());
|
|
|
resp.setStartTime(startTime=userCoupon.getStartTime());
|
|
|
resp.setStartTimeStr(DateUtil.int2DateStr(startTime, dateFormat));
|
...
|
...
|
@@ -192,106 +195,82 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{ |
|
|
}
|
|
|
|
|
|
|
|
|
private static final String SKUP_FORBID_TYPE_NONE = "0";
|
|
|
|
|
|
@Override
|
|
|
public ApiResponse saveOrUpdateCoupon(CouponSaveUpdateReq req) {
|
|
|
LOGGER.info("enter saveOrUpdateCoupon,param is {}",req);
|
|
|
checkSaveOrUpdateCouponParam(req);
|
|
|
|
|
|
// 检查优惠券类型
|
|
|
Optional<CouponTypeEnum> couponTypeEnum = CouponTypeEnum.of(req.getCouponType());
|
|
|
if (!couponTypeEnum.isPresent()){
|
|
|
throw new ServiceException(400, "错误:不合法的优惠券类型");
|
|
|
}
|
|
|
//parseSkupForbidType(req);
|
|
|
req.setSkupForbidType(SKUP_FORBID_TYPE_NONE);
|
|
|
parseSkupAllowType(req);
|
|
|
|
|
|
int productLimitType = req.getProductLimitType().intValue();
|
|
|
List<Integer> productIds = getProductIdsAndCheckProductLimitParam(productLimitType,req.getProductLimitValue());
|
|
|
|
|
|
// 初始化非必填数据
|
|
|
req.setSendNum(null == req.getSendNum()?0:req.getSendNum());
|
|
|
req.setPid(new UserHelper().getUserId());
|
|
|
|
|
|
// 如果是修改获取并校验优惠券信息
|
|
|
Coupon coupon = null;
|
|
|
if (req.getId() != null) {
|
|
|
coupon = couponMapper.selectById(req.getId());
|
|
|
if (Objects.isNull(coupon)) {
|
|
|
CouponAndProductConditions capc = new CouponAndProductConditionsBuilder(req).build();
|
|
|
if (capc.isChange()) {
|
|
|
// 如果是修改获取并校验优惠券信息
|
|
|
if (Objects.isNull(couponMapper.selectById(req.getId()))) {
|
|
|
throw new ServiceException(400, "错误:优惠券信息不存在");
|
|
|
}
|
|
|
}
|
|
|
Integer couponId;
|
|
|
// 插入
|
|
|
if(Objects.isNull(coupon)){
|
|
|
LOGGER.info("before saveOrUpdateCoupon#insert,req is {}",req);
|
|
|
req.setCouponToken(UUID.randomUUID().toString());
|
|
|
req.setCreateTime(DateUtil.getCurrentTimeSeconds());
|
|
|
req.setStatus(Coupon.CouponStatusEnum.IN_EFFECT.getValue());
|
|
|
couponMapper.insertByCouponSaveUpdateReq(req);
|
|
|
LOGGER.info("after saveOrUpdateCoupon#insert,req is {}",req);
|
|
|
saveProductLimitItems(req, productLimitType, productIds);
|
|
|
couponId = req.getId();
|
|
|
}
|
|
|
// 更新
|
|
|
else {
|
|
|
LOGGER.info("before saveOrUpdateCoupon#deleteByCouponId,couponId is {}",req.getId());
|
|
|
|
|
|
// 已经有了优惠券的发放记录
|
|
|
UserCouponNum userCouponNum = userCouponMapper.selectByCouponId(couponId = coupon.getId());
|
|
|
if (Objects.nonNull(userCouponNum) && userCouponNum.getCnt()>0){
|
|
|
LOGGER.info("sendNum bigger than 0, name|couponNu|remark only can update, couponId {}", req.getId());
|
|
|
CouponSaveUpdateReq couponSaveUpdateReq = new CouponSaveUpdateReq();
|
|
|
couponSaveUpdateReq.setId(couponId);
|
|
|
|
|
|
// 名称
|
|
|
couponSaveUpdateReq.setCouponName(req.getCouponName());
|
|
|
|
|
|
// 数量
|
|
|
couponSaveUpdateReq.setCouponNum(req.getCouponNum());
|
|
|
|
|
|
// 优惠券说明
|
|
|
couponSaveUpdateReq.setRemark(req.getRemark());
|
|
|
|
|
|
// 是否需要校验
|
|
|
couponSaveUpdateReq.setCheckRequired(req.getCheckRequired());
|
|
|
|
|
|
//结束时间
|
|
|
Integer endTime;
|
|
|
if (Objects.nonNull(endTime=req.getEndTime())){
|
|
|
couponSaveUpdateReq.setEndTime(endTime);
|
|
|
}
|
|
|
int couponId = capc.isChange() ? changeCouponDefinition(capc) : createCouponDefinition(capc);
|
|
|
saveOrUpdateDisplay(couponId, req.getShowInPrdDetail());
|
|
|
return new ApiResponse.ApiResponseBuilder().build();
|
|
|
}
|
|
|
|
|
|
LOGGER.info("has coupon send, saveOrUpdateCoupon#update,req is {}",req);
|
|
|
couponMapper.updateByCouponSaveUpdateReq(couponSaveUpdateReq);
|
|
|
private int createCouponDefinition(CouponAndProductConditions capc) {
|
|
|
LOGGER.info("create new coupon");
|
|
|
Coupon coupon = capc.getCoupon();
|
|
|
couponMapper.insertByCouponSaveUpdateReq(coupon);
|
|
|
int couponId = coupon.getId();
|
|
|
LOGGER.info("create coupon success,couponId is {}", couponId);
|
|
|
saveProductLimitItems(couponId, capc.getProductConditions());
|
|
|
LOGGER.info("save product limit items success");
|
|
|
return couponId;
|
|
|
}
|
|
|
|
|
|
private int changeCouponDefinition(CouponAndProductConditions capc) {
|
|
|
Coupon coupon = capc.getCoupon();
|
|
|
Integer couponId = coupon.getId();
|
|
|
// 已经有了优惠券的发放记录
|
|
|
if (isCouponAlreadySend(couponId)) {
|
|
|
LOGGER.info("sendNum bigger than 0, name|couponNu|remark only can update, couponId {}", couponId);
|
|
|
updateFewFields(coupon);
|
|
|
} else {
|
|
|
LOGGER.info("has no coupon send, before saveOrUpdateCoupon#update,couponId is {}", couponId);
|
|
|
couponMapper.updateByCouponSaveUpdateReq(coupon);
|
|
|
LOGGER.info("change coupon success,couponId is {}", couponId);
|
|
|
saveProductLimitItems(couponId, capc.getProductConditions());
|
|
|
LOGGER.info("change product limit items success");
|
|
|
}
|
|
|
return couponId;
|
|
|
}
|
|
|
|
|
|
}else{
|
|
|
private boolean isCouponAlreadySend(int couponId) {
|
|
|
UserCouponNum userCouponNum = userCouponMapper.selectByCouponId(couponId);
|
|
|
return Objects.nonNull(userCouponNum) && userCouponNum.getCnt() > 0;
|
|
|
}
|
|
|
|
|
|
LOGGER.info("sendNum noting, all info can update, couponId {}", req.getId());
|
|
|
private void updateFewFields(Coupon coupon) {
|
|
|
Coupon toUpdateCoupon = new Coupon();
|
|
|
toUpdateCoupon.setId(coupon.getId());
|
|
|
// 名称
|
|
|
toUpdateCoupon.setCouponName(coupon.getCouponName());
|
|
|
// 数量
|
|
|
toUpdateCoupon.setCouponNum(coupon.getCouponNum());
|
|
|
|
|
|
LOGGER.info("has no coupon send, before saveOrUpdateCoupon#update,req is {}",req);
|
|
|
couponMapper.updateByCouponSaveUpdateReq(req);
|
|
|
// 优惠券说明
|
|
|
toUpdateCoupon.setRemark(coupon.getRemark());
|
|
|
|
|
|
saveProductLimitItems(req, productLimitType, productIds);
|
|
|
}
|
|
|
// 是否需要校验
|
|
|
toUpdateCoupon.setCheckRequired(coupon.getCheckRequired());
|
|
|
|
|
|
LOGGER.info("after saveOrUpdateCoupon#update,req is {}",req);
|
|
|
//结束时间
|
|
|
Integer endTime;
|
|
|
if (Objects.nonNull(endTime = coupon.getEndTime())) {
|
|
|
toUpdateCoupon.setEndTime(endTime);
|
|
|
}
|
|
|
saveOrUpdateDisplay(couponId, req.getShowInPrdDetail());
|
|
|
return new ApiResponse.ApiResponseBuilder().build();
|
|
|
LOGGER.info("updateFewFields,toUpdateCoupon is {}", coupon);
|
|
|
couponMapper.updateByCouponSaveUpdateReq(toUpdateCoupon);
|
|
|
LOGGER.info("updateFewFields success");
|
|
|
}
|
|
|
|
|
|
|
|
|
private void parseSkupAllowType(CouponSaveUpdateReq req) {
|
|
|
if (StringUtils.isBlank(req.getSkupAllowType())) {
|
|
|
throw new ServiceException(403, "可使用该优惠券的商品属性不能为空");
|
|
|
}
|
|
|
List<String> allowAttributeTypes = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(req.getSkupAllowType());
|
|
|
req.setSkupAllowType(Joiner.on(",").join(allowAttributeTypes));
|
|
|
}
|
|
|
|
|
|
private final static String API_ADDORUPDATEDISPLAY = "coupon.addOrUpdateDisplay";
|
|
|
private void saveOrUpdateDisplay(Integer couponId, String showInPrdDetail){
|
|
|
LOGGER.info("saveOrUpdateDisplay couponId {} showInPrdDetail {}", couponId, showInPrdDetail);
|
...
|
...
|
@@ -320,41 +299,18 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{ |
|
|
|
|
|
}
|
|
|
|
|
|
private void parseSkupForbidType(CouponSaveUpdateReq req) {
|
|
|
if (StringUtils.isBlank(req.getSkupForbidType())) {
|
|
|
req.setSkupForbidType(SKUP_FORBID_TYPE_NONE);
|
|
|
return;
|
|
|
}
|
|
|
List<String> limitTypes = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(req.getSkupForbidType());
|
|
|
if (CollectionUtils.isEmpty(limitTypes)) {
|
|
|
req.setSkupForbidType(SKUP_FORBID_TYPE_NONE);
|
|
|
return;
|
|
|
}
|
|
|
for (String limitType : limitTypes) {
|
|
|
if (!limitType.matches("\\d+")) {
|
|
|
throw new ServiceException(400, "错误:不合法的限制类型");
|
|
|
}
|
|
|
if (!SkupType.of(Integer.parseInt(limitType)).isPresent() && !SKUP_FORBID_TYPE_NONE.equals(limitType)) {
|
|
|
throw new ServiceException(401, "错误:不合法的限制类型");
|
|
|
}
|
|
|
}
|
|
|
req.setSkupForbidType(Joiner.on(",").join(limitTypes));
|
|
|
}
|
|
|
|
|
|
private void saveProductLimitItems(CouponSaveUpdateReq req, int productLimitType, List<Integer> productIds) {
|
|
|
if(req.getProductLimitType() == Coupon.PRODUCTLIMITTYPE_SPECIALPRODUCT || req.getProductLimitType() == Coupon.PRODUCTLIMITTYPE_EXCLUDE){
|
|
|
// 清理之前的记录
|
|
|
couponProductLimitMapper.deleteByCouponId(req.getId());
|
|
|
// 重新插入
|
|
|
|
|
|
private void saveProductLimitItems(Integer couponId, List<ProductCondition> productConditions) {
|
|
|
// 清理之前的记录
|
|
|
couponProductLimitMapper.deleteByCouponId(couponId);
|
|
|
// 重新插入
|
|
|
if (CollectionUtils.isNotEmpty(productConditions)) {
|
|
|
// productIds 可能超过500个 每500个插入一次
|
|
|
Iterable<List<Integer>> productIdBatch = Iterables.partition(productIds, 1000);
|
|
|
|
|
|
for (List<Integer> productIdPer : productIdBatch){
|
|
|
couponProductLimitMapper.insertBatchByProductIds(productIdPer, productLimitType, req.getId());
|
|
|
//Iterable<List<Integer>> productIdBatch = Iterables.partition(productIds, 1000);
|
|
|
for (ProductCondition pc : productConditions) {
|
|
|
if (CollectionUtils.isNotEmpty(pc.getProductIds())) {
|
|
|
couponProductLimitMapper.insertBatchByProductIds(pc.getProductIds(), pc.getProductConditionType(), couponId);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
...
|
...
|
@@ -412,10 +368,32 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{ |
|
|
}
|
|
|
}
|
|
|
|
|
|
List<Integer> specificProductIds = Lists.newArrayList();
|
|
|
List<Integer> excludeProductIds = Lists.newArrayList();
|
|
|
if (CollectionUtils.isNotEmpty(productLimitList)) {
|
|
|
productLimitList.forEach(item -> {
|
|
|
switch (ProductLimitType.find(item.getLimitType())) {
|
|
|
case Specific_Product:
|
|
|
specificProductIds.add(item.getProductId());
|
|
|
break;
|
|
|
case Exclude_Product:
|
|
|
excludeProductIds.add(item.getProductId());
|
|
|
break;
|
|
|
default:
|
|
|
throw new IllegalStateException("i don't known,impossible,id: " + item.getId());
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (CollectionUtils.isNotEmpty(specificProductIds)) {
|
|
|
coupon.setProductLimitValue(Strings.join(specificProductIds));
|
|
|
}
|
|
|
|
|
|
JSONObject jsonObject = new JSONObject();
|
|
|
jsonObject.put("coupon",coupon);
|
|
|
jsonObject.put("showInPrdDetail", showInPrdDetail);
|
|
|
jsonObject.put("productLimits",productLimitList);
|
|
|
jsonObject.put("excludeProductIds",Strings.join(excludeProductIds));
|
|
|
//jsonObject.put("productLimits",productLimitList);
|
|
|
return new ApiResponse.ApiResponseBuilder().data(jsonObject).build();
|
|
|
}
|
|
|
|
...
|
...
|
@@ -586,6 +564,7 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{ |
|
|
.couponName(null != coupon ? coupon.getCouponName() : null)
|
|
|
.couponId(userCoupon.getCouponId())
|
|
|
.couponCode(userCoupon.getCouponCode())
|
|
|
.userType(userCoupon.getUserType())
|
|
|
.createTime(com.yoho.ufo.util.DateUtil.int2DateStr(userCoupon.getCreateTime(), "yyyy-MM-dd HH:mm:ss"))
|
|
|
.status(UserCoupon.UserCouponStatusEnum.getKey(userCoupon.getStatus()))
|
|
|
.statusValue(userCoupon.getStatus())
|
...
|
...
|
@@ -647,6 +626,12 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{ |
|
|
LOGGER.warn("checkSaveOrUpdateCouponParam failed! couponName is blank");
|
|
|
throw new ServiceException(400, "错误:优惠券名称为空");
|
|
|
}
|
|
|
|
|
|
if (null == req.getUserType()) {
|
|
|
LOGGER.warn("checkSaveOrUpdateCouponParam failed! userType error! userType is {}", req.getUserType());
|
|
|
throw new ServiceException(400, "错误:用户类型条件为空");
|
|
|
}
|
|
|
|
|
|
if(null == req.getUseLimitType()){
|
|
|
LOGGER.warn("checkSaveOrUpdateCouponParam failed! useLimitType error! useLimitType is {}",req.getUseLimitType());
|
|
|
throw new ServiceException(400, "错误:优惠条件为空");
|
...
|
...
|
@@ -663,6 +648,12 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{ |
|
|
LOGGER.warn("checkSaveOrUpdateCouponParam failed! useNum error! useNum is {}",req.getUseNum());
|
|
|
throw new ServiceException(400, "错误:使用次数无效");
|
|
|
}
|
|
|
|
|
|
if (StringUtils.isBlank(req.getSkupAllowType())) {
|
|
|
LOGGER.warn("checkSaveOrUpdateCouponParam failed! skupAllowType error! skupAllowType is {}",req.getSkupAllowType());
|
|
|
throw new ServiceException(403, "可使用该优惠券的商品属性不能为空");
|
|
|
}
|
|
|
|
|
|
Integer startTime;
|
|
|
if(null == (startTime=req.getStartTime()) || startTime<0){
|
|
|
LOGGER.warn("checkSaveOrUpdateCouponParam failed! startTime error! startTime is {}",startTime);
|
...
|
...
|
@@ -705,6 +696,12 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{ |
|
|
if (req.getCheckRequired() == null){
|
|
|
throw new ServiceException(400, "发券确认标记不能为空");
|
|
|
}
|
|
|
|
|
|
// 检查优惠券类型
|
|
|
Optional<CouponTypeEnum> couponTypeEnum = CouponTypeEnum.of(req.getCouponType());
|
|
|
if (!couponTypeEnum.isPresent()){
|
|
|
throw new ServiceException(400, "错误:不合法的优惠券类型");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private boolean checkUpdateCouponParam(CouponSaveUpdateReq req) {
|
...
|
...
|
|