diff --git a/doc/api.md b/doc/api.md index f0c8320c..d4e7d47b 100644 --- a/doc/api.md +++ b/doc/api.md @@ -2787,7 +2787,7 @@ API应该存在版本控制,以保证兼容性。 请求参数 cartId: 购物车ID,如果0则是购物车商品,如果非0则是立即单一商品 - grouponRulesId: 团购活动ID,如果是团购商品则需要设置具体团购活动ID + grouponRulesId: 团购规则ID,如果是团购商品则需要设置具体团购规则ID 响应内容 diff --git a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/OrderJob.java b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/OrderJob.java index 7ea803fb..c286367c 100644 --- a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/OrderJob.java +++ b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/OrderJob.java @@ -84,55 +84,4 @@ public class OrderJob { } } } - - /** - * 团购订单拼团超期自动取消 - */ - @Scheduled(initialDelay = 5000, fixedDelay = 10 * 60 * 1000) - @Transactional(rollbackFor = Exception.class) - public void checkGrouponOrderTimeout() { - logger.info("系统开启定时任务检查团购订单是否已经拼团超期自动取消订单"); - - List grouponList = grouponService.queryJoinRecord(0); - for (LitemallGroupon groupon : grouponList) { - LitemallGrouponRules rules = rulesService.queryById(groupon.getRulesId()); - if (rulesService.isExpired(rules)) { - List subGrouponList = grouponService.queryJoinRecord(groupon.getId()); - for (LitemallGroupon subGroupon : subGrouponList) { - cancelGrouponScope(subGroupon); - } - - cancelGrouponScope(groupon); - } - } - } - - private void cancelGrouponScope(LitemallGroupon groupon) { - LitemallOrder order = orderService.findById(groupon.getOrderId()); - if (order.getOrderStatus().equals(OrderUtil.STATUS_PAY_GROUPON)) { - order.setOrderStatus(OrderUtil.STATUS_TIMEOUT_GROUPON); - order.setEndTime(LocalDateTime.now()); - - cancelOrderScope(order); - - logger.info("团购订单 ID" + order.getId() + " 已经拼团超期自动取消订单"); - } - } - - private void cancelOrderScope(LitemallOrder order) { - if (orderService.updateWithOptimisticLocker(order) == 0) { - throw new RuntimeException("更新数据已失效"); - } - - // 商品货品数量增加 - Integer orderId = order.getId(); - List orderGoodsList = orderGoodsService.queryByOid(orderId); - for (LitemallOrderGoods orderGoods : orderGoodsList) { - Integer productId = orderGoods.getProductId(); - Short number = orderGoods.getNumber(); - if (productService.addStock(productId, number) == 0) { - throw new RuntimeException("商品货品库存增加失败"); - } - } - } } diff --git a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/service/AdminOrderService.java b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/service/AdminOrderService.java index 4985b48b..e271d230 100644 --- a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/service/AdminOrderService.java +++ b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/service/AdminOrderService.java @@ -138,6 +138,7 @@ public class AdminOrderService { // 设置订单取消状态 order.setOrderStatus(OrderUtil.STATUS_REFUND_CONFIRM); + order.setEndTime(LocalDateTime.now()); if (orderService.updateWithOptimisticLocker(order) == 0) { throw new RuntimeException("更新数据已失效"); } diff --git a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/task/AdminTaskStartupRunner.java b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/task/AdminTaskStartupRunner.java new file mode 100644 index 00000000..2a033942 --- /dev/null +++ b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/task/AdminTaskStartupRunner.java @@ -0,0 +1,41 @@ +package org.linlinjava.litemall.admin.task; + +import org.linlinjava.litemall.core.task.TaskService; +import org.linlinjava.litemall.db.domain.LitemallGrouponRules; +import org.linlinjava.litemall.db.service.LitemallGrouponRulesService; +import org.linlinjava.litemall.db.util.GrouponConstant; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.List; + +@Component +public class AdminTaskStartupRunner implements ApplicationRunner { + + @Autowired + private LitemallGrouponRulesService rulesService; + @Autowired + private TaskService taskService; + + @Override + public void run(ApplicationArguments args) throws Exception { + List grouponRulesList = rulesService.queryByStatus(GrouponConstant.RULE_STATUS_ON); + for(LitemallGrouponRules grouponRules : grouponRulesList){ + LocalDateTime now = LocalDateTime.now(); + LocalDateTime expire = grouponRules.getExpireTime(); + if(expire.isBefore(now)) { + // 已经过期,则加入延迟队列 + taskService.addTask(new GrouponRuleExpiredTask(grouponRules.getId(), 0)); + } + else{ + // 还没过期,则加入延迟队列 + long delay = ChronoUnit.MILLIS.between(now, expire); + taskService.addTask(new GrouponRuleExpiredTask(grouponRules.getId(), delay)); + } + } + } +} \ No newline at end of file diff --git a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/task/GrouponRuleExpiredTask.java b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/task/GrouponRuleExpiredTask.java new file mode 100644 index 00000000..8d0f72f6 --- /dev/null +++ b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/task/GrouponRuleExpiredTask.java @@ -0,0 +1,68 @@ +package org.linlinjava.litemall.admin.task; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.linlinjava.litemall.core.task.Task; +import org.linlinjava.litemall.core.util.BeanUtil; +import org.linlinjava.litemall.db.domain.LitemallGroupon; +import org.linlinjava.litemall.db.domain.LitemallGrouponRules; +import org.linlinjava.litemall.db.domain.LitemallOrder; +import org.linlinjava.litemall.db.service.*; +import org.linlinjava.litemall.db.util.GrouponConstant; +import org.linlinjava.litemall.db.util.OrderUtil; + +import java.util.List; + +public class GrouponRuleExpiredTask extends Task { + private final Log logger = LogFactory.getLog(GrouponRuleExpiredTask.class); + private int grouponRuleId = -1; + + public GrouponRuleExpiredTask(Integer grouponRuleId, long delayInMilliseconds){ + super("GrouponRuleExpiredTask-" + grouponRuleId, delayInMilliseconds); + this.grouponRuleId = grouponRuleId; + } + + @Override + public void run() { + logger.info("系统开始处理延时任务---团购规则过期---" + this.grouponRuleId); + + LitemallOrderService orderService = BeanUtil.getBean(LitemallOrderService.class); + LitemallGrouponService grouponService = BeanUtil.getBean(LitemallGrouponService.class); + LitemallGrouponRulesService grouponRulesService = BeanUtil.getBean(LitemallGrouponRulesService.class); + + LitemallGrouponRules grouponRules = grouponRulesService.findById(grouponRuleId); + if(grouponRules == null){ + return; + } + if(!grouponRules.getStatus().equals(GrouponConstant.RULE_STATUS_ON)){ + return; + } + + // 团购活动取消 + grouponRules.setStatus(GrouponConstant.RULE_STATUS_DOWN_EXPIRE); + grouponRulesService.updateById(grouponRules); + + List grouponList = grouponService.queryByRuleId(grouponRuleId); + // 用户团购处理 + for(LitemallGroupon groupon : grouponList){ + Short status = groupon.getStatus(); + LitemallOrder order = orderService.findById(groupon.getOrderId()); + if(status.equals(GrouponConstant.STATUS_NONE)){ + groupon.setStatus(GrouponConstant.STATUS_FAIL); + grouponService.updateById(groupon); + } + else if(status.equals(GrouponConstant.STATUS_ON)){ + // 如果团购进行中 + // (1) 团购设置团购失败等待退款状态 + groupon.setStatus(GrouponConstant.STATUS_FAIL); + grouponService.updateById(groupon); + // (2) 团购订单申请退款 + if(OrderUtil.isPayStatus(order)) { + order.setOrderStatus(OrderUtil.STATUS_REFUND); + orderService.updateWithOptimisticLocker(order); + } + } + } + logger.info("系统结束处理延时任务---团购规则过期---" + this.grouponRuleId); + } +} diff --git a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/util/AdminResponseCode.java b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/util/AdminResponseCode.java index f096a295..327df024 100644 --- a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/util/AdminResponseCode.java +++ b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/util/AdminResponseCode.java @@ -20,5 +20,8 @@ public class AdminResponseCode { public static final Integer ROLE_NAME_EXIST = 640; public static final Integer ROLE_SUPER_SUPERMISSION = 641; public static final Integer ROLE_USER_EXIST = 642; + public static final Integer GROUPON_GOODS_UNKNOWN = 650; + public static final Integer GROUPON_GOODS_EXISTED = 651; + public static final Integer GROUPON_GOODS_OFFLINE = 652; } diff --git a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGrouponController.java b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGrouponController.java index 4aef604f..f3fdd5da 100644 --- a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGrouponController.java +++ b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGrouponController.java @@ -4,6 +4,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc; +import org.linlinjava.litemall.admin.task.GrouponRuleExpiredTask; +import org.linlinjava.litemall.admin.util.AdminResponseCode; +import org.linlinjava.litemall.core.task.TaskService; import org.linlinjava.litemall.core.util.ResponseUtil; import org.linlinjava.litemall.core.validator.Order; import org.linlinjava.litemall.core.validator.Sort; @@ -13,12 +16,15 @@ import org.linlinjava.litemall.db.domain.LitemallGrouponRules; import org.linlinjava.litemall.db.service.LitemallGoodsService; import org.linlinjava.litemall.db.service.LitemallGrouponRulesService; import org.linlinjava.litemall.db.service.LitemallGrouponService; +import org.linlinjava.litemall.db.util.GrouponConstant; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.math.BigDecimal; +import java.time.Duration; import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -36,6 +42,8 @@ public class AdminGrouponController { private LitemallGoodsService goodsService; @Autowired private LitemallGrouponService grouponService; + @Autowired + private TaskService taskService; @RequiresPermissions("admin:groupon:read") @RequiresPermissionsDesc(menu = {"推广管理", "团购管理"}, button = "详情") @@ -52,7 +60,7 @@ public class AdminGrouponController { try { Map recordData = new HashMap<>(); List subGrouponList = grouponService.queryJoinRecord(groupon.getId()); - LitemallGrouponRules rules = rulesService.queryById(groupon.getRulesId()); + LitemallGrouponRules rules = rulesService.findById(groupon.getRulesId()); LitemallGoods goods = goodsService.findById(rules.getGoodsId()); recordData.put("groupon", groupon); @@ -111,6 +119,14 @@ public class AdminGrouponController { return error; } + LitemallGrouponRules rules = rulesService.findById(grouponRules.getId()); + if(rules == null){ + return ResponseUtil.badArgumentValue(); + } + if(!rules.getStatus().equals(GrouponConstant.RULE_STATUS_ON)){ + return ResponseUtil.fail(AdminResponseCode.GROUPON_GOODS_OFFLINE, "团购已经下线"); + } + Integer goodsId = grouponRules.getGoodsId(); LitemallGoods goods = goodsService.findById(goodsId); if (goods == null) { @@ -139,14 +155,23 @@ public class AdminGrouponController { Integer goodsId = grouponRules.getGoodsId(); LitemallGoods goods = goodsService.findById(goodsId); if (goods == null) { - return ResponseUtil.badArgumentValue(); + return ResponseUtil.fail(AdminResponseCode.GROUPON_GOODS_UNKNOWN, "团购商品不存在"); + } + if(rulesService.countByGoodsId(goodsId) > 0){ + return ResponseUtil.fail(AdminResponseCode.GROUPON_GOODS_EXISTED, "团购商品已经存在"); } grouponRules.setGoodsName(goods.getName()); grouponRules.setPicUrl(goods.getPicUrl()); - + grouponRules.setStatus(GrouponConstant.RULE_STATUS_ON); rulesService.createRules(grouponRules); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime expire = grouponRules.getExpireTime(); + long delay = ChronoUnit.MILLIS.between(now, expire); + // 团购过期任务 + taskService.addTask(new GrouponRuleExpiredTask(grouponRules.getId(), delay)); + return ResponseUtil.ok(grouponRules); } diff --git a/litemall-admin/src/views/promotion/grouponRule.vue b/litemall-admin/src/views/promotion/grouponRule.vue index 598e4764..b285107f 100644 --- a/litemall-admin/src/views/promotion/grouponRule.vue +++ b/litemall-admin/src/views/promotion/grouponRule.vue @@ -3,7 +3,7 @@
- + 查找 添加 导出 + @click="handleDownload" + >导出
- + - + + + - + - + - + + + - +