|
|
@@ -1,11 +1,11 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2018-2999 骞垮窞浜氱背淇℃伅绉戞妧鏈夐檺鍏徃 All rights reserved.
|
|
|
+ * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
|
|
|
*
|
|
|
* https://www.gz-yami.com/
|
|
|
*
|
|
|
- * 鏈粡鍏佽锛屼笉鍙仛鍟嗕笟鐢ㄩ€旓紒
|
|
|
+ * 未经允许,不可做商业用途!
|
|
|
*
|
|
|
- * 鐗堟潈鎵€鏈夛紝渚垫潈蹇呯┒锛?
|
|
|
+ * 版权所有,侵权必究!
|
|
|
*/
|
|
|
|
|
|
package com.yami.shop.api.listener;
|
|
|
@@ -45,7 +45,7 @@ import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
- * 纭璁㈠崟淇℃伅鏃剁殑榛樿鎿嶄綔
|
|
|
+ * 订单提交监听器
|
|
|
*
|
|
|
* @author LGH
|
|
|
*/
|
|
|
@@ -72,7 +72,7 @@ public class SubmitOrderListener {
|
|
|
private final BasketMapper basketMapper;
|
|
|
|
|
|
/**
|
|
|
- * 璁$畻璁㈠崟閲戦
|
|
|
+ * 默认订单提交监听器
|
|
|
*/
|
|
|
@EventListener(SubmitOrderEvent.class)
|
|
|
@Order(SubmitOrderOrder.DEFAULT)
|
|
|
@@ -83,24 +83,24 @@ public class SubmitOrderListener {
|
|
|
|
|
|
ShopCartOrderMergerDto mergerOrder = event.getMergerOrder();
|
|
|
|
|
|
- // 璁㈠崟鍟嗗搧鍙傛暟
|
|
|
+ // 获取所有店铺的订单
|
|
|
List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
|
|
|
|
|
|
List<Long> basketIds = new ArrayList<>();
|
|
|
- // 鍟嗗搧skuid涓簁ey 闇€瑕佹洿鏂扮殑sku涓簐alue鐨刴ap
|
|
|
+ // 库存检查Map
|
|
|
Map<Long, Sku> skuStocksMap = new HashMap<>(16);
|
|
|
- // 鍟嗗搧productid涓簁ey 闇€瑕佹洿鏂扮殑product涓簐alue鐨刴ap
|
|
|
+ // 商品库存检查Map
|
|
|
Map<Long, Product> prodStocksMap = new HashMap<>(16);
|
|
|
|
|
|
- // 鎶婅鍗曞湴鍧€淇濆瓨鍒版暟鎹簱
|
|
|
+ // 保存收货地址
|
|
|
UserAddrOrder userAddrOrder = mapperFacade.map(mergerOrder.getUserAddr(), UserAddrOrder.class);
|
|
|
if (userAddrOrder == null) {
|
|
|
- throw new GlobalException("璇峰~鍐欐敹璐у湴鍧€");
|
|
|
+ throw new GlobalException("请填写收货地址");
|
|
|
}
|
|
|
userAddrOrder.setUserId(userId);
|
|
|
userAddrOrder.setCreateTime(now);
|
|
|
userAddrOrderService.save(userAddrOrder);
|
|
|
- //鎵€鏈夊綋鍓嶇敤鎴峰彲鐢ㄧ殑绉垎璁板綍
|
|
|
+ // 查询用户可用积分记录
|
|
|
List<PointsRecord> pointsRecords = pointsRecordMapper.selectList(new LambdaQueryWrapper<PointsRecord>()
|
|
|
.eq(PointsRecord::getUserId, userId)
|
|
|
.eq(PointsRecord::getChannelId, mergerOrder.getChannelId())
|
|
|
@@ -116,32 +116,32 @@ public class SubmitOrderListener {
|
|
|
.thenComparing(PointsRecord::getId))
|
|
|
.collect(Collectors.toList());
|
|
|
;
|
|
|
- // 灏嗚褰曟坊鍔犲埌闃熷垪涓?
|
|
|
+ // 积分记录队列
|
|
|
ArrayDeque<PointsRecord> expiryQueue = new ArrayDeque<>(pointsRecords);
|
|
|
- // 璁㈠崟鍦板潃id
|
|
|
+ // 收货地址ID
|
|
|
Long addrOrderId = userAddrOrder.getAddrOrderId();
|
|
|
|
|
|
if (CollectionUtils.isNotEmpty(shopCartOrders)) {
|
|
|
- // 姣忎釜搴楅摵鐢熸垚涓€涓鍗?
|
|
|
+ // 遍历每个店铺订单
|
|
|
for (ShopCartOrderDto shopCartOrderDto : shopCartOrders) {
|
|
|
- //鍏戞崲浜烘皯甯佹槸鍒?蹇呴』瑕佸疄鏃剁粺璁¤绠?
|
|
|
+ // 获取用户可用积分
|
|
|
Long point = pointsRecordMapper.statisticsPoint(userId, mergerOrder.getChannelId());
|
|
|
- // 浣跨敤闆姳绠楁硶鐢熸垚鐨勮鍗曞彿
|
|
|
+ // 生成订单号
|
|
|
String orderNumber = "FD" + snowflake.nextId();
|
|
|
shopCartOrderDto.setOrderNumber(orderNumber);
|
|
|
|
|
|
Long shopId = shopCartOrderDto.getShopId();
|
|
|
- // 璁㈠崟淇℃伅
|
|
|
+ // 创建订单对象
|
|
|
com.yami.shop.bean.model.Order order = new com.yami.shop.bean.model.Order();
|
|
|
order.setIsPayed(0);
|
|
|
order.setHbOrderStatus(OrderStatus.UNPAY.value());
|
|
|
order.setOrderType(OrderType.ORDINARY.value());
|
|
|
- //杩欎釜杩愯垂鏄凡缁忕畻杩囩殑浜?
|
|
|
+ // 获取订单实际金额
|
|
|
double actualTotal = shopCartOrderDto.getActualTotal();
|
|
|
- //浼佷笟鐢ㄦ埛鎵嶈繘杩欎釜鍒ゆ柇,骞朵笖璇ョ敤鎴风殑绉垎蹇呴』澶т簬0
|
|
|
+ // 判断是否使用积分支付
|
|
|
if (null != point && point > 0) {
|
|
|
order.setOrderType(OrderType.SCORE.value());
|
|
|
- // 璁$畻鍟嗗搧閲戦鍜岀Н鍒?
|
|
|
+ // 计算积分抵扣金额
|
|
|
Double mul = Arith.mul(actualTotal, 100);
|
|
|
Double vp = Double.valueOf(point);
|
|
|
if (vp >= mul) {
|
|
|
@@ -149,14 +149,14 @@ public class SubmitOrderListener {
|
|
|
order.setIsPayed(1);
|
|
|
order.setPayTime(new Date());
|
|
|
order.setHbOrderStatus(OrderStatus.CONSIGNMENT.value());
|
|
|
- //绉垎瀹屽叏瓒冲鏀粯
|
|
|
+ // 设置抵扣积分数
|
|
|
order.setOffsetPoints(Long.valueOf(String.valueOf(mul).split("\\.")[0]));
|
|
|
- actualTotal = 0.0;//鍓╀笅闇€瑕佷粯鐨勯挶
|
|
|
+ actualTotal = 0.0;//剩余需要付的钱
|
|
|
} else {
|
|
|
- //绉垎涓嶅鎶垫墸
|
|
|
+ // 积分不足,计算剩余需支付金额
|
|
|
double sub = Arith.sub(mul, vp);
|
|
|
order.setOffsetPoints(point);
|
|
|
- //鍓╀笅闇€瑕佷粯鐨勯挶
|
|
|
+ // 设置剩余需支付金额
|
|
|
actualTotal = sub / 100;
|
|
|
mergerOrder.setNextPay(Boolean.TRUE);
|
|
|
}
|
|
|
@@ -165,7 +165,7 @@ public class SubmitOrderListener {
|
|
|
}
|
|
|
double sumItemA = 0.0;
|
|
|
boolean hasXsbMemberDiscount = false;
|
|
|
- // 璁㈠崟鍟嗗搧鍚嶇О
|
|
|
+ // 拼接商品名称
|
|
|
StringBuilder orderProdName = new StringBuilder(100);
|
|
|
List<OrderItem> orderItems = new ArrayList<>();
|
|
|
List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrderDto.getShopCartItemDiscounts();
|
|
|
@@ -190,7 +190,7 @@ public class SubmitOrderListener {
|
|
|
orderItem.setRecTime(now);
|
|
|
orderItem.setCommSts(0);
|
|
|
orderItem.setBasketDate(shopCartItem.getBasketDate());
|
|
|
- //骞冲彴鐨勮ˉ璐翠紭鎯犻噾棰?
|
|
|
+ // 设置平台分摊优惠
|
|
|
orderItem.setPlatformShareReduce(shopCartItem.getPlatformShareReduce());
|
|
|
if (XSB.equalsIgnoreCase(shopCartItem.getBusinessType())) {
|
|
|
Double memberDiscountShareAmount = shopCartItem.getMemberDiscountShareAmount();
|
|
|
@@ -200,33 +200,33 @@ public class SubmitOrderListener {
|
|
|
orderItem.setMemberDiscountShareAmount(0.0);
|
|
|
}
|
|
|
Double actualItem = shopCartItem.getActualTotal();
|
|
|
- //鍚庡彴鍏呭€肩殑绉垎
|
|
|
+ // 计算积分抵扣后的实际金额
|
|
|
if (null != point && point > 0) {
|
|
|
Double useActualItem = actualItem;
|
|
|
- if (!isUseTransfee) {//姣忎釜璁㈠崟澧炲姞杩愯垂锛岄兘鍙墸涓€娆?
|
|
|
+ if (!isUseTransfee) {//每个订单增加运费,都只扣丢?
|
|
|
Double transfee = shopCartOrderDto.getTransfee();
|
|
|
useActualItem = Arith.add(useActualItem, transfee);
|
|
|
isUseTransfee = Boolean.TRUE;
|
|
|
}
|
|
|
- //鎶婇挶鎹㈢畻鎴愮Н鍒?
|
|
|
+ // 使用积分抵扣
|
|
|
actualItem = this.doGetOrderItemPoints(Arith.mul(useActualItem, 100), expiryQueue, orderNumber, userId, mergerOrder.getChannelId());
|
|
|
- //鎶婄Н鍒嗘崲绠楁垚閽?
|
|
|
+ // 判断是否需要继续支付
|
|
|
if (actualItem > 0) {
|
|
|
actualItem = Arith.div(actualItem, 100);
|
|
|
}
|
|
|
}
|
|
|
- //鐢ㄤ簬鍒ゅ畾鏄惁闇€瑕佸井淇℃敮浠?
|
|
|
+ // 累计订单商品实际金额
|
|
|
sumItemA = Arith.add(sumItemA, actualItem);
|
|
|
- // 瀹為檯璁㈠崟椤规敮浠橀噾棰?
|
|
|
- // 鏍规嵁platform鏉ヨ绠楁槸鍚︿紭鍏堟墸鍑忕Н鍒嗘姷鎵?
|
|
|
+ // 设置订单商品项
|
|
|
+
|
|
|
orderItem.setActualTotal(actualItem);
|
|
|
- // 鍒嗘憡浼樻儬閲戦
|
|
|
+ // 设置商品项实际金额
|
|
|
orderItem.setShareReduce(shopCartItem.getShareReduce());
|
|
|
orderProdName.append(orderItem.getProdName()).append(",");
|
|
|
- //鎺ㄥ箍鍛樺崱鍙?
|
|
|
+ // 设置分销卡号
|
|
|
orderItem.setDistributionCardNo(shopCartItem.getDistributionCardNo());
|
|
|
orderItem.setWeight( shopCartItem.getWeight());
|
|
|
- //浣跨敤绉垎浠锋牸
|
|
|
+ // 设置使用积分数
|
|
|
orderItem.setUseScore((int) Arith.mul(Arith.sub(shopCartItem.getActualTotal(), actualItem), 100));
|
|
|
orderItems.add(orderItem);
|
|
|
|
|
|
@@ -244,15 +244,15 @@ public class SubmitOrderListener {
|
|
|
|
|
|
order.setShopId(shopId);
|
|
|
order.setOrderNumber(orderNumber);
|
|
|
- // 璁㈠崟鍟嗗搧鍚嶇О
|
|
|
+ // 设置商品名称
|
|
|
order.setProdName(orderProdName.toString());
|
|
|
- // 鐢ㄦ埛id
|
|
|
+ // 设置用户ID
|
|
|
order.setUserId(userId);
|
|
|
- // 鍟嗗搧鎬婚
|
|
|
+ // 设置订单总金额
|
|
|
order.setTotal(shopCartOrderDto.getTotal());
|
|
|
- // 瀹為檯鎬婚
|
|
|
+ // 设置订单实际金额
|
|
|
order.setActualTotal(actualTotal);
|
|
|
- order.setNextPay(sumItemA > 0);//true鏄渶瑕佸井淇℃敮浠?
|
|
|
+ order.setNextPay(sumItemA > 0);//true是需要微信支?
|
|
|
order.setChannelId(Long.valueOf(mergerOrder.getChannelId()));
|
|
|
order.setUpdateTime(now);
|
|
|
order.setCreateTime(now);
|
|
|
@@ -276,7 +276,7 @@ public class SubmitOrderListener {
|
|
|
order.setScore(shopCartOrderDto.getUseScore());
|
|
|
order.setDvyType(mergerOrder.getDvyType());
|
|
|
event.getOrders().add(order);
|
|
|
- // 鎻掑叆璁㈠崟缁撶畻琛?
|
|
|
+ // 创建订单结算记录
|
|
|
OrderSettlement orderSettlement = new OrderSettlement();
|
|
|
orderSettlement.setUserId(userId);
|
|
|
orderSettlement.setIsClearing(0);
|
|
|
@@ -286,7 +286,7 @@ public class SubmitOrderListener {
|
|
|
orderSettlement.setPayStatus(0);
|
|
|
orderSettlement.setVersion(0);
|
|
|
orderSettlement.setPayScore(0);
|
|
|
- //濡傛灉鐢ㄤ娇鐢ㄧН鍒嗭紝缁撶畻琛ㄥ皢绉垎浠锋牸鎻掑叆
|
|
|
+ // 判断是否积分支付
|
|
|
if (mergerOrder.getIsScorePay() != null && mergerOrder.getIsScorePay() == 1) {
|
|
|
orderSettlement.setPayScore(shopCartOrderDto.getUseScore());
|
|
|
}
|
|
|
@@ -294,7 +294,7 @@ public class SubmitOrderListener {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 鍒犻櫎璐墿杞︾殑鍟嗗搧淇℃伅
|
|
|
+ // 删除购物车商品
|
|
|
if (!basketIds.isEmpty()) {
|
|
|
basketMapper.deleteShopCartItemsByBasketIds(userId, basketIds);
|
|
|
}
|
|
|
@@ -304,14 +304,14 @@ public class SubmitOrderListener {
|
|
|
private Product checkAndGetProd(Long prodId, ShopCartItemDto shopCartItem, Map<Long, Product> prodStocksMap,Long shopId) {
|
|
|
Product product = productService.getProductByProdIdAndShopId(prodId, shopId);
|
|
|
if (product == null) {
|
|
|
- throw new GlobalException("璐墿杞﹀寘鍚棤娉曡瘑鍒殑鍟嗗搧");
|
|
|
+ throw new GlobalException("购物车包含无法识别的商品");
|
|
|
}
|
|
|
|
|
|
if (product.getStatus() != 1) {
|
|
|
throw new GlobalException("Product[" + product.getProdName() + "] is unavailable");
|
|
|
}
|
|
|
|
|
|
- // 鍟嗗搧闇€瑕佹敼鍙樼殑搴撳瓨
|
|
|
+ // 检查商品库存
|
|
|
Product mapProduct = prodStocksMap.get(prodId);
|
|
|
|
|
|
if (mapProduct == null) {
|
|
|
@@ -327,9 +327,9 @@ public class SubmitOrderListener {
|
|
|
prodStocksMap.put(product.getProdId(), mapProduct);
|
|
|
}
|
|
|
|
|
|
- // -1涓烘棤闄愬簱瀛?
|
|
|
+ // 检查库存是否足够
|
|
|
if (product.getTotalStocks() != -1 && mapProduct.getTotalStocks() > product.getTotalStocks()) {
|
|
|
- throw new GlobalException("鍟嗗搧锛歔" + product.getProdName() + "]搴撳瓨涓嶈冻5");
|
|
|
+ throw new GlobalException("商品:[" + product.getProdName() + "]库存不足");
|
|
|
}
|
|
|
|
|
|
return product;
|
|
|
@@ -337,24 +337,24 @@ public class SubmitOrderListener {
|
|
|
|
|
|
@SuppressWarnings({"Duplicates"})
|
|
|
private Sku checkAndGetSku(Long skuId, ShopCartItemDto shopCartItem, Map<Long, Sku> skuStocksMap) {
|
|
|
- // 鑾峰彇sku淇℃伅
|
|
|
+ // 获取SKU信息
|
|
|
Sku sku = skuService.getSkuBySkuId(skuId);
|
|
|
if (sku == null) {
|
|
|
- throw new GlobalException("璐墿杞﹀寘鍚棤娉曡瘑鍒殑鍟嗗搧");
|
|
|
+ throw new GlobalException("购物车包含无法识别的商品");
|
|
|
}
|
|
|
|
|
|
if (sku.getStatus() != 1) {
|
|
|
throw new GlobalException("Product[" + sku.getProdName() + "] is unavailable");
|
|
|
}
|
|
|
- // -1涓烘棤闄愬簱瀛?
|
|
|
+ // 检查SKU库存
|
|
|
if (sku.getActualStocks() != -1 && shopCartItem.getProdCount() > sku.getActualStocks()) {
|
|
|
- throw new GlobalException("鍟嗗搧锛歔" + sku.getProdName() + "]搴撳瓨涓嶈冻6");
|
|
|
+ throw new GlobalException("商品:[" + sku.getProdName() + "]库存不足");
|
|
|
}
|
|
|
|
|
|
if (sku.getActualStocks() != -1) {
|
|
|
Sku mapSku = new Sku();
|
|
|
mapSku.setProdId(sku.getProdId());
|
|
|
- // 杩欓噷鐨勫簱瀛樻槸鏀瑰彉鐨勫簱瀛?
|
|
|
+ // 设置SKU库存
|
|
|
mapSku.setStocks(shopCartItem.getProdCount());
|
|
|
mapSku.setSkuId(sku.getSkuId());
|
|
|
mapSku.setProdName(sku.getProdName());
|
|
|
@@ -365,24 +365,24 @@ public class SubmitOrderListener {
|
|
|
|
|
|
@SuppressWarnings({"Duplicates"})
|
|
|
private Sku checkAndGetSku(Long skuId, Long channelId, ShopCartItemDto shopCartItem, Map<Long, Sku> skuStocksMap) {
|
|
|
- // 鑾峰彇sku淇℃伅
|
|
|
+ // 获取SKU信息(带渠道)
|
|
|
Sku sku = skuService.getSkuBySkuId(skuId, channelId, shopCartItem.getShopId());
|
|
|
if (sku == null) {
|
|
|
- throw new GlobalException("璐墿杞﹀寘鍚棤娉曡瘑鍒殑鍟嗗搧");
|
|
|
+ throw new GlobalException("购物车包含无法识别的商品");
|
|
|
}
|
|
|
|
|
|
if (sku.getStatus() != 1) {
|
|
|
throw new GlobalException("Product[" + sku.getProdName() + "] is unavailable");
|
|
|
}
|
|
|
- // -1涓烘棤闄愬簱瀛?
|
|
|
+ // 检查SKU库存(带渠道)
|
|
|
if (sku.getActualStocks() != -1 && shopCartItem.getProdCount() > sku.getActualStocks()) {
|
|
|
- throw new GlobalException("鍟嗗搧锛歔" + sku.getProdName() + "]搴撳瓨涓嶈冻7");
|
|
|
+ throw new GlobalException("商品:[" + sku.getProdName() + "]库存不足");
|
|
|
}
|
|
|
|
|
|
if (sku.getActualStocks() != -1) {
|
|
|
Sku mapSku = new Sku();
|
|
|
mapSku.setProdId(sku.getProdId());
|
|
|
- // 杩欓噷鐨勫簱瀛樻槸鏀瑰彉鐨勫簱瀛?
|
|
|
+ // 设置SKU库存(带渠道)
|
|
|
mapSku.setStocks(shopCartItem.getProdCount());
|
|
|
mapSku.setSkuId(sku.getSkuId());
|
|
|
mapSku.setProdName(sku.getProdName());
|
|
|
@@ -397,15 +397,15 @@ public class SubmitOrderListener {
|
|
|
PointsRecord pr = new PointsRecord();
|
|
|
if (pointsRecord != null) {
|
|
|
Long point = pointsRecordMapper.statisticsPoint(userId, channelId);
|
|
|
- //鍒ゅ畾鍙敤閲戦
|
|
|
+ // 获取可用积分
|
|
|
BigDecimal points = pointsRecord.getPoints() != null ? pointsRecord.getPoints() : BigDecimal.ZERO;
|
|
|
BigDecimal variablePoints = pointsRecord.getVariablePoints() != null ? pointsRecord.getVariablePoints() : BigDecimal.ZERO;
|
|
|
- //鍏呭€艰褰曚腑鍙敤鐨勮褰?
|
|
|
+ // 计算可用积分余额
|
|
|
double available = points.subtract(variablePoints).doubleValue();
|
|
|
BeanUtil.copyProperties(pointsRecord, pr);
|
|
|
if (available > actualTotal) {
|
|
|
- //閽卞凡缁忔姷鎵e畬锛屼絾鏄綋鏉$Н鍒嗚繕鏈夊墿浣欙紝鎵€浠ヤ笉瑕侀噸鏂版妸鍓╀綑鐨勬斁鍏ラ槦鍒椼€傞挶灏戠Н鍒嗗
|
|
|
- //鍓╀綑鐨勭Н鍒?
|
|
|
+ // 积分足够抵扣
|
|
|
+
|
|
|
pointsRecord.setVariablePoints(variablePoints.add(BigDecimal.valueOf(actualTotal)));
|
|
|
pr.setVariablePoints(BigDecimal.valueOf(actualTotal));
|
|
|
expiryQueue.addFirst(pointsRecord);
|
|
|
@@ -414,13 +414,13 @@ public class SubmitOrderListener {
|
|
|
actualTotal = 0.0;
|
|
|
} else if (actualTotal > available) {
|
|
|
actualTotal = Arith.sub(actualTotal, available);
|
|
|
- //鎶婂綋鍓嶇Н鍒嗗凡鎵e畬,浣嗘槸杩樻湁閽便€傞挶澶氱Н鍒嗗皯
|
|
|
+ // 积分部分抵扣
|
|
|
pointsRecord.setVariablePoints(BigDecimal.valueOf(available));
|
|
|
pr.setVariablePoints(BigDecimal.valueOf(available));
|
|
|
pr.setPointsAudit(3);
|
|
|
pointsRecord.setPointsAudit(3);
|
|
|
} else {
|
|
|
- //鎭板ソ绛変簬
|
|
|
+ // 积分刚好抵扣
|
|
|
pr.setPointsAudit(3);
|
|
|
pointsRecord.setPointsAudit(3);
|
|
|
pointsRecord.setVariablePoints(variablePoints.add(BigDecimal.valueOf(actualTotal)));
|
|
|
@@ -436,7 +436,7 @@ public class SubmitOrderListener {
|
|
|
pr.setCreationDate(new Date());
|
|
|
pointsRecordMapper.insert(pr);
|
|
|
}
|
|
|
- // 鎻掑叆鏁版嵁搴?
|
|
|
+ // 递归处理剩余金额
|
|
|
if (actualTotal > 0.0) {
|
|
|
actualTotal = this.doGetOrderItemPoints(actualTotal, expiryQueue, orderNumber, userId, channelId);
|
|
|
}
|