|
|
@@ -10,19 +10,18 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
-import shop.alien.entity.store.LifeCoupon;
|
|
|
-import shop.alien.entity.store.LifeGroupBuyMain;
|
|
|
-import shop.alien.entity.store.LifeUserOrder;
|
|
|
-import shop.alien.entity.store.OrderCouponMiddle;
|
|
|
-import shop.alien.mapper.LifeCouponMapper;
|
|
|
-import shop.alien.mapper.LifeGroupBuyMainMapper;
|
|
|
-import shop.alien.mapper.LifeUserOrderMapper;
|
|
|
-import shop.alien.mapper.OrderCouponMiddleMapper;
|
|
|
+import shop.alien.entity.store.*;
|
|
|
+import shop.alien.entity.store.vo.LifeUserOrderVo;
|
|
|
+import shop.alien.job.feign.AlienStoreFeign;
|
|
|
+import shop.alien.mapper.*;
|
|
|
+import shop.alien.util.common.constant.DiscountCouponEnum;
|
|
|
import shop.alien.util.common.constant.OrderStatusEnum;
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.text.ParseException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
import java.time.LocalDateTime;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
@@ -43,27 +42,33 @@ public class LifeUserOrderJob {
|
|
|
private final OrderCouponMiddleMapper orderCouponMiddleMapper;
|
|
|
private final LifeCouponMapper lifeCouponMapper;
|
|
|
private final LifeGroupBuyMainMapper lifeGroupBuyMainMapper;
|
|
|
+ private final AlienStoreFeign alienStoreFeign;
|
|
|
+ private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
|
|
|
+ private final LifeRefundOrderMapper lifeRefundOrderMapper;
|
|
|
+ private final LifeUserMapper lifeUserMapper;
|
|
|
+ private final LifeNoticeMapper lifeNoticeMapper;
|
|
|
+
|
|
|
/**
|
|
|
* 待支付订单超时处理
|
|
|
*/
|
|
|
@XxlJob("autoCancelUnpaidOrders")
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public String autoCancelUnpaidOrders(){
|
|
|
+ public String autoCancelUnpaidOrders() {
|
|
|
//1.查询待支付超时订单
|
|
|
List<LifeUserOrder> lifeUserOrders = lifeUserOrderMapper.selectList(new LambdaQueryWrapper<LifeUserOrder>()
|
|
|
.eq(LifeUserOrder::getStatus, OrderStatusEnum.WAIT_PAY.getStatus())
|
|
|
.le(LifeUserOrder::getBuyTime, LocalDateTime.now().minusMinutes(15)));
|
|
|
- if( CollectionUtils.isEmpty(lifeUserOrders) ){
|
|
|
+ if (CollectionUtils.isEmpty(lifeUserOrders)) {
|
|
|
return "无待支付超时订单";
|
|
|
}
|
|
|
//2.超时则取消订单id
|
|
|
List<String> orderIds = lifeUserOrders.stream().map(LifeUserOrder::getId).collect(Collectors.toList());
|
|
|
- lifeUserOrderMapper.update(null,new LambdaUpdateWrapper<LifeUserOrder>()
|
|
|
- .set(LifeUserOrder::getStatus,OrderStatusEnum.CANCEL.getStatus())
|
|
|
- .set(LifeUserOrder::getCancelTime,LocalDateTime.now())
|
|
|
- .set(LifeUserOrder::getCancelReason,"订单超时未支付")
|
|
|
- .set(LifeUserOrder::getFinishTime,LocalDateTime.now())
|
|
|
- .in(LifeUserOrder::getId,orderIds));
|
|
|
+ lifeUserOrderMapper.update(null, new LambdaUpdateWrapper<LifeUserOrder>()
|
|
|
+ .set(LifeUserOrder::getStatus, OrderStatusEnum.CANCEL.getStatus())
|
|
|
+ .set(LifeUserOrder::getCancelTime, LocalDateTime.now())
|
|
|
+ .set(LifeUserOrder::getCancelReason, "订单超时未支付")
|
|
|
+ .set(LifeUserOrder::getFinishTime, LocalDateTime.now())
|
|
|
+ .in(LifeUserOrder::getId, orderIds));
|
|
|
// 根据类型分组
|
|
|
Map<Integer, List<String>> collect = lifeUserOrders.stream().filter(order -> order.getCouponType() != null)
|
|
|
.collect(Collectors.groupingBy(
|
|
|
@@ -74,9 +79,9 @@ public class LifeUserOrderJob {
|
|
|
)
|
|
|
));
|
|
|
int updateNum = 0;
|
|
|
- if(collect.containsKey(0)){
|
|
|
+ if (collect.containsKey(1)) {
|
|
|
//3.1代金券订单
|
|
|
- List<String> couponOrderIds = collect.get(0);
|
|
|
+ List<String> couponOrderIds = collect.get(1);
|
|
|
QueryWrapper<OrderCouponMiddle> queryWrapper = new QueryWrapper<OrderCouponMiddle>().in("order_id", couponOrderIds)
|
|
|
.eq("status", OrderStatusEnum.WAIT_PAY.getStatus())
|
|
|
.groupBy("coupon_id") // 按coupon_id分组
|
|
|
@@ -89,9 +94,9 @@ public class LifeUserOrderJob {
|
|
|
.eq(LifeCoupon::getId, orderCouponMiddle.getCouponId()));
|
|
|
}
|
|
|
}
|
|
|
- if(collect.containsKey(1)){
|
|
|
+ if (collect.containsKey(2)) {
|
|
|
//3.2团购订单
|
|
|
- List<String> groupOrderIds = collect.get(1);
|
|
|
+ List<String> groupOrderIds = collect.get(2);
|
|
|
QueryWrapper<OrderCouponMiddle> queryWrapper = new QueryWrapper<OrderCouponMiddle>().in("order_id", groupOrderIds)
|
|
|
.eq("status", OrderStatusEnum.WAIT_PAY.getStatus())
|
|
|
.groupBy("coupon_id") // 按coupon_id分组
|
|
|
@@ -99,15 +104,15 @@ public class LifeUserOrderJob {
|
|
|
List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(queryWrapper);
|
|
|
for (OrderCouponMiddle orderCouponMiddle : orderCouponMiddles) {
|
|
|
// 恢复库存
|
|
|
- lifeGroupBuyMainMapper.update(null,new LambdaUpdateWrapper<LifeGroupBuyMain>()
|
|
|
+ lifeGroupBuyMainMapper.update(null, new LambdaUpdateWrapper<LifeGroupBuyMain>()
|
|
|
.setSql("inventory_num=inventory_num+" + orderCouponMiddle.getCount())
|
|
|
.eq(LifeGroupBuyMain::getId, orderCouponMiddle.getCouponId()));
|
|
|
}
|
|
|
}
|
|
|
// 更新券状态
|
|
|
- orderCouponMiddleMapper.update(null,new LambdaUpdateWrapper<OrderCouponMiddle>()
|
|
|
- .set(OrderCouponMiddle::getStatus,OrderStatusEnum.CANCEL.getStatus())
|
|
|
- .in(OrderCouponMiddle::getOrderId,orderIds));
|
|
|
+ orderCouponMiddleMapper.update(null, new LambdaUpdateWrapper<OrderCouponMiddle>()
|
|
|
+ .set(OrderCouponMiddle::getStatus, OrderStatusEnum.CANCEL.getStatus())
|
|
|
+ .in(OrderCouponMiddle::getOrderId, orderIds));
|
|
|
return "success";
|
|
|
}
|
|
|
|
|
|
@@ -116,17 +121,163 @@ public class LifeUserOrderJob {
|
|
|
*/
|
|
|
@XxlJob("autoUpdateOrderStatus")
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public String autoUpdateOrderStatus(){
|
|
|
+ public String autoUpdateOrderStatus() {
|
|
|
+ // 定义需要排除的订单状态集合
|
|
|
+ Set<Integer> excludeStatuses = new HashSet<>(Arrays.asList(
|
|
|
+ OrderStatusEnum.CANCEL.getStatus(),
|
|
|
+ OrderStatusEnum.WAIT_PAY.getStatus(),
|
|
|
+ OrderStatusEnum.WAIT_USE.getStatus(),
|
|
|
+ OrderStatusEnum.REFUND_FAILED.getStatus()
|
|
|
+ ));
|
|
|
// 查询所以已完成的订单id
|
|
|
- List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(new LambdaQueryWrapper<OrderCouponMiddle>()
|
|
|
- .select(OrderCouponMiddle::getOrderId)
|
|
|
- .eq(OrderCouponMiddle::getDeleteFlag, 0)
|
|
|
- .in(OrderCouponMiddle::getStatus, OrderStatusEnum.CANCEL.getStatus(), OrderStatusEnum.WAIT_PAY.getStatus(), OrderStatusEnum.WAIT_USE.getStatus(), OrderStatusEnum.REFUND_FAILED.getStatus())
|
|
|
- .groupBy(OrderCouponMiddle::getOrderId));
|
|
|
+ List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<OrderCouponMiddle>()
|
|
|
+ .select(OrderCouponMiddle::getOrderId)
|
|
|
+ .eq(OrderCouponMiddle::getDeleteFlag, 0)
|
|
|
+ .in(OrderCouponMiddle::getStatus, excludeStatuses)
|
|
|
+ .groupBy(OrderCouponMiddle::getOrderId)
|
|
|
+ );
|
|
|
// 批量更新为已完成
|
|
|
- lifeUserOrderMapper.update(null,new UpdateWrapper<LifeUserOrder>()
|
|
|
- .set("status",OrderStatusEnum.COMPLETE.getStatus())
|
|
|
- .notIn("id",orderCouponMiddles.stream().map(OrderCouponMiddle::getOrderId).collect(Collectors.toList())));
|
|
|
+ lifeUserOrderMapper.update(null, new UpdateWrapper<LifeUserOrder>()
|
|
|
+ .set("status", OrderStatusEnum.COMPLETE.getStatus())
|
|
|
+ .notIn("id", orderCouponMiddles.stream().map(OrderCouponMiddle::getOrderId).collect(Collectors.toList())));
|
|
|
return "success";
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 过期自动退
|
|
|
+ */
|
|
|
+ @XxlJob("expiredRefundTask")
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void expiredRefundTask() {
|
|
|
+ Date now = new Date();
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.setTime(now);
|
|
|
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
+ calendar.set(Calendar.MINUTE, 0);
|
|
|
+ calendar.set(Calendar.SECOND, 0);
|
|
|
+ calendar.set(Calendar.MILLISECOND, 0);
|
|
|
+ now = calendar.getTime();
|
|
|
+ LambdaUpdateWrapper<LifeUserOrder> selectWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ // 查询状态为待使用的
|
|
|
+ List<Integer> status = new ArrayList<>();
|
|
|
+ status.add(OrderStatusEnum.WAIT_USE.getStatus());
|
|
|
+ selectWrapper.in(LifeUserOrder::getStatus, status);
|
|
|
+ // 查询待使用的订单
|
|
|
+ List<LifeUserOrderVo> orderList = lifeUserOrderMapper.selectRefundList(selectWrapper);
|
|
|
+
|
|
|
+ if (!orderList.isEmpty()) {
|
|
|
+ for (LifeUserOrderVo order : orderList) {
|
|
|
+ Date payTime = order.getPayTime();
|
|
|
+ // 根据有效期类型不同 进行不同判断 1: 指定天数,2:指定时间段
|
|
|
+ String effectiveDateValue = order.getEffectiveDateValue();
|
|
|
+ calendar.setTime(payTime);
|
|
|
+ Date guoqiDate = null;
|
|
|
+ if ("0".equals(order.getEffectiveDateType())) {
|
|
|
+ // 固定天数则加
|
|
|
+ calendar.add(Calendar.DAY_OF_MONTH, Integer.valueOf(effectiveDateValue));
|
|
|
+ guoqiDate = calendar.getTime();
|
|
|
+ } else {
|
|
|
+ // 指定时间段
|
|
|
+ String goqiDate = effectiveDateValue.split(",")[1];
|
|
|
+ try {
|
|
|
+ guoqiDate = new SimpleDateFormat("yyyy-MM-dd").parse(goqiDate);
|
|
|
+ } catch (ParseException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Date endDate = order.getEndDate();
|
|
|
+ if (now.compareTo(guoqiDate) > 0 || now.compareTo(endDate) > 0) {
|
|
|
+ // 过滤出退款的券列表
|
|
|
+ List<OrderCouponMiddle> orderCouponMiddleList = order.getOrderCouponMiddleList();
|
|
|
+ List<OrderCouponMiddle> refundList = orderCouponMiddleList.stream().filter(x -> x.getStatus() == OrderStatusEnum.WAIT_USE.getStatus() || x.getStatus() == OrderStatusEnum.REFUND_FAILED.getStatus()).collect(Collectors.toList());
|
|
|
+ List<OrderCouponMiddle> refundedList = orderCouponMiddleList.stream().filter(x -> x.getStatus() == OrderStatusEnum.REFUND.getStatus()).collect(Collectors.toList());
|
|
|
+ List<Integer> collect = refundList.stream().map(x -> x.getId()).collect(Collectors.toList());
|
|
|
+ if (!refundList.isEmpty()) {
|
|
|
+ // 调用退款接口
|
|
|
+ // 统计退款金额
|
|
|
+ BigDecimal totalRefundAmount = refundList.stream().map(x -> x.getPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ // 判断本次是否是全退 执行退款
|
|
|
+ String refundResult = null;
|
|
|
+ if (refundList.size() == orderCouponMiddleList.size()) {
|
|
|
+ // 全退
|
|
|
+ refundResult = alienStoreFeign.processRefund(order.getOrderNo(), totalRefundAmount.toString(), "过期自动退");
|
|
|
+ } else {
|
|
|
+ // TODO 本次部分退款
|
|
|
+ refundResult = alienStoreFeign.processRefund(order.getOrderNo(), totalRefundAmount.toString(), "过期自动退");
|
|
|
+ }
|
|
|
+ if ("调用成功".equals(refundResult)) {
|
|
|
+ // 1.更新中间表状态
|
|
|
+ int updateNum = orderCouponMiddleMapper.update(null, new LambdaUpdateWrapper<OrderCouponMiddle>()
|
|
|
+ .set(OrderCouponMiddle::getStatus, OrderStatusEnum.REFUND.getStatus())
|
|
|
+ .in(OrderCouponMiddle::getId, collect));
|
|
|
+ if (updateNum != collect.size()) {
|
|
|
+ log.error("expiredRefundTask更新中间表状态失败");
|
|
|
+ throw new RuntimeException("expiredRefundTask更新中间表状态失败");
|
|
|
+ }
|
|
|
+ // 2.过期后更新库存
|
|
|
+ if (1 == order.getCouponType()) {
|
|
|
+ // 代金券
|
|
|
+ // 恢复库存
|
|
|
+ lifeCouponMapper.update(null, new LambdaUpdateWrapper<LifeCoupon>()
|
|
|
+ .setSql("stock_qty=stock_qty+" + updateNum)
|
|
|
+ .eq(LifeCoupon::getId, order.getCouponId()));
|
|
|
+ } else {
|
|
|
+ // 团购
|
|
|
+ lifeGroupBuyMainMapper.update(null, new LambdaUpdateWrapper<LifeGroupBuyMain>()
|
|
|
+ .setSql("inventory_num=inventory_num+" + updateNum)
|
|
|
+ .eq(LifeGroupBuyMain::getId, order.getCouponId()));
|
|
|
+ }
|
|
|
+ // 3.更新订单状态 退款+已退 = 全部券则更新总订单状态
|
|
|
+ if (refundList.size() + refundedList.size() == orderCouponMiddleList.size()) {
|
|
|
+ lifeUserOrderMapper.update(null, new LambdaUpdateWrapper<LifeUserOrder>()
|
|
|
+ .set(LifeUserOrder::getStatus, OrderStatusEnum.REFUND.getStatus())
|
|
|
+ .eq(LifeUserOrder::getId, order.getId()));
|
|
|
+ if (null != order.getQuanId()) {
|
|
|
+ // 更新优惠券状态
|
|
|
+ lifeDiscountCouponUserMapper.update(null, new LambdaUpdateWrapper<LifeDiscountCouponUser>()
|
|
|
+ .set(LifeDiscountCouponUser::getStatus, DiscountCouponEnum.WAITING_USED.getValue())
|
|
|
+ .eq(LifeDiscountCouponUser::getId, order.getQuanId()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 4.添加退款记录
|
|
|
+ LifeRefundOrder refundOrder = new LifeRefundOrder()
|
|
|
+ .setOrderId(order.getId())
|
|
|
+ .setUserId(order.getUserId())
|
|
|
+ .setOrderId(order.getId())
|
|
|
+ .setRefundCouponAmount(updateNum)
|
|
|
+ .setReason("过期自动退")
|
|
|
+ .setApplicationTime(now)
|
|
|
+ .setRefundTime(now)
|
|
|
+ .setStatus(0)
|
|
|
+ .setRefundMoney(totalRefundAmount.toString());
|
|
|
+ if (lifeRefundOrderMapper.insert(refundOrder) > 0) {
|
|
|
+ // TODO 是否发送通知
|
|
|
+ // 发送通知
|
|
|
+ LifeNotice lifeMessage = new LifeNotice();
|
|
|
+ LifeUser lifeUser = lifeUserMapper.selectById(order.getUserId());
|
|
|
+ lifeMessage.setReceiverId("user_" + lifeUser.getUserPhone());
|
|
|
+ String text = "您的编号为" + order.getOrderNo() + "的订单过期自动退款,退款金额为" + totalRefundAmount.toString() + "元";
|
|
|
+ lifeMessage.setContext(text);
|
|
|
+ lifeMessage.setSenderId("system");
|
|
|
+ lifeMessage.setIsRead(0);
|
|
|
+ lifeMessage.setNoticeType(2);
|
|
|
+ lifeNoticeMapper.insert(lifeMessage);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 更新中间表状态
|
|
|
+ // 1.更新中间表状态
|
|
|
+ int updateNum = orderCouponMiddleMapper.update(null, new LambdaUpdateWrapper<OrderCouponMiddle>()
|
|
|
+ .set(OrderCouponMiddle::getStatus, OrderStatusEnum.REFUND_FAILED.getStatus())
|
|
|
+ .in(OrderCouponMiddle::getId, collect));
|
|
|
+ log.error("自动退款失败");
|
|
|
+ throw new RuntimeException("自动退款失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+
|