From 5790bb6480272342f074c12ff5ecff0aec62c775 Mon Sep 17 00:00:00 2001 From: zhh Date: Mon, 27 Aug 2018 17:30:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=A1=E7=AE=97=E8=B4=AD?= =?UTF-8?q?=E7=89=A9=E8=BD=A6=E4=BC=98=E6=83=A0=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/OmsCartItemController.java | 22 +- .../mall/portal/dao/PortalProductDao.java | 4 + .../mall/portal/domain/CartPromotionItem.java | 41 +++ .../mall/portal/domain/PromotionProduct.java | 45 +++ .../portal/service/OmsCartItemService.java | 11 + .../portal/service/OmsPromotionService.java | 18 ++ .../service/impl/OmsCartItemServiceImpl.java | 31 +++ .../service/impl/OmsPromotionServiceImpl.java | 261 ++++++++++++++++++ .../main/resources/dao/PortalProductDao.xml | 35 +++ .../mall/portal/PortalProductDaoTests.java | 34 +++ 10 files changed, 500 insertions(+), 2 deletions(-) create mode 100644 mall-portal/src/main/java/com/macro/mall/portal/domain/CartPromotionItem.java create mode 100644 mall-portal/src/main/java/com/macro/mall/portal/domain/PromotionProduct.java create mode 100644 mall-portal/src/main/java/com/macro/mall/portal/service/OmsPromotionService.java create mode 100644 mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPromotionServiceImpl.java create mode 100644 mall-portal/src/test/java/com/macro/mall/portal/PortalProductDaoTests.java diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsCartItemController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsCartItemController.java index 12f2332..a177ba2 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsCartItemController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsCartItemController.java @@ -2,6 +2,7 @@ package com.macro.mall.portal.controller; import com.macro.mall.model.OmsCartItem; import com.macro.mall.portal.domain.CartProduct; +import com.macro.mall.portal.domain.CartPromotionItem; import com.macro.mall.portal.domain.CommonResult; import com.macro.mall.portal.service.OmsCartItemService; import com.macro.mall.portal.service.UmsMemberService; @@ -30,7 +31,6 @@ public class OmsCartItemController { @RequestMapping(value = "/add", method = RequestMethod.POST) @ResponseBody public Object add(@RequestBody OmsCartItem cartItem) { - cartItem.setMemberId(memberService.getCurrentMember().getId()); int count = cartItemService.add(cartItem); if (count > 0) { return new CommonResult().success(count); @@ -46,6 +46,14 @@ public class OmsCartItemController { return new CommonResult().success(cartItemList); } + @ApiOperation("获取某个会员的购物车列表,包括促销信息") + @RequestMapping(value = "/list/promotion", method = RequestMethod.GET) + @ResponseBody + public Object listPromotion() { + List cartPromotionItemList = cartItemService.listPromotion(memberService.getCurrentMember().getId()); + return new CommonResult().success(cartPromotionItemList); + } + @ApiOperation("修改购物车中某个商品的数量") @RequestMapping(value = "/update/quantity", method = RequestMethod.GET) @ResponseBody @@ -70,7 +78,6 @@ public class OmsCartItemController { @RequestMapping(value = "/update/attr", method = RequestMethod.POST) @ResponseBody public Object updateAttr(@RequestBody OmsCartItem cartItem) { - cartItem.setMemberId(memberService.getCurrentMember().getId()); int count = cartItemService.updateAttr(cartItem); if (count > 0) { return new CommonResult().success(count); @@ -88,4 +95,15 @@ public class OmsCartItemController { } return new CommonResult().failed(); } + + @ApiOperation("清空购物车") + @RequestMapping(value = "/clear", method = RequestMethod.POST) + @ResponseBody + public Object clear() { + int count = cartItemService.clear(memberService.getCurrentMember().getId()); + if (count > 0) { + return new CommonResult().success(count); + } + return new CommonResult().failed(); + } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/dao/PortalProductDao.java b/mall-portal/src/main/java/com/macro/mall/portal/dao/PortalProductDao.java index 03f8ccd..0e3a296 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/dao/PortalProductDao.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/dao/PortalProductDao.java @@ -1,12 +1,16 @@ package com.macro.mall.portal.dao; import com.macro.mall.portal.domain.CartProduct; +import com.macro.mall.portal.domain.PromotionProduct; import org.apache.ibatis.annotations.Param; +import java.util.List; + /** * 前台系统自定义商品Dao * Created by macro on 2018/8/2. */ public interface PortalProductDao { CartProduct getCartProduct(@Param("id") Long id); + List getPromotionProductList(@Param("ids") List ids); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/CartPromotionItem.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/CartPromotionItem.java new file mode 100644 index 0000000..7a6dbfa --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/CartPromotionItem.java @@ -0,0 +1,41 @@ +package com.macro.mall.portal.domain; + +import com.macro.mall.model.OmsCartItem; + +import java.math.BigDecimal; + +/** + * Created by macro on 2018/8/27. + * 购物车中促销信息的封装 + */ +public class CartPromotionItem { + private OmsCartItem cartItem; + //促销活动信息 + private String promotionMessage; + //促销活动减去的金额,针对每个商品 + private BigDecimal reduceAmount; + + public OmsCartItem getCartItem() { + return cartItem; + } + + public void setCartItem(OmsCartItem cartItem) { + this.cartItem = cartItem; + } + + public String getPromotionMessage() { + return promotionMessage; + } + + public void setPromotionMessage(String promotionMessage) { + this.promotionMessage = promotionMessage; + } + + public BigDecimal getReduceAmount() { + return reduceAmount; + } + + public void setReduceAmount(BigDecimal reduceAmount) { + this.reduceAmount = reduceAmount; + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/PromotionProduct.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/PromotionProduct.java new file mode 100644 index 0000000..0ffe06c --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/PromotionProduct.java @@ -0,0 +1,45 @@ +package com.macro.mall.portal.domain; + +import com.macro.mall.model.PmsProduct; +import com.macro.mall.model.PmsProductFullReduction; +import com.macro.mall.model.PmsProductLadder; +import com.macro.mall.model.PmsSkuStock; + +import java.util.List; + +/** + * Created by macro on 2018/8/27. + * 商品的促销信息,包括sku、打折优惠、满减优惠 + */ +public class PromotionProduct extends PmsProduct { + //商品库存信息 + private List skuStockList; + //商品打折信息 + private List productLadderList; + //商品满减信息 + private List productFullReductionList; + + public List getSkuStockList() { + return skuStockList; + } + + public void setSkuStockList(List skuStockList) { + this.skuStockList = skuStockList; + } + + public List getProductLadderList() { + return productLadderList; + } + + public void setProductLadderList(List productLadderList) { + this.productLadderList = productLadderList; + } + + public List getProductFullReductionList() { + return productFullReductionList; + } + + public void setProductFullReductionList(List productFullReductionList) { + this.productFullReductionList = productFullReductionList; + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/OmsCartItemService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/OmsCartItemService.java index e188ec5..ef401df 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/OmsCartItemService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/OmsCartItemService.java @@ -2,6 +2,7 @@ package com.macro.mall.portal.service; import com.macro.mall.model.OmsCartItem; import com.macro.mall.portal.domain.CartProduct; +import com.macro.mall.portal.domain.CartPromotionItem; import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -22,6 +23,11 @@ public interface OmsCartItemService { */ List list(Long memberId); + /** + * 获取包含促销活动信息的购物车列表 + */ + List listPromotion(Long memberId); + /** * 修改某个购物车商品的数量 */ @@ -42,4 +48,9 @@ public interface OmsCartItemService { */ @Transactional int updateAttr(OmsCartItem cartItem); + + /** + * 清空购物车 + */ + int clear(Long memberId); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/OmsPromotionService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/OmsPromotionService.java new file mode 100644 index 0000000..2f521be --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/OmsPromotionService.java @@ -0,0 +1,18 @@ +package com.macro.mall.portal.service; + +import com.macro.mall.model.OmsCartItem; +import com.macro.mall.portal.domain.CartPromotionItem; + +import java.util.List; + +/** + * Created by macro on 2018/8/27. + * 促销管理Service + */ +public interface OmsPromotionService { + /** + * 计算购物车中的促销活动信息 + * @param cartItemList 购物车 + */ + List calcCartPromotion(List cartItemList); +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java index 4df93c8..10d5447 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java @@ -3,14 +3,19 @@ package com.macro.mall.portal.service.impl; import com.macro.mall.mapper.OmsCartItemMapper; import com.macro.mall.model.OmsCartItem; import com.macro.mall.model.OmsCartItemExample; +import com.macro.mall.model.UmsMember; import com.macro.mall.portal.dao.PortalProductDao; import com.macro.mall.portal.domain.CartProduct; +import com.macro.mall.portal.domain.CartPromotionItem; import com.macro.mall.portal.service.OmsCartItemService; +import com.macro.mall.portal.service.OmsPromotionService; +import com.macro.mall.portal.service.UmsMemberService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import java.util.Date; import java.util.List; /** @@ -23,14 +28,24 @@ public class OmsCartItemServiceImpl implements OmsCartItemService { private OmsCartItemMapper cartItemMapper; @Autowired private PortalProductDao productDao; + @Autowired + private OmsPromotionService promotionService; + @Autowired + private UmsMemberService memberService; @Override public int add(OmsCartItem cartItem) { int count; + UmsMember currentMember =memberService.getCurrentMember(); + cartItem.setMemberId(currentMember.getId()); + cartItem.setMemberNickname(currentMember.getNickname()); + cartItem.setDeleteStatus(0); OmsCartItem existCartItem = getCartItem(cartItem); if (existCartItem == null) { + cartItem.setCreateDate(new Date()); count = cartItemMapper.insert(cartItem); } else { + cartItem.setModifyDate(new Date()); existCartItem.setQuantity(existCartItem.getQuantity() + cartItem.getQuantity()); count = cartItemMapper.updateByPrimaryKey(existCartItem); } @@ -67,6 +82,12 @@ public class OmsCartItemServiceImpl implements OmsCartItemService { return cartItemMapper.selectByExample(example); } + @Override + public List listPromotion(Long memberId) { + List cartItemList = list(memberId); + return promotionService.calcCartPromotion(cartItemList); + } + @Override public int updateQuantity(Long id, Long memberId, Integer quantity) { OmsCartItem cartItem = new OmsCartItem(); @@ -96,10 +117,20 @@ public class OmsCartItemServiceImpl implements OmsCartItemService { //删除原购物车信息 OmsCartItem updateCart = new OmsCartItem(); updateCart.setId(cartItem.getId()); + updateCart.setModifyDate(new Date()); updateCart.setDeleteStatus(1); cartItemMapper.updateByPrimaryKeySelective(updateCart); cartItem.setId(null); add(cartItem); return 1; } + + @Override + public int clear(Long memberId) { + OmsCartItem record = new OmsCartItem(); + record.setDeleteStatus(1); + OmsCartItemExample example = new OmsCartItemExample(); + example.createCriteria().andMemberIdEqualTo(memberId); + return cartItemMapper.updateByExampleSelective(record,example); + } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPromotionServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPromotionServiceImpl.java new file mode 100644 index 0000000..737e505 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPromotionServiceImpl.java @@ -0,0 +1,261 @@ +package com.macro.mall.portal.service.impl; + +import com.macro.mall.model.OmsCartItem; +import com.macro.mall.model.PmsProductFullReduction; +import com.macro.mall.model.PmsProductLadder; +import com.macro.mall.model.PmsSkuStock; +import com.macro.mall.portal.dao.PortalProductDao; +import com.macro.mall.portal.domain.CartPromotionItem; +import com.macro.mall.portal.domain.PromotionProduct; +import com.macro.mall.portal.service.OmsPromotionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.*; + +/** + * Created by macro on 2018/8/27. + * 促销管理Service实现类 + */ +@Service +public class OmsPromotionServiceImpl implements OmsPromotionService { + @Autowired + private PortalProductDao portalProductDao; + + @Override + public List calcCartPromotion(List cartItemList) { + //1.先根据productId对CartItem进行分组,以spu为单位进行计算优惠 + Map> productCartMap = groupCartItemBySpu(cartItemList); + //2.查询所有商品的优惠相关信息 + List promotionProductList = getPromotionProductList(cartItemList); + //3.根据商品促销类型计算商品促销优惠价格 + List cartPromotionItemList = new ArrayList<>(); + for (Map.Entry> entry : productCartMap.entrySet()) { + Long productId = entry.getKey(); + PromotionProduct promotionProduct = getPromotionProductById(productId, promotionProductList); + List itemList = entry.getValue(); + Integer promotionType = promotionProduct.getPromotionType(); + if (promotionType == 1) { + //单品促销 + for (OmsCartItem item : itemList) { + CartPromotionItem cartPromotionItem = new CartPromotionItem(); + cartPromotionItem.setCartItem(item); + cartPromotionItem.setPromotionMessage("单品促销"); + //商品原价-促销价 + cartPromotionItem.setReduceAmount(getOriginalPrice(promotionProduct, item.getProductSkuId()).subtract(getSinglePromotionPrice(promotionProduct, item.getProductSkuId()))); + cartPromotionItemList.add(cartPromotionItem); + } + } else if (promotionType == 3) { + //打折优惠 + int count = getCartItemCount(itemList); + PmsProductLadder ladder = getProductLadder(count, promotionProduct.getProductLadderList()); + if(ladder!=null){ + for (OmsCartItem item : itemList) { + CartPromotionItem cartPromotionItem = new CartPromotionItem(); + cartPromotionItem.setCartItem(item); + String message = getLadderPromotionMessage(ladder); + cartPromotionItem.setPromotionMessage(message); + //商品原价-折扣金额*商品原价 + BigDecimal originalPrice = getOriginalPrice(promotionProduct, item.getProductSkuId()); + BigDecimal reduceAmount = originalPrice.subtract(ladder.getDiscount().multiply(originalPrice)); + cartPromotionItem.setReduceAmount(reduceAmount); + cartPromotionItemList.add(cartPromotionItem); + } + }else{ + handleNoReduce(cartPromotionItemList,itemList); + } + } else if (promotionType == 4) { + //满减 + BigDecimal totalAmount= getCartItemAmount(itemList,promotionProductList); + PmsProductFullReduction fullReduction = getProductFullReduction(totalAmount,promotionProduct.getProductFullReductionList()); + if(fullReduction!=null){ + for (OmsCartItem item : itemList) { + CartPromotionItem cartPromotionItem = new CartPromotionItem(); + cartPromotionItem.setCartItem(item); + String message = getFullReductionPromotionMessage(fullReduction); + cartPromotionItem.setPromotionMessage(message); + //(商品原价/总价)*满减金额 + BigDecimal reduceAmount = (getOriginalPrice(promotionProduct,item.getProductSkuId()).divide(totalAmount)).multiply(fullReduction.getReducePrice()); + cartPromotionItem.setReduceAmount(reduceAmount); + cartPromotionItemList.add(cartPromotionItem); + } + }else{ + handleNoReduce(cartPromotionItemList,itemList); + } + } else { + //无优惠 + handleNoReduce(cartPromotionItemList, itemList); + } + } + return cartPromotionItemList; + } + + /** + * 查询所有商品的优惠相关信息 + */ + private List getPromotionProductList(List cartItemList) { + List productIdList = new ArrayList<>(); + for(OmsCartItem cartItem:cartItemList){ + productIdList.add(cartItem.getProductId()); + } + return portalProductDao.getPromotionProductList(productIdList); + } + + /** + * 以spu为单位对购物车中商品进行分组 + */ + private Map> groupCartItemBySpu(List cartItemList) { + Map> productCartMap = new TreeMap<>(); + for (OmsCartItem cartItem : cartItemList) { + List productCartItemList = productCartMap.get(cartItem.getId()); + if (productCartItemList == null) { + productCartItemList = new ArrayList<>(); + productCartItemList.add(cartItem); + productCartMap.put(cartItem.getProductId(), productCartItemList); + } else { + productCartItemList.add(cartItem); + } + } + return productCartMap; + } + + /** + * 获取满减促销消息 + */ + private String getFullReductionPromotionMessage(PmsProductFullReduction fullReduction) { + StringBuilder sb = new StringBuilder(); + sb.append("满减优惠:"); + sb.append("满"); + sb.append(fullReduction.getFullPrice()); + sb.append("元,"); + sb.append("减"); + sb.append(fullReduction.getReducePrice()); + sb.append("元"); + return sb.toString(); + } + + /** + * 对没满足优惠条件的商品进行处理 + */ + private void handleNoReduce(List cartPromotionItemList, List itemList) { + for (OmsCartItem item : itemList) { + CartPromotionItem cartPromotionItem = new CartPromotionItem(); + cartPromotionItem.setCartItem(item); + cartPromotionItem.setPromotionMessage("无优惠"); + cartPromotionItem.setReduceAmount(new BigDecimal(0)); + cartPromotionItemList.add(cartPromotionItem); + } + } + + private PmsProductFullReduction getProductFullReduction(BigDecimal totalAmount,List fullReductionList) { + //按条件从高到低排序 + fullReductionList.sort(new Comparator() { + @Override + public int compare(PmsProductFullReduction o1, PmsProductFullReduction o2) { + return o2.getFullPrice().subtract(o1.getFullPrice()).intValue(); + } + }); + for(PmsProductFullReduction fullReduction:fullReductionList){ + if(totalAmount.subtract(fullReduction.getFullPrice()).intValue()>=0){ + return fullReduction; + } + } + return null; + } + + /** + * 获取打折优惠的促销信息 + */ + private String getLadderPromotionMessage(PmsProductLadder ladder) { + StringBuilder sb = new StringBuilder(); + sb.append("打折优惠:"); + sb.append("满"); + sb.append(ladder.getCount()); + sb.append("件,"); + sb.append("打"); + sb.append(ladder.getDiscount().multiply(new BigDecimal(10))); + sb.append("折"); + return sb.toString(); + } + + /** + * 根据购买商品数量获取满足条件的打折优惠策略 + */ + private PmsProductLadder getProductLadder(int count, List productLadderList) { + //按数量从大到小排序 + productLadderList.sort(new Comparator() { + @Override + public int compare(PmsProductLadder o1, PmsProductLadder o2) { + return o2.getCount() - o1.getCount(); + } + }); + for (PmsProductLadder productLadder : productLadderList) { + if (count >= productLadder.getCount()) { + return productLadder; + } + } + return null; + } + + /** + * 获取购物车中指定商品的数量 + */ + private int getCartItemCount(List itemList) { + int count = 0; + for (OmsCartItem item : itemList) { + count += item.getQuantity(); + } + return count; + } + + /** + * 获取购物车中指定商品的总价 + */ + private BigDecimal getCartItemAmount(List itemList, List promotionProductList) { + BigDecimal amount = new BigDecimal(0); + for (OmsCartItem item : itemList) { + //计算出商品原价 + PromotionProduct promotionProduct = getPromotionProductById(item.getProductId(), promotionProductList); + BigDecimal price = getOriginalPrice(promotionProduct,item.getProductSkuId()); + amount = amount.add(price.multiply(new BigDecimal(item.getQuantity()))); + } + return amount; + } + + /** + * 获取商品的单品促销价格 + */ + private BigDecimal getSinglePromotionPrice(PromotionProduct promotionProduct, Long productSkuId) { + for (PmsSkuStock skuStock : promotionProduct.getSkuStockList()) { + if (productSkuId == skuStock.getId()) { + return skuStock.getPromotionPrice(); + } + } + return null; + } + + /** + * 获取商品的原价 + */ + private BigDecimal getOriginalPrice(PromotionProduct promotionProduct, Long productSkuId) { + for (PmsSkuStock skuStock : promotionProduct.getSkuStockList()) { + if (productSkuId.equals(skuStock.getId())) { + return skuStock.getPrice(); + } + } + return null; + } + + /** + * 根据商品id获取商品的促销信息 + */ + private PromotionProduct getPromotionProductById(Long productId, List promotionProductList) { + for (PromotionProduct promotionProduct : promotionProductList) { + if (productId.equals(promotionProduct.getId())) { + return promotionProduct; + } + } + return null; + } +} diff --git a/mall-portal/src/main/resources/dao/PortalProductDao.xml b/mall-portal/src/main/resources/dao/PortalProductDao.xml index 5b0d1c3..1e35d5a 100644 --- a/mall-portal/src/main/resources/dao/PortalProductDao.xml +++ b/mall-portal/src/main/resources/dao/PortalProductDao.xml @@ -8,6 +8,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/mall-portal/src/test/java/com/macro/mall/portal/PortalProductDaoTests.java b/mall-portal/src/test/java/com/macro/mall/portal/PortalProductDaoTests.java new file mode 100644 index 0000000..228f6e8 --- /dev/null +++ b/mall-portal/src/test/java/com/macro/mall/portal/PortalProductDaoTests.java @@ -0,0 +1,34 @@ +package com.macro.mall.portal; + +import com.macro.mall.portal.dao.PortalProductDao; +import com.macro.mall.portal.domain.PromotionProduct; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by macro on 2018/8/27. + * 前台商品查询逻辑单元测试 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class PortalProductDaoTests { + @Autowired + private PortalProductDao portalProductDao; + @Test + public void testGetPromotionProductList(){ + List ids = new ArrayList<>(); + ids.add(26L); + ids.add(27L); + ids.add(28L); + ids.add(29L); + List promotionProductList = portalProductDao.getPromotionProductList(ids); + Assert.assertEquals(4,promotionProductList.size()); + } +}