优惠券的发布、领取、使用相关代码设计

后台-系统设置-扩展变量-手机广告位-内容正文顶部

代码设计

1、接口调用流程图

  平台和商家发布优惠券

  用户领取优惠券

  使用优惠券

2、相关代码展示

发布优惠券

  @RestController

  @RequestMapping("/seller/promotion/coupons")

  @Api(description = "优惠券相关API")

  @Validated

  public class CouponSellerController {

  @ApiOperation(value = "添加优惠券", response = CouponDO.class)

  @PostMapping

  public CouponDO add(@Valid CouponDO couponDO) {

  Seller seller = UserContext.getSeller();

  couponDO.setSellerId(seller.getSellerId());

  couponDO.setSellerName(seller.getSellerName());

  this.couponManager.add(couponDO);

  return couponDO;

  }

  }

  @Service

  public class CouponManagerImpl implements CouponManager {

  @Override

  @Transactional(propagation = Propagation.REQUIRED, rollbackFor

  = {ServiceException.class, RuntimeException.class, Exception.class})

  public CouponDO add(CouponDO coupon) {

  //检测开始时间和结束时间

  PromotionValid.paramValid(coupon.getStartTime(), coupon.getEndTime(), 1, null);

  if (coupon.getLimitNum() < 0) {

  throw new ServiceException(PromotionErrorCode.E406.code(),

  "限领数量不能为负数");

  }

  //校验每人限领数是都大于发行量

  if (coupon.getLimitNum() > coupon.getCreateNum()) {

  throw new ServiceException(PromotionErrorCode.E405.code(),

  "限领数量超出发行量");

  }

  if (coupon.getCouponPrice() == null || coupon.getCouponPrice() <= 0) {

  throw new ServiceException(PromotionErrorCode.E409.code(),

  "优惠券面额必须大于0元");

  }

  if (coupon.getCouponThresholdPrice() == null ||

  coupon.getCouponThresholdPrice() <= 0) {

  throw new ServiceException(PromotionErrorCode.E409.code(),

  "优惠券门槛价格必须大于0元");

  }

  //校验优惠券面额是否小于门槛价格

  if (coupon.getCouponPrice() >= coupon.getCouponThresholdPrice()) {

  throw new ServiceException(PromotionErrorCode.E409.code(),

  "优惠券面额必须小于优惠券门槛价格");

  }

  //开始时间取前段+00:00:00 结束时间取前段+23:59:59

  String startStr = DateUtil.toString(coupon.getStartTime(), "yyyy-MM-dd");

  String endStr = DateUtil.toString(coupon.getEndTime(), "yyyy-MM-dd");

  coupon.setStartTime(DateUtil.getDateline(startStr + " 00:00:00"));

  coupon.setEndTime(DateUtil.getDateline(endStr + " 23:59:59",

  "yyyy-MM-dd hh:mm:ss"));

  this.paramValid(coupon.getStartTime(), coupon.getEndTime());

  coupon.setReceivedNum(0);

  coupon.setUsedNum(0);

  //部分商品和分类的id存储增加,,

  if (CouponUseScope.SOME_GOODS.name().equals(coupon.getUseScope()) ||

  CouponUseScope.CATEGORY.name().equals(coupon.getUseScope())) {

  coupon.setScopeId("," + coupon.getScopeId() + ",");

  }

  this.couponMapper.insert(coupon);

  //启用延时任务创建优惠券脚本信息

  PromotionScriptMsg promotionScriptMsg = new PromotionScriptMsg();

  promotionScriptMsg.setPromotionId(coupon.getCouponId());

  promotionScriptMsg.setPromotionName(coupon.getTitle());

  promotionScriptMsg.setPromotionType(PromotionTypeEnum.COUPON);

  promotionScriptMsg.setOperationType(ScriptOperationTypeEnum.CREATE);

  promotionScriptMsg.setEndTime(coupon.getEndTime());

  String uniqueKey = "{TIME_TRIGGER_" + PromotionTypeEnum.COUPON.name()

  + "}_" + coupon.getCouponId();

  timeTrigger.add(TimeExecute.COUPON_SCRIPT_EXECUTER, promotionScriptMsg,

  coupon.getStartTime(), uniqueKey);

  return coupon;

  }

  }

用户领取优惠券

  @RestController

  @RequestMapping("/members/coupon")

  @Api(description = "会员优惠券相关API")

  @Validated

  public class MemberCouponBuyerController {

  @ApiOperation(value = "用户领取优惠券")

  @ApiImplicitParams({

  @ApiImplicitParam(name = "coupon_id", value = "优惠券id", required = true,

  dataType = "String", paramType = "path")

  })

  @PostMapping(value = "/{coupon_id}/receive")

  public String receiveBonus(@ApiIgnore @PathVariable("coupon_id") Long couponId) {

  //限领检测

  this.memberCouponManager.checkLimitNum(couponId);

  Buyer buyer = UserContext.getBuyer();

  this.memberCouponManager.receiveBonus(buyer.getUid(),

  buyer.getUsername(), couponId);

  return "";

  }

  }

  @Service

  public class MemberCouponManagerImpl implements MemberCouponManager {

  @Override

  @Transactional(value = "memberTransactionManager", propagation =

  Propagation.REQUIRED, rollbackFor = Exception.class)

  public void receiveBonus(Long memberId, String memberName, Long couponId) {

  //根据优惠券id获取优惠券信息

  CouponDO couponDO = this.couponClient.getModel(couponId);

  //如果会员id不为空

  if (memberId != null) {

  //添加会员优惠券表

  MemberCoupon memberCoupon = new MemberCoupon(couponDO);

  //设置优惠券创建时间

  memberCoupon.setCreateTime(DateUtil.getDateline());

  //设置会员ID

  memberCoupon.setMemberId(memberId);

  //设置会员名称

  memberCoupon.setMemberName(memberName);

  //设置优惠券使用状态 0:未使用,1:已使用,2:已过期,3:已作废

  memberCoupon.setUsedStatus(0);

  //会员优惠券入库

  memberCouponMapper.insert(memberCoupon);

  // 修改优惠券已被领取的数量

  this.couponClient.addReceivedNum(couponId);

  }

  }

  @Override

  public void checkLimitNum(Long couponId) {

  //根据优惠券ID获取优惠券信息

  CouponDO couponDO = this.couponClient.getModel(couponId);

  //获取当前登录的会员信息

  Buyer buyer = UserContext.getBuyer();

  //获取每人限领数量

  int limitNum = couponDO.getLimitNum();

  //新建查询条件包装器

  QueryWrapper wrapper = new QueryWrapper<>();

  //以会员id为查询条件

  wrapper.eq("member_id", buyer.getUid());

  //以优惠券id为查询条件

  wrapper.eq("coupon_id", couponId);

  //查询会员优惠券数量

  int num = memberCouponMapper.selectCount(wrapper);

  //判断优惠券是否已被领完

  if (couponDO.getReceivedNum() >= couponDO.getCreateNum()) {

  throw new ServiceException(MemberErrorCode.E203.code(), "优惠券已被领完");

  }

  //判断优惠券是否已达到限领数量

  if (limitNum != 0 && num >= limitNum) {

  throw new ServiceException(MemberErrorCode.E203.code(),

  "优惠券限领" + limitNum + "个");

  }

  }

  }

使用优惠券

  @Api(description = "购物车价格计算API")

  @RestController

  @RequestMapping("/trade/promotion")

  @Validated

  public class TradePromotionController {

  @ApiOperation(value = "设置优惠券", notes = "使用优惠券的时候分为三种情况:前2种情况couponId 不为0,不为空。第3种情况couponId为0," +

  "1、使用优惠券:在刚进入订单结算页,为使用任何优惠券之前。" +

  "2、切换优惠券:在1、情况之后,当用户切换优惠券的时候。" +

  "3、取消已使用的优惠券:用户不想使用优惠券的时候。")

  @ApiImplicitParams({

  @ApiImplicitParam(name = "seller_id", value = "店铺ID", required = true,

  dataType = "int", paramType = "path"),

  @ApiImplicitParam(name = "mc_id", value = "优惠券ID", required = true,

  dataType = "int", paramType = "path"),

  @ApiImplicitParam(name = "way", value = "结算方式,BUY_NOW:立即购买,CART:"

  +"购物车", required = true, dataType = "String")

  })

  @PostMapping(value = "/{seller_id}/seller/{mc_id}/coupon")

  public void setCoupon(@NotNull(message = "店铺id不能为空")

  @PathVariable("seller_id") Long sellerId,

  @NotNull(message = "优惠券id不能为空")

  @PathVariable("mc_id") Long mcId,

  @NotNull(message = "结算方式不能为空")

  @RequestParam String way) {

  CartBuilder cartBuilder =

  new DefaultCartBuilder(CartType.CART, cartSkuRenderer, null,

  cartPriceCalculator, checkDataRebderer);

  CartView cartViewold =

  cartBuilder.renderSku(CheckedWay.valueOf(way)).countPrice(false).build();

  //先判断优惠券能否使用

  MemberCoupon memberCoupon = promotionManager.detectCoupon(

  sellerId, mcId, cartViewold.getCartList());

  //查询要结算的某卖家的购物信息

  CartView cartView = cartBuilder.renderSku(CheckedWay.valueOf(way))

  .countPrice(true).build();

  //设置优惠券 goodsPrice

  promotionManager.useCoupon(sellerId, mcId, cartView.getCartList(),

  memberCoupon);

  }

  }

  @Service

  public class CartPromotionManagerImpl implements CartPromotionManager {

  @Override

  public void useCoupon(Long sellerId, Long mcId, List cartList,

  MemberCoupon memberCoupon) {

  if (memberCoupon != null) {

  //查询选中的促销

  SelectedPromotionVo selectedPromotionVo = getSelectedPromotion();

  CouponVO couponVO = new CouponVO(memberCoupon);

  SelectedPromotionVo selectedPromotion = getSelectedPromotion();

  selectedPromotion.putCooupon(sellerId, couponVO);

  logger.debug("使用优惠券:" + couponVO);

  logger.debug("促销信息为:" + selectedPromotionVo);

  String cacheKey = this.getOriginKey();

  cache.put(cacheKey, selectedPromotion);

  }

  }

  }

创建和删除优惠券促销脚本

  @Component("couponScriptTimeTriggerExecuter")

  public class CouponScriptTimeTriggerExecuter implements TimeTriggerExecuter {

  @Override

  public void execute(Object object) {

  PromotionScriptMsg promotionScriptMsg = (PromotionScriptMsg) object;

  //获取促销活动ID

  Long promotionId = promotionScriptMsg.getPromotionId();

  //优惠券级别缓存key

  String cacheKey = CachePrefix.COUPON_PROMOTION.getPrefix() + promotionId;

  //如果是优惠券开始生效

  if (ScriptOperationTypeEnum.CREATE.equals(

  promotionScriptMsg.getOperationType())) {

  //获取优惠券详情

  CouponDO coupon = this.couponClient.getModel(promotionId);

  //渲染并读取优惠券脚本信息

  String script = renderCouponScript(coupon);

  //将优惠券脚本信息放入缓存

  cache.put(cacheKey, script);

  //优惠券生效后,立马设置一个优惠券失效的流程

  promotionScriptMsg.setOperationType(ScriptOperationTypeEnum.DELETE);

  String uniqueKey = "{TIME_TRIGGER_"

  + promotionScriptMsg.getPromotionType().name()

  + "}_" + promotionId;

  timeTrigger.add(TimeExecute.COUPON_SCRIPT_EXECUTER, promotionScriptMsg,

  promotionScriptMsg.getEndTime(), uniqueKey);

  this.logger.debug("优惠券[" + promotionScriptMsg.getPromotionName()

  + "]开始生效,id=[" + promotionId + "]");

  } else {

  //删除缓存中的促销脚本数据

  cache.remove(cacheKey);

  this.logger.debug("优惠券[" + promotionScriptMsg.getPromotionName()

  + "]已经失效,id=[" + promotionId + "]");

  }

  }

  /**

  * 渲染并读取优惠券脚本信息

  * @param coupon 优惠券信息

  * @return

  */

  private String renderCouponScript(CouponDO coupon) {

  Map model = new HashMap<>();

  Map params = new HashMap<>();

  params.put("startTime", coupon.getStartTime().toString());

  params.put("endTime", coupon.getEndTime().toString());

  params.put("couponPrice", coupon.getCouponPrice());

  model.put("coupon", params);

  String path = "coupon.ftl";

  String script = ScriptUtil.renderScript(path, model);

  logger.debug("生成优惠券脚本:" + script);

  return script;

  }

  }

优惠券脚本引擎模板文件—coupon.ftl

  <#--验证优惠券是否在有效期内@param coupon 优惠券信息对象(内置常量)

  .startTime 有效期开始时间

  .endTime 有效期结束时间@param $currentTime 当前时间(变量)@return {boolean}-->

  function validTime(){

  if (${coupon.startTime} <= $currentTime && $currentTime <= ${coupon.endTime}) {

  return true;

  }

  return false;

  }

  <#--优惠券金额计算@param coupon 优惠券信息对象(内置常量)

  .couponPrice 优惠券面额@param $price 商品总价(变量,如果有商品参与了其它促销活动,为商品优惠后的总价)@returns {*}-->

  function countPrice() {

  var resultPrice = $price - ${coupon.couponPrice};

  return resultPrice < 0 ? 0 : resultPrice.toString();

  }

  根据以上内容可以了解到优惠券的代码设计是怎么样的,想了解更多详情,可以持续关注易族智汇javashop

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

后台-系统设置-扩展变量-手机广告位-内容正文底部
留言与评论(共有 0 条评论)
   
验证码: