diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java index 85aa713b..16711aa1 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java @@ -4,6 +4,7 @@ import com.github.pagehelper.PageHelper; import org.linlinjava.litemall.db.dao.LitemallOrderMapper; import org.linlinjava.litemall.db.domain.LitemallOrder; import org.linlinjava.litemall.db.domain.LitemallOrderExample; +import org.linlinjava.litemall.db.util.OrderUtil; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @@ -147,4 +148,16 @@ public class LitemallOrderService { example.or().andDeletedEqualTo(false); return (int)orderMapper.countByExample(example); } + + public List queryUnpaid() { + LitemallOrderExample example = new LitemallOrderExample(); + example.or().andOrderStatusEqualTo(OrderUtil.STATUS_CREATE).andDeletedEqualTo(false); + return orderMapper.selectByExample(example); + } + + public List queryUnconfirm() { + LitemallOrderExample example = new LitemallOrderExample(); + example.or().andOrderStatusEqualTo(OrderUtil.STATUS_SHIP).andShipEndTimeIsNotNull().andDeletedEqualTo(false); + return orderMapper.selectByExample(example); + } } diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/Application.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/Application.java index 9a536666..f079f22f 100644 --- a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/Application.java +++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/Application.java @@ -3,11 +3,13 @@ package org.linlinjava.litemall.wx; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication(scanBasePackages={"org.linlinjava.litemall.core", "org.linlinjava.litemall.wx","org.linlinjava.litemall.db"}) @MapperScan("org.linlinjava.litemall.db.dao") @EnableTransactionManagement +@EnableScheduling public class Application { public static void main(String[] args) { diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java index f4ddc7fe..6423b520 100644 --- a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java +++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java @@ -10,6 +10,7 @@ import org.linlinjava.litemall.core.util.JacksonUtil; import org.linlinjava.litemall.core.util.ResponseUtil; import org.linlinjava.litemall.wx.annotation.LoginUser; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; @@ -401,6 +402,7 @@ public class WxOrderController { try { // 设置订单已取消状态 order.setOrderStatus(OrderUtil.STATUS_CANCEL); + order.setEndTime(LocalDateTime.now()); orderService.update(order); // 商品货品数量增加 @@ -508,7 +510,7 @@ public class WxOrderController { if (!order.getOrderStatus().equals(OrderUtil.STATUS_PAY)) { logger.error("系统内部错误"); } - if (!order.getPayId().equals(payId)) { + if (!order.getPayId().equals(String.valueOf(payId))) { logger.error("系统内部错误"); } @@ -669,49 +671,6 @@ public class WxOrderController { order.setOrderStatus(OrderUtil.STATUS_CONFIRM); order.setConfirmTime(LocalDateTime.now()); orderService.update(order); - - return ResponseUtil.ok(); - } - - - /** - * 自动确认收货 - * 1. 检测当前订单是否能够自动确认订单 - * 2. 设置订单自动确认状态 - * - * @param userId 用户ID - * @param body 订单信息,{ orderId:xxx } - * @return 订单操作结果 - * 成功则 { errno: 0, errmsg: '成功' } - * 失败则 { errno: XXX, errmsg: XXX } - */ - @PostMapping("autoconfirm") - public Object autoconfirm(@LoginUser Integer userId, @RequestBody String body) { - if (userId == null) { - return ResponseUtil.unlogin(); - } - Integer orderId = JacksonUtil.parseInteger(body, "orderId"); - if (orderId == null) { - return ResponseUtil.badArgument(); - } - - LitemallOrder order = orderService.findById(orderId); - if (order == null) { - return ResponseUtil.badArgument(); - } - if (!order.getUserId().equals(userId)) { - return ResponseUtil.badArgumentValue(); - } - - OrderHandleOption handleOption = OrderUtil.build(order); - if (!handleOption.isConfirm()) { - return ResponseUtil.fail(403, "订单不能确认收货"); - } - - order.setOrderStatus(OrderUtil.STATUS_AUTO_CONFIRM); - order.setConfirmTime(LocalDateTime.now()); - orderService.update(order); - return ResponseUtil.ok(); } @@ -787,4 +746,92 @@ public class WxOrderController { LitemallOrderGoods orderGoods = orderGoodsList.get(0); return ResponseUtil.ok(orderGoods); } + + /** + * 自动取消订单 + * + * 定时检查订单未付款情况,如果超时半个小时则自动取消订单 + * 定时时间是每次相隔半个小时。 + * + * 注意,因为是相隔半小时检查,因此导致有订单是超时一个小时以后才设置取消状态。 + * TODO + * 这里可以进一步地配合用户订单查询时订单未付款检查,如果订单超时半小时则取消。 + */ + @Scheduled(fixedDelay = 30*60*1000) + public void checkOrderUnpaid() { + logger.debug(LocalDateTime.now()); + + List orderList = orderService.queryUnpaid(); + for(LitemallOrder order : orderList){ + LocalDateTime add = order.getAddTime(); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime expired = add.plusMinutes(30); + if(expired.isAfter(now)){ + continue; + } + + // 开启事务管理 + DefaultTransactionDefinition def = new DefaultTransactionDefinition(); + def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); + TransactionStatus status = txManager.getTransaction(def); + try { + // 设置订单已取消状态 + order.setOrderStatus(OrderUtil.STATUS_CANCEL); + order.setEndTime(LocalDateTime.now()); + orderService.updateById(order); + + // 商品货品数量增加 + Integer orderId = order.getId(); + List orderGoodsList = orderGoodsService.queryByOid(orderId); + for (LitemallOrderGoods orderGoods : orderGoodsList) { + Integer productId = orderGoods.getProductId(); + LitemallProduct product = productService.findById(productId); + Integer number = product.getGoodsNumber() + orderGoods.getNumber(); + product.setGoodsNumber(number); + productService.updateById(product); + } + } catch (Exception ex) { + txManager.rollback(status); + logger.error("系统内部错误", ex); + } + txManager.commit(status); + } + } + + /** + * 自动确认订单 + * + * 定时检查订单未确认情况,如果超时七天则自动确认订单 + * 定时时间是每天凌晨3点。 + * + * 注意,因为是相隔一天检查,因此导致有订单是超时八天以后才设置自动确认。 + * 这里可以进一步地配合用户订单查询时订单未确认检查,如果订单超时7天则自动确认。 + * 但是,这里可能不是非常必要。相比订单未付款检查中存在商品资源有限所以应该 + * 早点清理未付款情况,这里八天再确认是可以的。 + * + * TODO + * 目前自动确认是基于管理后台管理员所设置的商品快递到达时间,见orderService.queryUnconfirm。 + * 那么在实际业务上有可能存在商品寄出以后商品因为一些原因快递最终没有到达, + * 也就是商品快递失败而shipEndTime一直是空的情况,因此这里业务可能需要扩展,以防止订单一直 + * 处于发货状态。 + */ + @Scheduled(cron = "0 0 3 * * ?") + public void checkOrderUnconfirm() { + logger.debug(LocalDateTime.now()); + + List orderList = orderService.queryUnconfirm(); + for(LitemallOrder order : orderList){ + LocalDateTime shipEnd = order.getShipEndTime(); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime expired = shipEnd.plusDays(7); + if(expired.isAfter(now)){ + continue; + } + // 设置订单已取消状态 + order.setOrderStatus(OrderUtil.STATUS_AUTO_CONFIRM); + order.setConfirmTime(now); + orderService.updateById(order); + } + } + } \ No newline at end of file