购物车逻辑相关处理

This commit is contained in:
Chopper 2021-06-21 11:55:08 +08:00
parent 9546807031
commit 50911137cb
9 changed files with 284 additions and 156 deletions

View File

@ -73,12 +73,11 @@ public class LimitInterceptor {
} else {
throw new ServiceException("访问过于频繁,请稍后再试");
}
} catch (NullPointerException e) {
}
//如果从redis中执行都值判定为空则这里跳过
catch (NullPointerException e) {
return pjp.proceed();
} catch (Exception e) {
if (e instanceof ServiceException) {
throw new ServiceException(e.getLocalizedMessage());
}
throw new RuntimeException("服务器异常,请稍后再试");
}
}

View File

@ -97,8 +97,8 @@ public enum ResultCode {
USER_RECEIPT_NOT_EXIST(20014, "会员发票信息不存在"),
USER_EDIT_ERROR(20015, "用户修改失败"),
USER_OLD_PASSWORD_ERROR(20016, "旧密码不正确"),
USER_COLLECTION_EXIST(20017,"无法重复收藏"),
USER_GRADE_IS_DEFAULT(20018,"会员等级为默认会员等级"),
USER_COLLECTION_EXIST(20017, "无法重复收藏"),
USER_GRADE_IS_DEFAULT(20018, "会员等级为默认会员等级"),
DELETE_EXIST(2001, "无法重复收藏"),
/**
@ -125,62 +125,97 @@ public enum ResultCode {
* 购物车
*/
CART_ERROR(30001, "读取结算页的购物车异常"),
CART_PINTUAN_NOT_EXIST_ERROR(30002, "拼团活动不存在错误"),
CART_PINTUAN_LIMIT_ERROR(30003, "购买数量超过拼团活动限制数量"),
SHIPPING_NOT_APPLY(30005, "购物商品不支持当前收货地址配送"),
/**
* 订单
*/
ORDER_ERROR(31001, "创建订单异常,请稍后重试"),
ORDER_NOT_EXIST(31002, "订单不存在"),
ORDER_DELIVERED_ERROR(31003, "订单状态错误,无法进行确认收货"),
ORDER_UPDATE_PRICE_ERROR(31004, "已支付的订单不能修改金额"),
ORDER_LOGISTICS_ERROR(31005, "物流错误"),
ORDER_DELIVER_ERROR(31006, "物流错误"),
ORDER_NOT_USER(31007, "非当前会员的订单"),
ORDER_TAKE_ERROR(31008, "当前订单无法核销"),
MEMBER_ADDRESS_NOT_EXIST(31009, "订单无收货地址,请先配置收货地址"),
ORDER_DELIVER_NUM_ERROR(31010, "没有待发货的订单"),
/**
* 支付
*/
PAY_UN_WANTED(32000, "当前订单不需要付款,返回订单列表等待系统订单出库即可"),
PAY_SUCCESS(32001, "支付成功"),
PAY_INCONSISTENT_ERROR(32002, "付款金额和应付金额不一致"),
PAY_DOUBLE_ERROR(32003, "订单已支付,不能再次进行支付"),
PAY_CASHIER_ERROR(32004, "收银台信息获取错误"),
PAY_ERROR(32005, "支付业务异常,请稍后重试"),
PAY_BAN(32006, "当前订单不需要付款,请返回订单列表重新操作"),
PAY_PARTIAL_ERROR(32007, "该订单已部分支付,请前往订单中心进行支付"),
PAY_NOT_SUPPORT(32008, "支付暂不支持"),
PAY_CLIENT_TYPE_ERROR(32009, "错误的客户端"),
PAY_POINT_ENOUGH(32010, "积分不足,不能兑换"),
PAY_NOT_EXIST_ORDER(32011, "支付订单不存在"),
/**
* 售后
*/
AFTER_SALES_NOT_PAY_ERROR(33001, "当前订单未支付,不能申请售后"),
AFTER_SALES_CANCEL_ERROR(33002, "当前售后单无法取消"),
AFTER_SALES_BAN(33003, "订单状态不允许申请售后,请联系平台或商家"),
AFTER_SALES_DOUBLE_ERROR(33004, "售后已审核,无法重复操作"),
AFTER_SALES_LOGISTICS_ERROR(33005, "物流公司错误,请重新选择"),
AFTER_STATUS_ERROR(33006, "售后状态错误,请刷新页面"),
/**
* 投诉
*/
COMPLAINT_ORDER_ITEM_EMPTY_ERROR(33100, "订单不存在"),
COMPLAINT_SKU_EMPTY_ERROR(33101, "商品已下架,如需投诉请联系平台客服"),
COMPLAINT_ERROR(33102, "投诉异常,请稍后重试"),
/**
* 余额
*/
WALLET_NOT_EXIT_ERROR(34000, "钱包不存在,请联系管理员"),
WALLET_INSUFFICIENT(34001, "余额不足以支付订单,请充值!"),
WALLET_WITHDRAWAL_INSUFFICIENT(34002, "可提现金额不足!"),
WALLET_ERROR_INSUFFICIENT(34003, "零钱提现失败!"),
WALLET_REMARK_ERROR(34004, "请填写审核备注!"),
WALLET_APPLY_ERROR(34005, "提现申请异常!"),
/**
@ -197,52 +232,74 @@ public enum ResultCode {
* 优惠券
*/
COUPON_EDIT_STATUS_SUCCESS(41001, "修改状态成功!"),
COUPON_CANCELLATION_SUCCESS(41002, "会员优惠券作废成功"),
COUPON_EXPIRED(41003, "优惠券已使用/已过期,不能使用"),
COUPON_EDIT_STATUS_ERROR(41004, "优惠券修改状态失败!"),
/**
* 拼团
*/
PINTUAN_MANUAL_OPEN_SUCCESS(42001, "手动开启拼团活动成功"),
PINTUAN_MANUAL_CLOSE_SUCCESS(42002, "手动关闭拼团活动成功"),
PINTUAN_ADD_SUCCESS(42003, "添加拼团活动成功"),
PINTUAN_EDIT_SUCCESS(42004, "修改拼团活动成功"),
PINTUAN_DELETE_SUCCESS(42005, "删除拼团活动成功"),
PINTUAN_MANUAL_OPEN_ERROR(42006, "手动开启拼团活动失败"),
PINTUAN_MANUAL_CLOSE_ERROR(42007, "手动关闭拼团活动失败"),
PINTUAN_ADD_ERROR(42008, "添加拼团活动失败"),
PINTUAN_EDIT_ERROR(42009, "修改拼团活动失败"),
PINTUAN_DELETE_ERROR(42010, "删除拼团活动失败"),
/**
* 满额活动
*/
FULL_DISCOUNT_EDIT_SUCCESS(43001, "修改满优惠活动成功"),
FULL_DISCOUNT_EDIT_DELETE(43002, "删除满优惠活动成功"),
/**
* 店铺
*/
STORE_NOT_EXIST(50001, "此店铺不存在"),
STORE_NAME_EXIST_ERROR(50002, "店铺名称已存在!"),
STORE_APPLY_DOUBLE_ERROR(50003, "已有店铺,无需重复申请!"),
/**
* 结算单
*/
BILL_CHECK_ERROR(51001, "只有已出账结算单可以核对"),
BILL_COMPLETE_ERROR(51002, "只有已审核结算单可以支付"),
/**
* 文章
*/
ARTICLE_CATEGORY_NAME_EXIST(60001, "文章分类名称已存在"),
ARTICLE_CATEGORY_PARENT_NOT_EXIST(60002, "文章分类父分类不存在"),
ARTICLE_CATEGORY_BEYOND_TWO(60003, "最多为二级分类,操作失败"),
ARTICLE_CATEGORY_DELETE_ERROR(60004, "该文章分类下存在子分类,不能删除"),
ARTICLE_CATEGORY_HAS_ARTICLE(60005, "该文章分类下存在文章,不能删除"),
ARTICLE_CATEGORY_NO_DELETION(60007, "默认文章分类不能进行删除"),
ARTICLE_NO_DELETION(60008, "默认文章不能进行删除"),
@ -250,8 +307,11 @@ public enum ResultCode {
* 页面
*/
PAGE_NOT_EXIST(61001, "页面不存在"),
PAGE_OPEN_DELETE_ERROR(61002, "当前页面为开启状态,无法删除"),
PAGE_DELETE_ERROR(61003, "当前页面为唯一页面,无法删除"),
PAGE_RELEASE_ERROR(61004, "页面已发布,无需重复提交"),
/**
@ -268,39 +328,49 @@ public enum ResultCode {
* 站内信
*/
NOTICE_NOT_EXIST(80101, "当前消息模板不存在"),
NOTICE_ERROR(80102, "修改站内信异常,请稍后重试"),
/**
* OSS
*/
OSS_NOT_EXIST(80201, "OSS未配置"),
OSS_EXCEPTION(80202, "文件上传失败,请稍后重试"),
/**
* 验证码
*/
VERIFICATION_SEND_SUCCESS(80301, "短信验证码,发送成功"),
VERIFICATION_ERROR(80302, "验证失败"),
VERIFICATION_SMS_ERROR(80303, "短信验证码错误,请重新校验"),
VERIFICATION_SMS_EXPIRED_ERROR(80304, "验证码已失效,请重新校验"),
/**
* 配置错误
*/
ALIPAY_NOT_SETTING(80401, "支付宝支付未配置"),
ALIPAY_EXCEPTION(80402, "支付宝支付错误,请稍后重试"),
ALIPAY_PARAMS_EXCEPTION(80403, "支付宝参数异常"),
/**
* 微信相关异常
*/
WECHAT_CONNECT_NOT_SETTING(80500, "微信联合登陆信息未配置"),
WECHAT_PAYMENT_NOT_SETTING(80501, "微信支付信息未配置"),
WECHAT_QRCODE_ERROR(80502, "微信二维码生成异常"),
WECHAT_MP_MESSAGE_ERROR(80503, "微信小程序小消息订阅异常"),
APP_VERSION_EXIST(80600, "APP版本已存在")
;
APP_VERSION_EXIST(80600, "APP版本已存在");
private final Integer code;
private final String message;

View File

@ -16,7 +16,7 @@ import java.util.List;
import java.util.stream.Collectors;
/**
* TradeBuilder
* 交易构造&&创建
*
* @author Chopper
* @date2020-04-01 9:47 下午
@ -24,36 +24,41 @@ import java.util.stream.Collectors;
@Service
@Slf4j
public class TradeBuilder {
//购物车渲染
//购物车渲染步骤
@Autowired
private List<CartRenderStep> cartRenderSteps;
//交易
@Autowired
private TradeService tradeService;
//购物车业务
@Autowired
private CartService cartService;
/**
* 渲染整比交易
* 0-> 校验商品 1- 满优惠渲染 2->渲染优惠 3->优惠券渲染 4->计算运费 5->计算价格 6->分销渲染 7->扩展操作
*/
int[] defaultRender = {0, 1, 2, 4, 5, 6, 7};
/**
* 购物车购物车渲染
* 0-> 校验商品 1- 满优惠渲染 2->渲染优惠 5->计算价格
*/
int[] cartRender = {0, 1, 2, 5};
/**
* 0-> 校验商品 1- 满优惠渲染 2->渲染优惠 3->优惠券渲染 4->计算运费 5->计算价格 6->分销渲染 7->扩展操作
*/
@Autowired
private CartService cartService;
/**
* 构造购物车
* 购物车与结算信息不一致的地方主要是优惠券计算和运费计算其他规则都是一致都
*
* @param checkedWay 购物车类型
* @return 购物车展示信息
*/
public TradeDTO buildCart(CartTypeEnum checkedWay) {
//读取对应购物车的商品信息
TradeDTO tradeDTO = cartService.readDTO(checkedWay);
//购物车需要将交易中的优惠券取消掉
@ -67,7 +72,7 @@ public class TradeBuilder {
try {
cartRenderSteps.get(index).render(tradeDTO);
} catch (Exception e) {
log.error("购物车渲染异常:", e);
log.error("购物车{}渲染异常:", cartRenderSteps.get(index).getClass(), e);
}
}
return tradeDTO;
@ -80,28 +85,26 @@ public class TradeBuilder {
* @return 购物车展示信息
*/
public TradeDTO buildTrade(CartTypeEnum checkedWay) {
//读取对应购物车的商品信息
TradeDTO tradeDTO = cartService.readDTO(checkedWay);
tradeDTO.setNotSupportFreight(null);
//将购物车到sku未选择信息过滤
List<CartSkuVO> collect = tradeDTO.getSkuList().parallelStream().filter(i -> Boolean.TRUE.equals(i.getChecked())).collect(Collectors.toList());
//拼团类型订单预处理
if (checkedWay.equals(CartTypeEnum.PINTUAN)) {
for (CartSkuVO cartSkuVO : collect) {
cartSkuVO.setPintuanId("");
}
}
tradeDTO.setSkuList(collect);
//按照计划进行渲染
for (int index : defaultRender) {
try {
cartRenderSteps.get(index).render(tradeDTO);
} catch (Exception e) {
log.error("购物车渲染异常:", e);
log.error("购物车{}渲染异常:", cartRenderSteps.get(index).getClass(), e);
}
}
//购物车信息接受
List<CartVO> cartVOList = new ArrayList<>();
for (CartVO i : tradeDTO.getCartList()) {
i.setSkuList(i.getSkuList().stream().filter(j -> Boolean.TRUE.equals(j.getChecked())).collect(Collectors.toList()));
cartVOList.add(i);
//循环购物车信息
for (CartVO cartVO : tradeDTO.getCartList()) {
//如果商品选中则加入到对应购物车
cartVO.setSkuList(cartVO.getSkuList().stream().filter(j -> Boolean.TRUE.equals(j.getChecked())).collect(Collectors.toList()));
cartVOList.add(cartVO);
}
tradeDTO.setCartList(cartVOList);
return tradeDTO;
@ -111,12 +114,10 @@ public class TradeBuilder {
* 创建一笔交易
*
* @param checkedWay 购物车类型
* @param parentOrderSn 是否为其他订单下的订单如果是则为依赖订单的sn否则为空
* @return 交易信息
*/
public Trade createTrade(CartTypeEnum checkedWay, String parentOrderSn) {
public Trade createTrade(CartTypeEnum checkedWay) {
TradeDTO tradeDTO = this.buildTrade(checkedWay);
tradeDTO.setParentOrderSn(parentOrderSn);
return tradeService.createTrade(tradeDTO);
}
}

View File

@ -1,18 +1,28 @@
package cn.lili.modules.order.cart.render.impl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import lombok.RequiredArgsConstructor;
import cn.lili.modules.order.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 商品有效性校验
*
@ -26,10 +36,31 @@ public class CheckDataRender implements CartRenderStep {
@Autowired
private GoodsSkuService goodsSkuService;
@Autowired
private OrderService orderService;
@Override
public void render(TradeDTO tradeDTO) {
//校验商品有效性
checkData(tradeDTO);
//店铺分组数据初始化
groupStore(tradeDTO);
//预校验
preCalibration(tradeDTO);
}
/**
* 校验商品属性
*
* @param tradeDTO
*/
private void checkData(TradeDTO tradeDTO) {
//循环购物车中的商品
for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
//缓存中的商品信息
GoodsSku dataSku = goodsSkuService.getGoodsSkuByIdFromCache(cartSkuVO.getGoodsSku().getId());
//商品有效性判定
if (dataSku == null || dataSku.getUpdateTime().before(cartSkuVO.getGoodsSku().getUpdateTime())) {
//设置购物车未选中
cartSkuVO.setChecked(false);
@ -39,6 +70,7 @@ public class CheckDataRender implements CartRenderStep {
cartSkuVO.setErrorMessage("商品信息发生变化,已失效");
continue;
}
// 商品上架状态判定
if (!GoodsAuthEnum.PASS.name().equals(dataSku.getIsAuth()) || !GoodsStatusEnum.UPPER.name().equals(dataSku.getMarketEnable())) {
//设置购物车未选中
cartSkuVO.setChecked(false);
@ -48,17 +80,59 @@ public class CheckDataRender implements CartRenderStep {
cartSkuVO.setErrorMessage("商品已下架");
continue;
}
//商品库存不足
if (dataSku.getQuantity() <= 0) {
// 商品库存判定
if (dataSku.getQuantity() < cartSkuVO.getNum()) {
//设置购物车未选中
cartSkuVO.setChecked(false);
//设置购物车此sku商品已失效
cartSkuVO.setInvalid(true);
//设置失效消息
cartSkuVO.setErrorMessage("商品库存不足");
cartSkuVO.setErrorMessage("商品库存不足,现有库存数量[" + dataSku.getQuantity() + "]");
}
//写入初始价格
cartSkuVO.getPriceDetailDTO().setGoodsPrice(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum()));
}
}
/**
* 店铺分组
*
* @param tradeDTO
*/
private void groupStore(TradeDTO tradeDTO) {
// 渲染的购物车
List<CartVO> cartList = new ArrayList<>();
// 根据店铺分组
Map<String, List<CartSkuVO>> storeCollect = tradeDTO.getSkuList().parallelStream().collect(Collectors.groupingBy(CartSkuVO::getStoreId));
for (Map.Entry<String, List<CartSkuVO>> storeCart : storeCollect.entrySet()) {
if (!storeCart.getValue().isEmpty()) {
CartVO cartVO = new CartVO(storeCart.getValue().get(0));
if (CharSequenceUtil.isEmpty(cartVO.getDeliveryMethod())) {
cartVO.setDeliveryMethod(DeliveryMethodEnum.LOGISTICS.name());
}
cartVO.setSkuList(storeCart.getValue());
storeCart.getValue().stream().filter(i -> Boolean.TRUE.equals(i.getChecked())).findFirst().ifPresent(cartSkuVO -> cartVO.setChecked(true));
cartList.add(cartVO);
}
}
tradeDTO.setCartList(cartList);
}
/**
* 订单预校验
* 1自己拼团自己创建都拼团判定
*
* @param tradeDTO
*/
private void preCalibration(TradeDTO tradeDTO) {
//拼团判定不能参与自己创建的拼团
if (tradeDTO.getParentOrderSn() != null) {
//订单接受
cn.lili.modules.order.order.entity.dos.Order parentOrder = orderService.getBySn(tradeDTO.getParentOrderSn());
//参与活动判定
if (parentOrder.getMemberId().equals(UserContext.getCurrentUser().getId())) {
throw new ServiceException("不能参与自己发起的拼团活动!");
}
}
}
}

View File

@ -1,15 +1,12 @@
package cn.lili.modules.order.cart.render.impl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.service.FullDiscountService;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.entity.vo.FullDiscountVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import lombok.RequiredArgsConstructor;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.service.FullDiscountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
@ -38,47 +35,47 @@ public class FullDiscountRender implements CartRenderStep {
// 获取购物车中所有的商品
List<CartSkuVO> cartSkuList = tradeDTO.getSkuList();
// 渲染的购物车
List<CartVO> cartList = new ArrayList<>();
// 确定有哪些商家
// 店铺id集合
List<String> storeIds = new ArrayList<>();
// 根据店铺分组
Map<String, List<CartSkuVO>> storeCollect = cartSkuList.parallelStream().collect(Collectors.groupingBy(CartSkuVO::getStoreId));
// 店铺集合
List<CartVO> cartList = tradeDTO.getCartList();
// 获取店铺id
Map<String, List<CartSkuVO>> storeCollect = tradeDTO.getSkuList().parallelStream().collect(Collectors.groupingBy(CartSkuVO::getStoreId));
for (Map.Entry<String, List<CartSkuVO>> storeCart : storeCollect.entrySet()) {
if (!storeCart.getValue().isEmpty()) {
storeIds.add(storeCart.getKey());
CartVO cartVO = new CartVO(storeCart.getValue().get(0));
if (CharSequenceUtil.isEmpty(cartVO.getDeliveryMethod())) {
cartVO.setDeliveryMethod(DeliveryMethodEnum.LOGISTICS.name());
}
cartVO.setSkuList(storeCart.getValue());
storeCart.getValue().stream().filter(i -> Boolean.TRUE.equals(i.getChecked())).findFirst().ifPresent(cartSkuVO -> cartVO.setChecked(true));
cartList.add(cartVO);
}
}
// 获取当前店铺进行到满减活动
List<FullDiscountVO> fullDiscounts = fullDiscountService.currentPromotion(storeIds);
//循环满减信息
for (FullDiscountVO fullDiscount : fullDiscounts) {
//判定参与活动的商品
if (fullDiscount.getPromotionGoodsList() != null || fullDiscount.getNumber() == -1) {
//循环店铺购物车
for (CartVO cart : cartList) {
//如果购物车中的店铺id与活动店铺id相等则进行促销计算
if (fullDiscount.getStoreId().equals(cart.getStoreId())) {
//写入满减活动
cart.setFullDiscount(fullDiscount);
List<String> skuIds;
// 参与活动的sku判定
if (fullDiscount.getNumber() != -1) {
skuIds = initFullDiscountGoods(fullDiscount, cartSkuList);
} else {
skuIds = cart.getSkuList().stream().map(i -> i.getGoodsSku().getId()).collect(Collectors.toList());
}
//记录参与满减活动的sku
cart.setFullDiscountSkuIds(skuIds);
}
}
}
}
tradeDTO.setCartList(cartList);
}
/**
@ -90,8 +87,11 @@ public class FullDiscountRender implements CartRenderStep {
*/
public List<String> initFullDiscountGoods(FullDiscountVO fullDiscount, List<CartSkuVO> cartSkuVOS) {
List<String> goodsIds = new ArrayList<>();
//判定参与活动的商品
for (PromotionGoods promotionGoods : fullDiscount.getPromotionGoodsList()) {
//sku 集合判定
for (CartSkuVO cartSkuVO : cartSkuVOS) {
//如果参加则记录商品sku
if (cartSkuVO.getGoodsSku().getId().equals(promotionGoods.getSkuId())) {
goodsIds.add(promotionGoods.getSkuId());
}

View File

@ -1,6 +1,8 @@
package cn.lili.modules.order.cart.render.impl;
import cn.hutool.core.util.NumberUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.member.entity.dos.MemberAddress;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
@ -36,24 +38,24 @@ public class SkuFreightRender implements CartRenderStep {
List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
//会员收货地址问题处理
MemberAddress memberAddress = tradeDTO.getMemberAddress();
//如果收货地址为空则抛出异常
if (memberAddress == null) {
return;
throw new ServiceException(ResultCode.MEMBER_ADDRESS_NOT_EXIST);
}
//循环渲染购物车商品运费价格
forSku:
for (CartSkuVO cartSkuVO : cartSkuVOS) {
//获取sku运费模版
String freightTemplateId = cartSkuVO.getGoodsSku().getFreightTemplateId();
//免运费则跳出运费计算
if (Boolean.TRUE.equals(cartSkuVO.getIsFreeFreight()) || freightTemplateId == null) {
continue;
}
//寻找对应对商品运费计算模版
FreightTemplateVO freightTemplate = freightTemplateService.getFreightTemplate(freightTemplateId);
if (freightTemplate != null && freightTemplate.getFreightTemplateChildList() != null && !freightTemplate.getFreightTemplateChildList().isEmpty()) {
//店铺支付运费则跳过
if(freightTemplate.getPricingMethod().equals(FreightTemplateEnum.FREE.name())){
if (freightTemplate.getPricingMethod().equals(FreightTemplateEnum.FREE.name())) {
break;
}
FreightTemplateChild freightTemplateChild = null;
@ -68,7 +70,7 @@ public class SkuFreightRender implements CartRenderStep {
break;
}
}
//如果没有匹配到物流规则则说明不支持配送
if (freightTemplateChild == null) {
if (tradeDTO.getNotSupportFreight() == null) {
tradeDTO.setNotSupportFreight(new ArrayList<>());
@ -77,6 +79,7 @@ public class SkuFreightRender implements CartRenderStep {
continue forSku;
}
//物流规则模型创立
FreightTemplateChildDTO freightTemplateChildDTO = new FreightTemplateChildDTO(freightTemplateChild);
freightTemplateChildDTO.setPricingMethod(freightTemplate.getPricingMethod());

View File

@ -1,16 +1,12 @@
package cn.lili.modules.order.cart.service;
import cn.lili.modules.member.entity.dos.MemberAddress;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.TradeParams;
import cn.lili.modules.order.order.entity.dos.Trade;
import cn.lili.modules.order.order.entity.vo.ReceiptVO;
import java.util.List;
/**
* 购物车业务层
*
@ -171,13 +167,4 @@ public interface CartService {
* @return 交易信息
*/
Trade createTrade(TradeParams tradeParams);
/**
* 检查商品是否在配送范围
*
* @param skuList 商品列表
* @param memberAddress 配送地址
*/
void checkAddressScope(List<CartSkuVO> skuList, MemberAddress memberAddress);
}

View File

@ -10,7 +10,6 @@ import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.member.entity.dos.MemberAddress;
import cn.lili.modules.order.cart.entity.dto.MemberCouponDTO;
@ -25,19 +24,17 @@ import cn.lili.modules.order.cart.render.TradeBuilder;
import cn.lili.modules.order.order.entity.dos.Trade;
import cn.lili.modules.order.order.entity.vo.ReceiptVO;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dos.Pintuan;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.enums.CouponScopeTypeEnum;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionTypeEnum;
import cn.lili.modules.promotion.service.MemberAddressService;
import cn.lili.modules.promotion.service.MemberCouponService;
import cn.lili.modules.promotion.service.PintuanService;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsSearchService;
import cn.lili.modules.store.entity.dos.FreightTemplateChild;
import cn.lili.modules.store.entity.enums.FreightTemplateEnum;
import cn.lili.modules.store.entity.vos.FreightTemplateVO;
import cn.lili.modules.store.service.FreightTemplateService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -79,9 +76,10 @@ public class CartServiceImpl implements CartService {
//ES商品
@Autowired
private EsGoodsSearchService esGoodsSearchService;
//运费模板
//拼团服务
@Autowired
private FreightTemplateService freightTemplateService;
private PintuanService pintuanService;
//交易
@Autowired
private TradeBuilder tradeBuilder;
@ -136,10 +134,16 @@ public class CartServiceImpl implements CartService {
promotionGoodsService.updatePromotion(cartSkuVO);
//再设置加入购物车的数量
this.checkSetGoodsQuantity(cartSkuVO, skuId, num);
//拼团判定
checkPintuan(cartTypeEnum, cartSkuVO);
//计算购物车小计
cartSkuVO.setSubTotal(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum()));
cartSkuVOS.add(cartSkuVO);
}
tradeDTO.setCartTypeEnum(cartTypeEnum);
// 如购物车发生更改则重置优惠券
tradeDTO.setStoreCoupons(null);
@ -501,61 +505,15 @@ public class CartServiceImpl implements CartService {
//设置基础属性
tradeDTO.setClientType(tradeParams.getClient());
tradeDTO.setStoreRemark(tradeParams.getRemark());
//过滤勾选商品
List<CartSkuVO> collect = tradeDTO.getSkuList().parallelStream().filter(i -> Boolean.TRUE.equals(i.getChecked())).collect(Collectors.toList());
//校验收获地址
MemberAddress memberAddress = tradeDTO.getMemberAddress();
this.checkAddressScope(collect, memberAddress);
tradeDTO.setParentOrderSn(tradeParams.getParentOrderSn());
//将购物车信息写入缓存后续逻辑调用校验
this.resetTradeDTO(tradeDTO);
//构建交易
Trade trade = tradeBuilder.createTrade(cartTypeEnum, tradeParams.getParentOrderSn());
Trade trade = tradeBuilder.createTrade(cartTypeEnum);
this.cleanChecked(tradeDTO);
return trade;
}
/**
* 检查商品是否在配送范围
*
* @param skuList 商品列表
* @param memberAddress 配送地址
*/
@Override
public void checkAddressScope(List<CartSkuVO> skuList, MemberAddress memberAddress) {
//如果收货地址为空则抛出异常
if (memberAddress == null) {
throw new ServiceException(ResultCode.MEMBER_ADDRESS_NOT_EXIST);
}
//循环购物车列表计算运费
for (CartSkuVO cartSkuVO : skuList) {
GoodsSku goodsSku = cartSkuVO.getGoodsSku();
//如果是虚拟商品无需运费
if (goodsSku.getGoodsType() != null && goodsSku.getGoodsType().equals(GoodsTypeEnum.VIRTUAL_GOODS.name())) {
break;
}
//获取运费模板ID
String freightTemplateId = cartSkuVO.getGoodsSku().getFreightTemplateId();
FreightTemplateVO freightTemplate = freightTemplateService.getFreightTemplate(freightTemplateId);
//店铺支付运费则跳过
if (freightTemplate.getPricingMethod().equals(FreightTemplateEnum.FREE.name())) {
break;
}
//收货地址判定
forTemplates:
if (freightTemplate != null && freightTemplate.getFreightTemplateChildList() != null && !freightTemplate.getFreightTemplateChildList().isEmpty()) {
//获取市级别id
String addressId = memberAddress.getConsigneeAddressIdPath().split(",")[1];
//获取匹配的收货地址
for (FreightTemplateChild templateChild : freightTemplate.getFreightTemplateChildList()) {
//如果当前模版包含则返回
if (templateChild.getAreaId().contains(addressId)) {
break forTemplates;
}
}
throw new ServiceException(ResultCode.SHIPPING_NOT_APPLY, cartSkuVO.getGoodsSku().getGoodsName());
}
}
}
/**
* 获取购物车类型
@ -576,6 +534,13 @@ public class CartServiceImpl implements CartService {
return cartTypeEnum;
}
/**
* 使用优惠券判定
*
* @param tradeDTO 交易对象
* @param memberCoupon 会员优惠券
* @param cartTypeEnum 购物车
*/
private void useCoupon(TradeDTO tradeDTO, MemberCoupon memberCoupon, CartTypeEnum cartTypeEnum) {
//如果是平台优惠券
if (Boolean.TRUE.equals(memberCoupon.getIsPlatform())) {
@ -583,24 +548,34 @@ public class CartServiceImpl implements CartService {
Double cartPrice = 0d;
for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
// 获取商品的促销信息
Optional<PromotionGoods> promotionOptional = cartSkuVO.getPromotions().parallelStream().filter(i -> (i.getPromotionType().equals(PromotionTypeEnum.PINTUAN.name()) && cartTypeEnum.equals(CartTypeEnum.PINTUAN))
|| i.getPromotionType().equals(PromotionTypeEnum.SECKILL.name())).findAny();
Optional<PromotionGoods> promotionOptional =
cartSkuVO.getPromotions().parallelStream().filter(promotionGoods ->
(promotionGoods.getPromotionType().equals(PromotionTypeEnum.PINTUAN.name()) &&
cartTypeEnum.equals(CartTypeEnum.PINTUAN)) ||
promotionGoods.getPromotionType().equals(PromotionTypeEnum.SECKILL.name())).findAny();
//有促销金额则用促销金额否则用商品原价
if (promotionOptional.isPresent()) {
cartPrice += CurrencyUtil.mul(promotionOptional.get().getPrice(), cartSkuVO.getNum());
cartPrice = CurrencyUtil.add(cartPrice, CurrencyUtil.mul(promotionOptional.get().getPrice(), cartSkuVO.getNum()));
} else {
cartPrice += CurrencyUtil.mul(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getNum());
cartPrice = CurrencyUtil.add(cartPrice, CurrencyUtil.mul(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getNum()));
}
}
//如果购物车金额大于消费门槛则使用
if (memberCoupon.getConsumeThreshold() <= cartPrice) {
tradeDTO.setPlatformCoupon(new MemberCouponDTO(memberCoupon));
//选择平台优惠券则将品台优惠券清空
tradeDTO.setStoreCoupons(new HashMap<>());
}
} else {
}
//否则为店铺优惠券
else {
//过滤对应店铺购物车
CartSkuVO cartVO = tradeDTO.getSkuList().stream().filter(i -> i.getStoreId().equals(memberCoupon.getStoreId())).findFirst().orElse(null);
// 优惠券消费门槛 <= 商品购买时的成交价单品 * 购买数量
if (cartVO != null && memberCoupon.getConsumeThreshold() <= CurrencyUtil.mul(cartVO.getPurchasePrice(), cartVO.getNum())) {
tradeDTO.getStoreCoupons().put(memberCoupon.getStoreId(), new MemberCouponDTO(memberCoupon));
//选择店铺优惠券则将品台优惠券清空
tradeDTO.setPlatformCoupon(null);
}
}
@ -615,9 +590,12 @@ public class CartServiceImpl implements CartService {
*/
private boolean checkCoupon(MemberCoupon memberCoupon, TradeDTO tradeDTO) {
List<CartSkuVO> cartSkuVOS;
//如果是店铺优惠券判定的内容
if (Boolean.FALSE.equals(memberCoupon.getIsPlatform())) {
cartSkuVOS = tradeDTO.getSkuList().stream().filter(i -> i.getStoreId().equals(memberCoupon.getStoreId())).collect(Collectors.toList());
} else {
}
//否则为平台优惠券筛选商品为全部商品
else {
cartSkuVOS = tradeDTO.getSkuList();
}
@ -635,8 +613,33 @@ public class CartServiceImpl implements CartService {
return true;
}
@Autowired
public void setTradeBuilder(TradeBuilder tradeBuilder) {
this.tradeBuilder = tradeBuilder;
/**
* 校验拼团信息
*
* @param cartTypeEnum 购物车枚举
* @param cartSkuVO 购物车信息
*/
private void checkPintuan(CartTypeEnum cartTypeEnum, CartSkuVO cartSkuVO) {
//拼团活动的话需要对限购数量进行判定
if (cartTypeEnum.equals(CartTypeEnum.PINTUAN)) {
//获取拼团信息
List<PromotionGoods> currentPromotion = cartSkuVO.getPromotions().stream().filter(
promotionGoods -> (promotionGoods.getPromotionType().equals(PromotionTypeEnum.PINTUAN.name())))
.collect(Collectors.toList());
//拼团活动判定
if (currentPromotion.size() > 0) {
//写入拼团信息
cartSkuVO.setPintuanId(currentPromotion.get(0).getPromotionId());
} else {
throw new ServiceException(ResultCode.CART_PINTUAN_NOT_EXIST_ERROR);
}
Pintuan pintuan = pintuanService.getPintuanById(cartSkuVO.getPintuanId());
Integer limitNum = pintuan.getLimitNum();
if (limitNum != 0 && cartSkuVO.getNum() > limitNum) {
throw new ServiceException(ResultCode.CART_PINTUAN_LIMIT_ERROR);
}
}
}
}

View File

@ -134,35 +134,26 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
//存放自订单/订单日志
List<OrderItem> orderItems = new ArrayList<>();
List<OrderLog> orderLogs = new ArrayList<>();
//拼团判定不能参与自己创建的拼团
if (tradeDTO.getParentOrderSn() != null) {
Order parentOrder = this.getBySn(tradeDTO.getParentOrderSn());
if (parentOrder.getMemberId().equals(UserContext.getCurrentUser().getId())) {
throw new ServiceException("不能参与自己发起的拼团活动!");
}
}
//订单集合
List<OrderVO> orderVOS = new ArrayList<>();
//循环购物车商品集合
//循环购物车
tradeDTO.getCartList().forEach(item -> {
Order order = new Order(item, tradeDTO);
if (OrderTypeEnum.PINTUAN.name().equals(order.getOrderType())) {
Pintuan pintuan = pintuanService.getPintuanById(order.getPromotionId());
Integer limitNum = pintuan.getLimitNum();
if (limitNum != 0 && order.getGoodsNum() > limitNum) {
throw new ServiceException("购买数量超过拼团活动限制数量");
}
}
//构建orderVO对象
OrderVO orderVO = new OrderVO();
BeanUtil.copyProperties(order, orderVO);
//持久化DO
orders.add(order);
String message = "订单[" + item.getSn() + "]创建";
//记录日志
orderLogs.add(new OrderLog(item.getSn(), UserContext.getCurrentUser().getId(), UserContext.getCurrentUser().getRole().getRole(), UserContext.getCurrentUser().getUsername(), message));
item.getSkuList().forEach(
sku -> orderItems.add(new OrderItem(sku, item, tradeDTO))
);
//写入子订单信息
orderVO.setOrderItems(orderItems);
//orderVO 记录
orderVOS.add(orderVO);
});
tradeDTO.setOrderVO(orderVOS);