促销活动核心逻辑说明:促销商品价格计算

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

  促销商品价格计算

  1.渲染促销活动

  接口调用流程图:


  相关代码展示

  渲染促销信息主方法

  com.enation.app.javashop.service.trade.cart.cartbuilder.impl.CartPromotionRendererImpl#renderPromotion

  /**

  * 渲染促销提示信息

  * @param cartList

  */

  private void renderPromotion(List cartList){

  //循环购物车,取出购物车所有sku

  List cartSkuVOS = new ArrayList<>();

  for (CartVO cartVO:cartList) {

  cartSkuVOS.addAll(cartVO.getSkuList());

  }

  //首先检测已使用的活动是否失效,如果失效则移除

  this.cartPromotionManager.checkPromotionInvalid();

  //获取购物车中所有商品参与的促销活动

  List promotions = this.scriptProcess.readSkuScript(cartSkuVOS);

  if(promotions == null || promotions.isEmpty()){

  promotions = new ArrayList<>();

  }

  //获取选中的促销活动

  SelectedPromotionVo selectedPromotionVo = cartPromotionManager.getSelectedPromotion();

  //用户选择的组合活动

  Map groupPromotionMap = selectedPromotionVo.getGroupPromotionMap();

  //用户选择的单品活动

  Map> singlePromotionMap = selectedPromotionVo.getSinglePromotionMap();

  //循环购物车,渲染购物车中促销信息

  for (CartVO cartVO:cartList) {

  //获取当前购物车用户选择的组合活动

  CartPromotionVo groupPromotion = groupPromotionMap.get(cartVO.getSellerId());

  List promotionsList = new ArrayList<>(promotions);

  //获取当前购物车用户选择的单品活动

  List singlePromotions = singlePromotionMap.get(cartVO.getSellerId());

  if(singlePromotions == null){

  singlePromotions = new ArrayList<>();

  }

  //全部商品参与的活动 读取"全部商品"参与的促销活动

  List promotionScripts = this.scriptProcess.readCartScript(cartVO.getSellerId());

  //如果不为空,则将全部商品参与的促销活动加入促销活动列表中

  if(promotionScripts != null && !promotionScripts.isEmpty()){

  promotionsList.addAll(promotionScripts);

  }

  //渲染sku促销信息

  renderSkuPromotion(promotionsList, cartVO, groupPromotion, singlePromotions);

  //设置购物车促销提示

  cartVO.setPromotionNotice(this.createNotice(cartVO.getPromotionList()));

  }

  }

  渲染SKU级别促销脚本信息

  com.enation.app.javashop.service.trade.cart.cartbuilder.impl.ScriptProcessImpl#readSkuScript(java.util.List)

  @Override

  public List readSkuScript(List skuList){

  List skuKeys = new ArrayList<>();

  for (CartSkuVO cartSkuVO :skuList){

  skuKeys.add(CachePrefix.SKU_PROMOTION.getPrefix() +cartSkuVO.getSkuId());

  }

  List> skuScripts = cache.multiGet(skuKeys);

  List result = new ArrayList<>();

  for (List scriptVO:skuScripts) {

  if(scriptVO != null && !scriptVO.isEmpty()){

  result.addAll(scriptVO);

  }

  }

  return result;

  }

  获取选中的促销活动

  com.enation.app.javashop.service.trade.cart.impl.CartPromotionManagerImpl#getSelectedPromotion

  /**

  * 由缓存中读取出用户选择的促销信息

  *

  * @return 用户选择的促销信息

  */

  @Override

  public SelectedPromotionVo getSelectedPromotion() {

  String cacheKey = this.getOriginKey();

  SelectedPromotionVo selectedPromotionVo = (SelectedPromotionVo) cache.get(cacheKey);

  if (selectedPromotionVo == null) {

  selectedPromotionVo = new SelectedPromotionVo();

  cache.put(cacheKey, selectedPromotionVo);

  }

  return selectedPromotionVo;

  }

  渲染店铺(购物车)级别促销脚本信息

  com.enation.app.javashop.service.trade.cart.cartbuilder.impl.ScriptProcessImpl#readCartScript

  @Override

  public List readCartScript(Long sellerId){

  List scriptVO = (List) cache.get(CachePrefix.CART_PROMOTION.getPrefix() + sellerId);

  return scriptVO;

  }

  2.促销活动商品价格计算

  接口调用流程图

  CartPriceCalculatorImpl内部实现:

  相关代码展示

  价格计算核心代码--CartPriceCalculatorImpl

  @Override

  public PriceDetailVO countPrice(List cartList, Boolean includeCoupon) {

  //如果不包含优惠券计算,则将选中的优惠券信息删除

  if (!includeCoupon) {

  cartPromotionManager.cleanCoupon();

  }

  //根据规则计算价格

  PriceDetailVO priceDetailVO = this.countPriceWithScript(cartList, includeCoupon);

  return priceDetailVO;

  }

  /**

  * 根据促销脚本计算价格

  *

  * @param cartList 购物车列表

  * @param includeCoupon 是否包含优惠券

  * @return

  */

  private PriceDetailVO countPriceWithScript(List cartList, boolean includeCoupon) {

  PriceDetailVO price = new PriceDetailVO();

  //获取选中的促销活动

  SelectedPromotionVo selectedPromotionVo = cartPromotionManager.getSelectedPromotion();

  //用户选择的组合活动

  Map groupPromotionMap = selectedPromotionVo.getGroupPromotionMap();

  //用户选择的单品活动

  Map> singlePromotionMap = selectedPromotionVo.getSinglePromotionMap();

  //用户选择使用的优惠券

  Map couponMap = selectedPromotionVo.getCouponMap();

  for (CartVO cart : cartList) {

  //未选中的购物车不参与计算

  if (cart.getChecked() == 0) {

  continue;

  }

  //获取当前购物车用户选择的组合活动

  CartPromotionVo groupPromotion = groupPromotionMap.get(cart.getSellerId());

  //获取当前购物车用户选择的单品活动

  List singlePromotions = singlePromotionMap.get(cart.getSellerId());

  PriceDetailVO cartPrice = new PriceDetailVO();

  cartPrice.setFreightPrice(cart.getPrice().getFreightPrice());

  List groupSkuList = new ArrayList<>();

  for (CartSkuVO cartSku : cart.getSkuList()) {

  //未选中的商品不参与计算

  if (cartSku.getChecked() == 0) {

  continue;

  }

  //计算单品活动促销优惠

  this.calculatorSingleScript(cart, singlePromotions, cartPrice, cartSku);

  if (cartSku.getGroupList().contains(groupPromotion)) {

  groupSkuList.add(cartSku);

  }

  }

  //计算满减优惠,返回是否免运费

  Boolean freeShipping = calculatorGroupScript(cart, groupPromotion, cartPrice, groupSkuList);

  //单品规则中有免运费或满减里有免运费

  if (freeShipping) {

  cartPrice.setIsFreeFreight(1);

  cartPrice.setFreightPrice(0D);

  }

  //是否计算优惠券优惠价格

  Long sellerId = cart.getSellerId();

  if (includeCoupon) {

  CouponVO couponVO = couponMap.get(sellerId);

  calculatorCoupon(cartPrice, couponVO);

  }

  //计算店铺商品总优惠金额

  double totalDiscount = CurrencyUtil.add(cartPrice.getCashBack(), cartPrice.getCouponPrice());

  cartPrice.setDiscountPrice(totalDiscount);

  //总价为商品价加运费

  double totalPrice = CurrencyUtil.add(cartPrice.getTotalPrice(), cartPrice.getFreightPrice());

  cartPrice.setTotalPrice(totalPrice);

  cart.setPrice(cartPrice);

  price = price.plus(cartPrice);

  }

  //是否计算优惠券价格 此处针对平台优惠券

  if (includeCoupon) {

  CouponVO couponVO = couponMap.get(0L);

  calculatorCoupon(price, couponVO);

  }

  logger.debug("计算完优惠后购物车数据为:");

  logger.debug(cartList);

  logger.debug("价格为:");

  logger.debug(price);

  return price;

  }

  ```

  计算组合活动优惠

  ```java

  /**

  * 计算组合活动优惠

  *

  * @param cart 购物车

  * @param groupPromotion 组合活动

  * @param cartPrice 购物车价格VO

  * @param groupSkuList 参与组合活动的skuVO

  * @return 是否免运费 true 免运费 false不免运费

  */

  private Boolean calculatorGroupScript(CartVO cart, CartPromotionVo groupPromotion, PriceDetailVO cartPrice, List groupSkuList) {

  Boolean freeShipping = false;

  if (groupPromotion != null && groupSkuList.size() > 0) {

  Double cost;

  String giftJson;

  Double totalGroupPrice = 0D;

  for (CartSkuVO cartSku : groupSkuList) {

  //如果商品是积分商品,则不参与满减优惠

  // if (GoodsType.POINT.name().equals(cartSku.getGoodsType())) {

  // continue;

  // }

  totalGroupPrice += cartSku.getSubtotal();

  }

  Map param = new HashedMap();

  param.put("$price", totalGroupPrice);

  cost = scriptProcess.countPrice(groupPromotion.getPromotionScript(), param);

  //获取赠品信息

  giftJson = scriptProcess.giveGift(groupPromotion.getPromotionScript(), param);

  //设置购物车赠品信息

  cart.setGiftJson(giftJson);

  //计算优惠前后差价

  Double diffPrice = CurrencyUtil.sub(totalGroupPrice, cost);

  //设置返现金额

  cartPrice.setCashBack(CurrencyUtil.add(cartPrice.getCashBack(), diffPrice));

  //设置满减优惠金额

  cartPrice.setFullMinus(diffPrice);

  //设置优惠后的金额

  cartPrice.setTotalPrice(CurrencyUtil.sub(cartPrice.getTotalPrice(), diffPrice));

  if (!StringUtil.isEmpty(giftJson)) {

  List giftList = JsonUtil.jsonToList(giftJson, GiveGiftVO.class);

  for (GiveGiftVO giveGiftVO : giftList) {

  if ("freeShip".equals(giveGiftVO.getType())) {

  freeShipping = (Boolean) giveGiftVO.getValue();

  }

  }

  }

  }

  return freeShipping;

  }

  ```

  计算单品活动优惠

  ```java

  /**

  * 计算单品活动优惠

  *

  * @param cart 购物车

  * @param singlePromotions 参与的单品活动

  * @param cartPrice 当前购物车价格

  * @param cartSku 当前skuVO

  */

  private void calculatorSingleScript(CartVO cart, List singlePromotions, PriceDetailVO cartPrice, CartSkuVO cartSku) {

  Double cost;

  Integer point = 0;

  if (CartType.CHECKOUT.equals(cart.getCartType()) && cartSku.getChecked() == 0) {

  return;

  }

  CartPromotionVo promotionVo = null;

  if (singlePromotions != null) {

  for (CartPromotionVo cartPromotionVo : singlePromotions) {

  if (cartSku.getSkuId().equals(cartPromotionVo.getSkuId())) {

  promotionVo = cartPromotionVo;

  break;

  }

  }

  }

  //转换脚本参数

  ScriptSkuVO skuVO = new ScriptSkuVO(cartSku);

  Map param = new HashedMap();

  param.put("$sku", skuVO);

  //商品参与了用户选择的活动

  if (promotionVo != null) {

  //获取优惠后的价格

  cost = scriptProcess.countPrice(promotionVo.getPromotionScript(), param);

  //获取积分兑换所需积分

  logger.debug("用户选择参与的促销活动类型:" + promotionVo.getPromotionType());

  if (PromotionTypeEnum.EXCHANGE.name().equals(promotionVo.getPromotionType())) {

  point = scriptProcess.countPoint(promotionVo.getPromotionScript(), param);

  }

  //设置商品单品成交单价

  calculatorPurchasePrice(cartSku, cost, promotionVo.getPromotionType());

  cartSku.setPoint(point);

  cartSku.setSubtotal(cost);

  }

  //未选中的不计入合计中

  if (cartSku.getChecked() == 0) {

  return;

  }

  //购物车全部商品的原价合

  cartPrice.setOriginalPrice(CurrencyUtil.add(cartPrice.getOriginalPrice(), CurrencyUtil.mul(cartSku.getOriginalPrice(), cartSku.getNum())));

  //购物车所有小计合

  cartPrice.setGoodsPrice(CurrencyUtil.add(cartPrice.getGoodsPrice(), cartSku.getSubtotal()));

  //购物车返现合

  cartPrice.setCashBack(CurrencyUtil.add(cartPrice.getCashBack(), CurrencyUtil.sub(CurrencyUtil.mul(cartSku.getOriginalPrice(), cartSku.getNum()), cartSku.getSubtotal())));

  //购物车使用积分

  cartPrice.setExchangePoint(cartPrice.getExchangePoint() + cartSku.getPoint());

  //购物车小计

  cartPrice.setTotalPrice(CurrencyUtil.add(cartPrice.getTotalPrice(), cartSku.getSubtotal()));

  //累计商品重量

  double weight = CurrencyUtil.mul(cartSku.getGoodsWeight(), cartSku.getNum());

  double cartWeight = CurrencyUtil.add(cart.getWeight(), weight);

  cart.setWeight(cartWeight);

  }

  ```

  返回结果对象--PriceDetailVO

  ```java

  @ApiModel(value = "PriceDetailVO", description = "价格明细")

  @JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)

  public class PriceDetailVO implements Serializable {

  @ApiModelProperty(value = "总价")

  private Double totalPrice;

  @ApiModelProperty(value = "商品原价,没有优惠过的")

  private Double originalPrice;

  @ApiModelProperty(value = "商品价格,优惠后的")

  private Double goodsPrice;

  @ApiModelProperty(value = "配送费")

  private Double freightPrice;

  @ApiModelProperty(value = "优惠金额")

  private Double discountPrice;

  @ApiModelProperty(value = "返现金额,不含优惠券")

  private Double cashBack;

  @ApiModelProperty(value = "优惠券抵扣金额")

  private Double couponPrice;

  @ApiModelProperty(value = "满减金额")

  private Double fullMinus;

  @ApiModelProperty(value = "是否免运费,1为免运费")

  private Integer isFreeFreight;

  @ApiModelProperty(value = "使用的积分")

  private Long exchangePoint;

  /**

  * 构造器,初始化默认值

  */

  public PriceDetailVO() {

  this.goodsPrice = 0.0;

  this.freightPrice = 0.0;

  this.totalPrice = 0.0;

  this.discountPrice = 0.0;

  this.exchangePoint = 0L;

  this.isFreeFreight = 0;

  this.couponPrice = 0D;

  this.cashBack = 0D;

  this.originalPrice = 0D;

  fullMinus = 0d;

  }

  /**

  * 清空功能

  */

  public void clear() {

  this.goodsPrice = 0.0;

  this.freightPrice = 0.0;

  this.totalPrice = 0.0;

  this.discountPrice = 0.0;

  this.exchangePoint = 0L;

  this.isFreeFreight = 0;

  this.cashBack = 0D;

  this.originalPrice=0D;

  this.couponPrice=0D;

  fullMinus = 0d;

  }

  /**

  * 价格累加运算

  * @param price

  * @return

  */

  public PriceDetailVO plus(PriceDetailVO price) {

  double total = CurrencyUtil.add(totalPrice, price.getTotalPrice());

  double original = CurrencyUtil.add(originalPrice, price.getOriginalPrice());

  double goods = CurrencyUtil.add(goodsPrice, price.getGoodsPrice());

  double freight = CurrencyUtil.add(this.freightPrice, price.getFreightPrice());

  double discount = CurrencyUtil.add(this.discountPrice, price.getDiscountPrice());

  double couponPrice = CurrencyUtil.add(this.couponPrice, price.getCouponPrice());

  double cashBack = CurrencyUtil.add(this.cashBack, price.getCashBack());

  double fullMinus = CurrencyUtil.add(this.cashBack, price.getFullMinus());

  Long point = this.exchangePoint + price.getExchangePoint();

  PriceDetailVO newPrice = new PriceDetailVO();

  newPrice.setTotalPrice(total);

  newPrice.setGoodsPrice(goods);

  newPrice.setFreightPrice(freight);

  newPrice.setDiscountPrice(discount);

  newPrice.setExchangePoint(point);

  newPrice.setCouponPrice(couponPrice);

  newPrice.setCashBack(cashBack);

  newPrice.setIsFreeFreight(price.getIsFreeFreight());

  newPrice.setOriginalPrice(original);

  newPrice.setFullMinus(fullMinus);

  return newPrice;

  }

  /**

  * 当前店铺总价计算

  */

  public void countPrice() {

  //购物车内当前商家的商品原价总计

  Double goodsPrice = this.getGoodsPrice();

  //购物车内当前商家的配送金额总计

  Double freightPrice = this.getFreightPrice();

  //购物车内当前商家的应付金额总计

  //运算过程=商品原价总计-返现金额+配送费用

  Double totalPrice = CurrencyUtil.add(CurrencyUtil.sub(goodsPrice, this.getCashBack()), freightPrice);

  //运算过程=商品原价总计-优惠券金额

  totalPrice = CurrencyUtil.sub(totalPrice, this.getCouponPrice());

  //防止金额为负数

  if (totalPrice.doubleValue() <= 0) {

  totalPrice = 0d;

  }

  this.setTotalPrice(totalPrice);

  }

  //get、set、equals、toString等方法略

  }

  ```

  综上所述,可以了解到促销商品价格计算的详细内容,想要了解更多技术方面的内容,可以持续关注易族智汇javashop 技术文档栏目。

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

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

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