|
@@ -10,8 +10,10 @@
|
|
|
|
|
|
package com.yami.shop.api.listener;
|
|
|
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.lang.Snowflake;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.yami.shop.bean.app.dto.ShopCartItemDiscountDto;
|
|
|
import com.yami.shop.bean.app.dto.ShopCartItemDto;
|
|
|
import com.yami.shop.bean.app.dto.ShopCartOrderDto;
|
|
@@ -22,7 +24,6 @@ import com.yami.shop.bean.event.SubmitOrderEvent;
|
|
|
import com.yami.shop.bean.model.*;
|
|
|
import com.yami.shop.bean.order.SubmitOrderOrder;
|
|
|
import com.yami.shop.common.exception.GlobalException;
|
|
|
-import com.yami.shop.common.exception.YamiShopBindException;
|
|
|
import com.yami.shop.common.util.Arith;
|
|
|
import com.yami.shop.dao.*;
|
|
|
import com.yami.shop.security.api.util.SecurityUtils;
|
|
@@ -36,7 +37,10 @@ import org.springframework.context.event.EventListener;
|
|
|
import org.springframework.core.annotation.Order;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 确认订单信息时的默认操作
|
|
@@ -58,6 +62,7 @@ public class SubmitOrderListener {
|
|
|
|
|
|
private final Snowflake snowflake;
|
|
|
|
|
|
+ private final PointsRecordMapper pointsRecordMapper;
|
|
|
private final OrderItemMapper orderItemMapper;
|
|
|
|
|
|
private final SkuMapper skuMapper;
|
|
@@ -98,20 +103,57 @@ public class SubmitOrderListener {
|
|
|
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.getPlatform())
|
|
|
+ .in(PointsRecord::getPointsType, Arrays.asList(1, 3))
|
|
|
+ .in(PointsRecord::getPointsAudit, Arrays.asList(1, 2)).and(wrapper -> wrapper
|
|
|
+ .gt(PointsRecord::getExpiryDate, LocalDateTime.now())
|
|
|
+ .or()
|
|
|
+ .isNull(PointsRecord::getExpiryDate)
|
|
|
+ )).stream()
|
|
|
+ .sorted(Comparator
|
|
|
+ .comparing(PointsRecord::getExpiryDate,
|
|
|
+ Comparator.nullsLast(Comparator.naturalOrder()))
|
|
|
+ .thenComparing(PointsRecord::getId))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ ;
|
|
|
+ // 将记录添加到队列中
|
|
|
+ ArrayDeque<PointsRecord> expiryQueue = new ArrayDeque<>(pointsRecords);
|
|
|
// 订单地址id
|
|
|
Long addrOrderId = userAddrOrder.getAddrOrderId();
|
|
|
|
|
|
if (CollectionUtils.isNotEmpty(shopCartOrders)) {
|
|
|
// 每个店铺生成一个订单
|
|
|
for (ShopCartOrderDto shopCartOrderDto : shopCartOrders) {
|
|
|
- Double sumPlatformAmount = 0.0;
|
|
|
+ //兑换人民币是分,必须要实时统计计算
|
|
|
+ Integer point = pointsRecordMapper.statisticsPoint(userId, mergerOrder.getPlatform());
|
|
|
// 使用雪花算法生成的订单号
|
|
|
String orderNumber = String.valueOf(snowflake.nextId());
|
|
|
shopCartOrderDto.setOrderNumber(orderNumber);
|
|
|
|
|
|
Long shopId = shopCartOrderDto.getShopId();
|
|
|
-
|
|
|
+ // 订单信息
|
|
|
+ com.yami.shop.bean.model.Order order = new com.yami.shop.bean.model.Order();
|
|
|
+ Double actualTotal = shopCartOrderDto.getActualTotal();
|
|
|
+ //企业用户才进这个判断,并且该用户的积分必须大于0
|
|
|
+ if (1 == mergerOrder.getPlatform() && null != point && point > 0) {
|
|
|
+ // 计算商品金额和积分
|
|
|
+ Double mul = Arith.mul(actualTotal, 100);
|
|
|
+ Double vp = Double.valueOf(point);
|
|
|
+ if (vp >= mul) {
|
|
|
+ //积分完全足够支付
|
|
|
+ actualTotal = 0.0;//剩下需要付的钱
|
|
|
+ order.setOffsetPoints(Long.valueOf(String.valueOf(mul)));
|
|
|
+ } else {
|
|
|
+ //积分不够抵扣
|
|
|
+ double sub = Arith.sub(mul, vp);
|
|
|
+ //剩下需要付的钱
|
|
|
+ actualTotal = sub / 100;
|
|
|
+ order.setOffsetPoints(Long.valueOf(String.valueOf(sub)));
|
|
|
+ }
|
|
|
+ }
|
|
|
// 订单商品名称
|
|
|
StringBuilder orderProdName = new StringBuilder(100);
|
|
|
List<OrderItem> orderItems = new ArrayList<>();
|
|
@@ -138,9 +180,19 @@ public class SubmitOrderListener {
|
|
|
orderItem.setBasketDate(shopCartItem.getBasketDate());
|
|
|
//平台的补贴优惠金额
|
|
|
orderItem.setPlatformShareReduce(shopCartItem.getPlatformShareReduce());
|
|
|
+ Double actualItem = shopCartItem.getActualTotal();
|
|
|
+ //后台充值的积分
|
|
|
+ if (1 == mergerOrder.getPlatform() && null != point && point > 0) {
|
|
|
+ //把钱换算成积分
|
|
|
+ actualItem = this.doGetOrderItemPoints(Arith.mul(actualItem, 100), expiryQueue, orderNumber);
|
|
|
+ //把积分换算成钱
|
|
|
+ if (actualItem > 0) {
|
|
|
+ actualItem = Arith.div(actualItem, 100);
|
|
|
+ }
|
|
|
+ }
|
|
|
// 实际订单项支付金额
|
|
|
- //TODO wangjian 根据platform来计算是否优先扣减积分抵扣
|
|
|
- orderItem.setActualTotal(shopCartItem.getActualTotal());
|
|
|
+ // 根据platform来计算是否优先扣减积分抵扣
|
|
|
+ orderItem.setActualTotal(actualItem);
|
|
|
// 分摊优惠金额
|
|
|
orderItem.setShareReduce(shopCartItem.getShareReduce());
|
|
|
orderProdName.append(orderItem.getProdName()).append(",");
|
|
@@ -162,8 +214,6 @@ public class SubmitOrderListener {
|
|
|
orderProdName.deleteCharAt(orderProdName.length() - 1);
|
|
|
}
|
|
|
|
|
|
- // 订单信息
|
|
|
- com.yami.shop.bean.model.Order order = new com.yami.shop.bean.model.Order();
|
|
|
|
|
|
order.setShopId(shopId);
|
|
|
order.setOrderNumber(orderNumber);
|
|
@@ -174,8 +224,7 @@ public class SubmitOrderListener {
|
|
|
// 商品总额
|
|
|
order.setTotal(shopCartOrderDto.getTotal());
|
|
|
// 实际总额
|
|
|
- //TODO wangjian 根据platform来计算是否优先扣减积分抵扣
|
|
|
- order.setActualTotal(shopCartOrderDto.getActualTotal());
|
|
|
+ order.setActualTotal(actualTotal);
|
|
|
order.setStatus(OrderStatus.UNPAY.value());
|
|
|
order.setChannelId(Long.valueOf(mergerOrder.getPlatform()));
|
|
|
order.setUpdateTime(now);
|
|
@@ -217,7 +266,7 @@ public class SubmitOrderListener {
|
|
|
basketMapper.deleteShopCartItemsByBasketIds(userId, basketIds);
|
|
|
}
|
|
|
|
|
|
-//TODO wangjia 修改本地库存
|
|
|
+// 现在不用维护库存
|
|
|
// // 更新sku库存
|
|
|
// skuStocksMap.forEach((key, sku) -> {
|
|
|
//
|
|
@@ -228,7 +277,7 @@ public class SubmitOrderListener {
|
|
|
// }
|
|
|
// });
|
|
|
//
|
|
|
-//// 更新商品库存
|
|
|
+// //更新商品库存
|
|
|
// prodStocksMap.forEach((prodId, prod) -> {
|
|
|
//
|
|
|
// if (productMapper.updateStocks(prod) == 0) {
|
|
@@ -331,4 +380,36 @@ public class SubmitOrderListener {
|
|
|
}
|
|
|
|
|
|
|
|
|
+ private Double doGetOrderItemPoints(Double actualTotal, ArrayDeque<PointsRecord> expiryQueue, String orderNumber) {
|
|
|
+ PointsRecord pointsRecord = expiryQueue.poll();
|
|
|
+ //判定可用金额
|
|
|
+ BigDecimal points = pointsRecord.getPoints();
|
|
|
+ BigDecimal variablePoints = pointsRecord.getVariablePoints();
|
|
|
+ //充值记录中可用的记录
|
|
|
+ Double available = points.subtract(variablePoints).doubleValue();
|
|
|
+ actualTotal = Arith.sub(actualTotal, available);
|
|
|
+ pointsRecord.setVariablePoints(BigDecimal.valueOf(available));
|
|
|
+ if (available > actualTotal) {
|
|
|
+ //钱已经抵扣完,但是当条积分还有剩余,所以不要重新把剩余的放入队列
|
|
|
+ //更改pointsRecord的变动的值,并修改数据库
|
|
|
+ expiryQueue.addFirst(pointsRecord);
|
|
|
+ }
|
|
|
+ int update = pointsRecordMapper.updateById(pointsRecord);
|
|
|
+ if (update > 0) {
|
|
|
+ PointsRecord pr = new PointsRecord();
|
|
|
+ BeanUtil.copyProperties(pointsRecord, pr);
|
|
|
+ pr.setId(null);
|
|
|
+ pr.setOrderNumber(orderNumber);
|
|
|
+ }
|
|
|
+ // TODO 插入数据库
|
|
|
+ if (actualTotal > available) {
|
|
|
+ //把当前积分已完全够扣,但是还有钱
|
|
|
+ actualTotal = this.doGetOrderItemPoints(actualTotal, expiryQueue, orderNumber);
|
|
|
+ } else {
|
|
|
+ //恰好积分等于钱
|
|
|
+// actualTotal = Arith.sub(actualTotal, available);
|
|
|
+ }
|
|
|
+ return actualTotal;
|
|
|
+ }
|
|
|
+
|
|
|
}
|