Quellcode durchsuchen

trade:订单评论超时时,自动评论

YunaiV vor 1 Jahr
Ursprung
Commit
53bd1b9ec1

+ 4 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java

@@ -23,6 +23,10 @@ public class LocalDateTimeUtils {
         return LocalDateTime.now().plus(duration);
     }
 
+    public static LocalDateTime minusTime(Duration duration) {
+        return LocalDateTime.now().minus(duration);
+    }
+
     public static boolean beforeNow(LocalDateTime date) {
         return date.isBefore(LocalDateTime.now());
     }

+ 1 - 0
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderOperateTypeEnum.java

@@ -18,6 +18,7 @@ public enum TradeOrderOperateTypeEnum {
     MEMBER_RECEIVE(30, "用户已收货"),
     SYSTEM_RECEIVE(31, "到期未收货,系统自动确认收货"),
     MEMBER_COMMENT(33, "用户评价"),
+    SYSTEM_COMMENT(34, "到期未评价,系统自动评价"),
     MEMBER_CANCEL(40, "取消订单"),
     SYSTEM_CANCEL(41, "到期未支付,系统自动取消订单"),
     // 42 预留:管理员取消订单

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java

@@ -173,7 +173,7 @@ public class AppTradeOrderController {
     @PostMapping("/item/create-comment")
     @Operation(summary = "创建交易订单项的评价")
     public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
-        return success(tradeOrderUpdateService.createOrderItemComment(getLoginUserId(), createReqVO));
+        return success(tradeOrderUpdateService.createOrderItemCommentByMember(getLoginUserId(), createReqVO));
     }
 
 }

+ 6 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java

@@ -38,4 +38,10 @@ public interface TradeOrderItemMapper extends BaseMapperX<TradeOrderItemDO> {
                 .eq(TradeOrderItemDO::getUserId, loginUserId));
     }
 
+    default List<TradeOrderItemDO> selectListByOrderIdAndCommentStatus(Long orderId, Boolean commentStatus) {
+        return selectList(new LambdaQueryWrapperX<TradeOrderItemDO>()
+                .eq(TradeOrderItemDO::getOrderId, orderId)
+                .eq(TradeOrderItemDO::getCommentStatus, commentStatus));
+    }
+
 }

+ 8 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java

@@ -73,4 +73,12 @@ public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
                 .lt(TradeOrderDO::getDeliveryTime, deliveryTime));
     }
 
+    default List<TradeOrderDO> selectListByStatusAndReceiveTimeLt(Integer status, LocalDateTime receive,
+                                                                  Boolean commentStatus) {
+        return selectList(new LambdaUpdateWrapper<TradeOrderDO>()
+                .eq(TradeOrderDO::getStatus, status)
+                .lt(TradeOrderDO::getReceiveTime, receive)
+                .eq(TradeOrderDO::getCommentStatus, commentStatus));
+    }
+
 }

+ 6 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java

@@ -36,4 +36,10 @@ public class TradeOrderProperties {
     @NotNull(message = "收货超时时间不能为空")
     private Duration receiveExpireTime;
 
+    /**
+     * 评论超时时间
+     */
+    @NotNull(message = "评论超时时间不能为空")
+    private Duration commentExpireTime;
+
 }

+ 28 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/order/TradeOrderAutoCommentJob.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.trade.job.order;
+
+import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
+import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 交易订单的自动评论 Job
+ *
+ * @author 芋道源码
+ */
+@Component
+@TenantJob
+public class TradeOrderAutoCommentJob implements JobHandler {
+
+    @Resource
+    private TradeOrderUpdateService tradeOrderUpdateService;
+
+    @Override
+    public String execute(String param) {
+        int count = tradeOrderUpdateService.createOrderItemCommentBySystem();
+        return String.format("评论订单 %s 个", count);
+    }
+
+}

+ 9 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java

@@ -139,12 +139,19 @@ public interface TradeOrderUpdateService {
                                         Long afterSaleId, Integer refundPrice);
 
     /**
-     * 创建订单项的评论
+     * 【会员】创建订单项的评论
      *
      * @param userId      用户编号
      * @param createReqVO 创建请求
      * @return 得到评价 id
      */
-    Long createOrderItemComment(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO);
+    Long createOrderItemCommentByMember(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO);
+
+    /**
+     * 【系统】创建订单项的评论
+     *
+     * @return 被评论的订单数
+     */
+    int createOrderItemCommentBySystem();
 
 }

+ 96 - 24
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java

@@ -77,7 +77,7 @@ import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime;
+import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.minusTime;
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
 
 /**
@@ -499,7 +499,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
     @Override
     public int receiveOrderBySystem() {
         // 1. 查询过期的待支付订单
-        LocalDateTime expireTime = addTime(tradeOrderProperties.getReceiveExpireTime());
+        LocalDateTime expireTime = minusTime(tradeOrderProperties.getReceiveExpireTime());
         List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndDeliveryTimeLt(
                 TradeOrderStatusEnum.DELIVERED.getStatus(), expireTime);
         if (CollUtil.isEmpty(orders)) {
@@ -513,7 +513,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
                 getSelf().receiveOrderBySystem(order);
                 count ++;
             } catch (Throwable e) {
-                log.error("[autoReceiveOrder][order({}) 自动收货订单异常]", order.getId(), e);
+                log.error("[receiveOrderBySystem][order({}) 自动收货订单异常]", order.getId(), e);
             }
         }
         return count;
@@ -590,7 +590,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
     @Override
     public int cancelOrderBySystem() {
         // 1. 查询过期的待支付订单
-        LocalDateTime expireTime = addTime(tradeOrderProperties.getPayExpireTime());
+        LocalDateTime expireTime = minusTime(tradeOrderProperties.getPayExpireTime());
         List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndCreateTimeLt(
                 TradeOrderStatusEnum.UNPAID.getStatus(), expireTime);
         if (CollUtil.isEmpty(orders)) {
@@ -604,7 +604,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
                 getSelf().cancelOrderBySystem(order);
                 count ++;
             } catch (Throwable e) {
-                log.error("[autoCancelOrder][order({}) 过期订单异常]", order.getId(), e);
+                log.error("[cancelOrderBySystem][order({}) 过期订单异常]", order.getId(), e);
             }
         }
         return count;
@@ -726,7 +726,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         }
         tradeOrderItemMapper.updateBatch(updateItems);
 
-
         // 6、更新支付订单
         payOrderApi.updatePayOrderPrice(order.getPayOrderId(), update.getPayPrice());
     }
@@ -835,16 +834,29 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         }
     }
 
+
+    /**
+     * 判断指定订单的所有订单项,是不是都售后成功
+     *
+     * @param id 订单编号
+     * @return 是否都售后成功
+     */
+    private boolean isAllOrderItemAfterSaleSuccess(Long id) {
+        List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
+        return orderItems.stream().allMatch(orderItem -> Objects.equals(orderItem.getAfterSaleStatus(),
+                TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()));
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_COMMENT)
-    public Long createOrderItemComment(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO) {
-        // 先通过订单项 ID,查询订单项是否存在
+    public Long createOrderItemCommentByMember(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO) {
+        // 1.1 先通过订单项 ID,查询订单项是否存在
         TradeOrderItemDO orderItem = tradeOrderItemMapper.selectByIdAndUserId(createReqVO.getOrderItemId(), userId);
         if (orderItem == null) {
             throw exception(ORDER_ITEM_NOT_FOUND);
         }
-        // 校验订单相关状态
+        // 1.2 校验订单相关状态
         TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderItem.getOrderId(), userId);
         if (order == null) {
             throw exception(ORDER_NOT_FOUND);
@@ -856,31 +868,91 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
             throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
         }
 
-        // 1. 创建评价
-        ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItem);
-        Long comment = productCommentApi.createComment(productCommentCreateReqDTO);
+        // 2. 创建评价
+        Long commentId = createOrderItemComment0(orderItem, createReqVO);
 
-        // 2. 更新订单项评价状态
-        tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE));
+        // 3. 如果订单项都评论了,则更新订单评价状态
         List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(order.getId());
         if (!anyMatch(orderItems, item -> Objects.equals(item.getCommentStatus(), Boolean.FALSE))) {
-            tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE));
-            // 增加订单日志
+            tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE)
+                    .setFinishTime(LocalDateTime.now()));
+            // 增加订单日志。注意:只有在所有订单项都评价后,才会增加
             TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus());
         }
-        return comment;
+        return commentId;
+    }
+
+    @Override
+    public int createOrderItemCommentBySystem() {
+        // 1. 查询过期的待支付订单
+        LocalDateTime expireTime = minusTime(tradeOrderProperties.getCommentExpireTime());
+        List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndReceiveTimeLt(
+                TradeOrderStatusEnum.COMPLETED.getStatus(), expireTime, false);
+        if (CollUtil.isEmpty(orders)) {
+            return 0;
+        }
+
+        // 2. 遍历执行,逐个取消
+        int count = 0;
+        for (TradeOrderDO order : orders) {
+            try {
+                getSelf().createOrderItemCommentBySystemBySystem(order);
+                count ++;
+            } catch (Throwable e) {
+                log.error("[createOrderItemCommentBySystem][order({}) 过期订单异常]", order.getId(), e);
+            }
+        }
+        return count;
     }
 
     /**
-     * 判断指定订单的所有订单项,是不是都售后成功
+     * 创建单个订单的评论
      *
-     * @param id 订单编号
-     * @return 是否都售后成功
+     * @param order 订单
      */
-    private boolean isAllOrderItemAfterSaleSuccess(Long id) {
-        List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
-        return orderItems.stream().allMatch(orderItem -> Objects.equals(orderItem.getAfterSaleStatus(),
-                TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()));
+    @Transactional(rollbackFor = Exception.class)
+    @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_COMMENT)
+    public void createOrderItemCommentBySystemBySystem(TradeOrderDO order) {
+        // 1. 查询未评论的订单项
+        List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderIdAndCommentStatus(order.getId(), Boolean.FALSE);
+        if (CollUtil.isEmpty(orderItems)) {
+            return;
+        }
+
+        // 2. 逐个评论
+        for (TradeOrderItemDO orderItem : orderItems) {
+            // 2.1 创建评价
+            AppTradeOrderItemCommentCreateReqVO commentCreateReqVO = new AppTradeOrderItemCommentCreateReqVO()
+                    .setOrderItemId(orderItem.getId()).setAnonymous(false).setContent("")
+                    .setBenefitScores(5).setDescriptionScores(5);
+            createOrderItemComment0(orderItem, commentCreateReqVO);
+
+            // 2.2 更新订单项评价状态
+            tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE));
+        }
+
+        // 3. 所有订单项都评论了,则更新订单评价状态
+        tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE)
+                .setFinishTime(LocalDateTime.now()));
+        // 增加订单日志。注意:只有在所有订单项都评价后,才会增加
+        TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus());
+    }
+
+    /**
+     * 创建订单项的评论的核心实现
+     *
+     * @param orderItem 订单项
+     * @param createReqVO 评论内容
+     * @return 评论编号
+     */
+    private Long createOrderItemComment0(TradeOrderItemDO orderItem, AppTradeOrderItemCommentCreateReqVO createReqVO) {
+        // 1. 创建评价
+        ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItem);
+        Long commentId = productCommentApi.createComment(productCommentCreateReqDTO);
+
+        // 2. 更新订单项评价状态
+        tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE));
+        return commentId;
     }
 
     // =================== 营销相关的操作 ===================

+ 1 - 0
yudao-server/src/main/resources/application.yaml

@@ -205,6 +205,7 @@ yudao:
       app-id: 1 # 商户编号
       pay-expire-time: 2h # 支付的过期时间
       receive-expire-time: 14d # 收货的过期时间
+      comment-expire-time: 7d # 评论的过期时间
     express:
       client: kd_niao
       kd-niao: