|
@@ -45,10 +45,14 @@ import com.yami.shop.service.OrderService;
|
|
|
import com.yami.shop.service.OrderSettlementService;
|
|
|
import com.yami.shop.service.hb.IHBOrderService;
|
|
|
import com.yami.shop.utils.CullenUtils;
|
|
|
+import com.yami.shop.wx.po.RefundInfoPo;
|
|
|
+import com.yami.shop.wx.service.WxProviderService;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.cache.annotation.CacheEvict;
|
|
|
import org.springframework.cache.annotation.CachePut;
|
|
@@ -62,7 +66,9 @@ import javax.servlet.ServletOutputStream;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import javax.validation.Valid;
|
|
|
import java.io.IOException;
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.time.Instant;
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -77,7 +83,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
|
|
private final OrderMapper orderMapper;
|
|
|
|
|
|
private final SkuMapper skuMapper;
|
|
|
-
|
|
|
+ private final OrderItemMapper orderItemMapper;
|
|
|
private final OrderItemService orderItemService;
|
|
|
|
|
|
private final OrderSettlementService orderSettlementService;
|
|
@@ -88,6 +94,10 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
|
|
|
|
|
private final OrderRefundMapper orderRefundMapper;
|
|
|
|
|
|
+ private final PointsRecordMapper pointsRecordMapper;
|
|
|
+
|
|
|
+ private final WxProviderService wxProviderService;
|
|
|
+ private final OrderSettlementMapper orderSettlementMapper;
|
|
|
private Snowflake snowflake;
|
|
|
|
|
|
|
|
@@ -895,21 +905,149 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
|
|
*/
|
|
|
@Override
|
|
|
public void returnRefund(String orderNumber) {
|
|
|
- Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
|
|
|
- .eq(Order::getOrderNumber, orderNumber)
|
|
|
- .in(Order::getHbOrderStatus, List.of(OrderStatus.CONSIGNMENT.value(), OrderStatus.SUCCESS.value()))
|
|
|
+ OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>()
|
|
|
+ .eq(OrderRefund::getOrderNumber, orderNumber)
|
|
|
+ .eq(OrderRefund::getReturnMoneySts, 70)
|
|
|
);
|
|
|
- if (null != order) {
|
|
|
+ if (ObjectUtils.isNotEmpty(orderRefund)) {
|
|
|
+ Order order = orderMapper.selectById(orderRefund.getOrderId());
|
|
|
+ if (null == order) throw new GlobalException("该订单不支持退款");
|
|
|
//判定已完成的时间
|
|
|
if (Objects.equals(order.getHbOrderStatus(), OrderStatus.SUCCESS.value()) && isPaymentOver7Days(order.getPayTime())) {
|
|
|
throw new GlobalException("支付完成已经超过7天,不支持退款");
|
|
|
}
|
|
|
- //可以直接退积分或者是钱
|
|
|
- if (order.getActualTotal() > 0) {
|
|
|
- //退,微信支付
|
|
|
- } else {
|
|
|
- //退,积分
|
|
|
+ //"订单退款状态(1:申请退款 2:退款成功 3:部分退款成功 4:退款失败)"
|
|
|
+ switch (orderRefund.getRefundType()) {
|
|
|
+ case 1://1:整单退款
|
|
|
+ order.setRefundStatus(2);
|
|
|
+ if (order.getActualTotal() > 0) {
|
|
|
+ OrderSettlement orderSettlement = orderSettlementMapper.selectOne(new LambdaQueryWrapper<OrderSettlement>()
|
|
|
+ .eq(OrderSettlement::getOrderNumber, order.getOrderNumber())
|
|
|
+ .eq(OrderSettlement::getPayType, 1));
|
|
|
+ if (order.getOffsetPoints() > 0) {//混合支付
|
|
|
+ //退钱
|
|
|
+ RefundInfoPo po = new RefundInfoPo();
|
|
|
+ po.setOutTradeNo(orderSettlement.getPayNo());
|
|
|
+ po.setTotal((int) Arith.mul(Arith.add(order.getActualTotal(), order.getFreightAmount()), 100));
|
|
|
+ po.setRefundMoney((int) Arith.mul(Arith.add(order.getActualTotal(), order.getFreightAmount()), 100));
|
|
|
+ String s = wxProviderService.refundOrder(po);
|
|
|
+ System.out.println("微信退款结果:" + s);
|
|
|
+ //优先退未过期的积分,退积分
|
|
|
+ List<PointsRecord> pointsRecords = pointsRecordMapper.selectList(new LambdaQueryWrapper<PointsRecord>()
|
|
|
+ .eq(PointsRecord::getOrderNumber, order.getOrderNumber()).eq(PointsRecord::getPointsType, 2)
|
|
|
+ .and(wrapper -> wrapper
|
|
|
+ .gt(PointsRecord::getExpiryDate, LocalDateTime.now())
|
|
|
+ .or()
|
|
|
+ .isNull(PointsRecord::getExpiryDate)
|
|
|
+ ).orderByDesc(PointsRecord::getExpiryDate));
|
|
|
+ for (PointsRecord pointsRecord : pointsRecords) {
|
|
|
+ PointsRecord npr = new PointsRecord();
|
|
|
+ BeanUtils.copyProperties(pointsRecord, npr);
|
|
|
+ npr.setId(null);
|
|
|
+ npr.setPointsType(3);
|
|
|
+ npr.setPoints(pointsRecord.getVariablePoints());
|
|
|
+ npr.setVariablePoints(BigDecimal.valueOf(0));
|
|
|
+ Long l = pointsRecordMapper.statisticsPoint(pointsRecord.getUserId(), Math.toIntExact(pointsRecord.getChannelId()));
|
|
|
+ npr.setCurrentlyAvailablePoints(pointsRecord.getVariablePoints().add(BigDecimal.valueOf(l)));
|
|
|
+ npr.setCreationDate(new Date());
|
|
|
+ pointsRecordMapper.insert(npr);
|
|
|
+ }
|
|
|
+ } else {//仅微信支付
|
|
|
+ RefundInfoPo po = new RefundInfoPo();
|
|
|
+ po.setOutTradeNo(orderSettlement.getPayNo());
|
|
|
+ po.setTotal((int) Arith.mul(Arith.add(order.getTotal(), order.getFreightAmount()), 100));
|
|
|
+ po.setRefundMoney((int) Arith.mul(Arith.add(order.getTotal(), order.getFreightAmount()), 100));
|
|
|
+ String s = wxProviderService.refundOrder(po);
|
|
|
+ System.out.println("微信退款结果:" + s);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //退,积分【优先退未过期的积分】
|
|
|
+ List<PointsRecord> pointsRecords = pointsRecordMapper.selectList(new LambdaQueryWrapper<PointsRecord>()
|
|
|
+ .eq(PointsRecord::getOrderNumber, order.getOrderNumber()).eq(PointsRecord::getPointsType, 2)
|
|
|
+ .and(wrapper -> wrapper
|
|
|
+ .gt(PointsRecord::getExpiryDate, LocalDateTime.now())
|
|
|
+ .or()
|
|
|
+ .isNull(PointsRecord::getExpiryDate)
|
|
|
+ ).orderByDesc(PointsRecord::getExpiryDate));
|
|
|
+ for (PointsRecord pointsRecord : pointsRecords) {
|
|
|
+ PointsRecord npr = new PointsRecord();
|
|
|
+ BeanUtils.copyProperties(pointsRecord, npr);
|
|
|
+ npr.setId(null);
|
|
|
+ npr.setPointsType(3);
|
|
|
+ npr.setPoints(pointsRecord.getVariablePoints());
|
|
|
+ npr.setVariablePoints(BigDecimal.valueOf(0));
|
|
|
+ Long l = pointsRecordMapper.statisticsPoint(pointsRecord.getUserId(), Math.toIntExact(pointsRecord.getChannelId()));
|
|
|
+ npr.setCurrentlyAvailablePoints(pointsRecord.getVariablePoints().add(BigDecimal.valueOf(l)));
|
|
|
+ npr.setCreationDate(new Date());
|
|
|
+ pointsRecordMapper.insert(npr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 2://2:单个物品退款
|
|
|
+ order.setRefundStatus(3);
|
|
|
+ List<OrderRefundSku> orderRefundSkus = orderRefundSkuMapper.selectList(new LambdaQueryWrapper<OrderRefundSku>()
|
|
|
+ .eq(OrderRefundSku::getOrderRefundId, orderRefund.getRefundId()));
|
|
|
+ List<PointsRecord> pointsRecords = pointsRecordMapper.selectList(new LambdaQueryWrapper<PointsRecord>()
|
|
|
+ .eq(PointsRecord::getOrderNumber, order.getOrderNumber()).eq(PointsRecord::getPointsType, 2).and(wrapper -> wrapper
|
|
|
+ .gt(PointsRecord::getExpiryDate, LocalDateTime.now())
|
|
|
+ .or()
|
|
|
+ .isNull(PointsRecord::getExpiryDate)
|
|
|
+ ).orderByDesc(PointsRecord::getExpiryDate));
|
|
|
+ int totalRefundScore = 0;//需要退的总积分
|
|
|
+ double totalRefundActual = 0.0;//需要退的总金额
|
|
|
+ for (OrderRefundSku refundSkus : orderRefundSkus) {
|
|
|
+ Integer productCount = refundSkus.getProductCount();//退款的数量
|
|
|
+ OrderItem orderItem = orderItemMapper.selectById(refundSkus.getOrderItemId());
|
|
|
+ Double actualTotal = orderItem.getActualTotal();//付的钱
|
|
|
+ Integer useScore = orderItem.getUseScore();//使用的总积分
|
|
|
+ if (useScore > 0) {
|
|
|
+ //退的积分不一定等于下单的数量
|
|
|
+ totalRefundScore = (int) (totalRefundScore + Arith.mul(productCount * orderItem.getPrice(), 100));
|
|
|
+ }
|
|
|
+ if (actualTotal > 0) {
|
|
|
+ totalRefundActual = Arith.add(totalRefundActual, productCount * orderItem.getPrice());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //退积分
|
|
|
+ if (totalRefundScore > 0) {
|
|
|
+ for (PointsRecord pointsRecord : pointsRecords) {
|
|
|
+ //下单支付的金额
|
|
|
+ int variablePoints = pointsRecord.getVariablePoints().intValue();
|
|
|
+ PointsRecord npr = new PointsRecord();
|
|
|
+ BeanUtils.copyProperties(pointsRecord, npr);
|
|
|
+ npr.setId(null);
|
|
|
+ npr.setPointsType(3);
|
|
|
+ Long l = pointsRecordMapper.statisticsPoint(pointsRecord.getUserId(), Math.toIntExact(pointsRecord.getChannelId()));
|
|
|
+ npr.setCurrentlyAvailablePoints(pointsRecord.getVariablePoints().add(BigDecimal.valueOf(l)));
|
|
|
+ npr.setCreationDate(new Date());
|
|
|
+ if (variablePoints < totalRefundScore) {//下单金额全退
|
|
|
+ npr.setPoints(pointsRecord.getVariablePoints());
|
|
|
+ npr.setVariablePoints(BigDecimal.valueOf(0));
|
|
|
+ totalRefundScore -= variablePoints;
|
|
|
+ } else {
|
|
|
+ npr.setPoints(pointsRecord.getVariablePoints().subtract(BigDecimal.valueOf(totalRefundScore)));
|
|
|
+ npr.setVariablePoints(BigDecimal.valueOf(0));
|
|
|
+ }
|
|
|
+ pointsRecordMapper.insert(npr);
|
|
|
+ if (variablePoints >= totalRefundScore) return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //退钱
|
|
|
+ if (totalRefundActual > 0) {
|
|
|
+ OrderSettlement orderSettlement = orderSettlementMapper.selectOne(new LambdaQueryWrapper<OrderSettlement>()
|
|
|
+ .eq(OrderSettlement::getOrderNumber, order.getOrderNumber())
|
|
|
+ .eq(OrderSettlement::getPayType, 1));
|
|
|
+ RefundInfoPo po = new RefundInfoPo();
|
|
|
+ po.setOutTradeNo(orderSettlement.getPayNo());
|
|
|
+ po.setTotal((int) Arith.mul(Arith.add(order.getTotal(), order.getFreightAmount()), 100));
|
|
|
+ po.setRefundMoney((int) Arith.mul(totalRefundActual, 100));
|
|
|
+ String s = wxProviderService.refundOrder(po);
|
|
|
+ System.out.println("微信退款结果:" + s);
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
+
|
|
|
+ orderMapper.updateById(order);
|
|
|
}
|
|
|
}
|
|
|
|