Commit be426235dd447e2f13dbc9a255c598cc516ed5df

Authored by owen
2 parents bc07e1db 53bd1b9e

Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product

yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
@@ -23,6 +23,10 @@ public class LocalDateTimeUtils { @@ -23,6 +23,10 @@ public class LocalDateTimeUtils {
23 return LocalDateTime.now().plus(duration); 23 return LocalDateTime.now().plus(duration);
24 } 24 }
25 25
  26 + public static LocalDateTime minusTime(Duration duration) {
  27 + return LocalDateTime.now().minus(duration);
  28 + }
  29 +
26 public static boolean beforeNow(LocalDateTime date) { 30 public static boolean beforeNow(LocalDateTime date) {
27 return date.isBefore(LocalDateTime.now()); 31 return date.isBefore(LocalDateTime.now());
28 } 32 }
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 { @@ -18,6 +18,7 @@ public enum TradeOrderOperateTypeEnum {
18 MEMBER_RECEIVE(30, "用户已收货"), 18 MEMBER_RECEIVE(30, "用户已收货"),
19 SYSTEM_RECEIVE(31, "到期未收货,系统自动确认收货"), 19 SYSTEM_RECEIVE(31, "到期未收货,系统自动确认收货"),
20 MEMBER_COMMENT(33, "用户评价"), 20 MEMBER_COMMENT(33, "用户评价"),
  21 + SYSTEM_COMMENT(34, "到期未评价,系统自动评价"),
21 MEMBER_CANCEL(40, "取消订单"), 22 MEMBER_CANCEL(40, "取消订单"),
22 SYSTEM_CANCEL(41, "到期未支付,系统自动取消订单"), 23 SYSTEM_CANCEL(41, "到期未支付,系统自动取消订单"),
23 // 42 预留:管理员取消订单 24 // 42 预留:管理员取消订单
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 { @@ -173,7 +173,7 @@ public class AppTradeOrderController {
173 @PostMapping("/item/create-comment") 173 @PostMapping("/item/create-comment")
174 @Operation(summary = "创建交易订单项的评价") 174 @Operation(summary = "创建交易订单项的评价")
175 public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) { 175 public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
176 - return success(tradeOrderUpdateService.createOrderItemComment(getLoginUserId(), createReqVO)); 176 + return success(tradeOrderUpdateService.createOrderItemCommentByMember(getLoginUserId(), createReqVO));
177 } 177 }
178 178
179 } 179 }
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&lt;TradeOrderItemDO&gt; { @@ -38,4 +38,10 @@ public interface TradeOrderItemMapper extends BaseMapperX&lt;TradeOrderItemDO&gt; {
38 .eq(TradeOrderItemDO::getUserId, loginUserId)); 38 .eq(TradeOrderItemDO::getUserId, loginUserId));
39 } 39 }
40 40
  41 + default List<TradeOrderItemDO> selectListByOrderIdAndCommentStatus(Long orderId, Boolean commentStatus) {
  42 + return selectList(new LambdaQueryWrapperX<TradeOrderItemDO>()
  43 + .eq(TradeOrderItemDO::getOrderId, orderId)
  44 + .eq(TradeOrderItemDO::getCommentStatus, commentStatus));
  45 + }
  46 +
41 } 47 }
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&lt;TradeOrderDO&gt; { @@ -73,4 +73,12 @@ public interface TradeOrderMapper extends BaseMapperX&lt;TradeOrderDO&gt; {
73 .lt(TradeOrderDO::getDeliveryTime, deliveryTime)); 73 .lt(TradeOrderDO::getDeliveryTime, deliveryTime));
74 } 74 }
75 75
  76 + default List<TradeOrderDO> selectListByStatusAndReceiveTimeLt(Integer status, LocalDateTime receive,
  77 + Boolean commentStatus) {
  78 + return selectList(new LambdaUpdateWrapper<TradeOrderDO>()
  79 + .eq(TradeOrderDO::getStatus, status)
  80 + .lt(TradeOrderDO::getReceiveTime, receive)
  81 + .eq(TradeOrderDO::getCommentStatus, commentStatus));
  82 + }
  83 +
76 } 84 }
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 { @@ -36,4 +36,10 @@ public class TradeOrderProperties {
36 @NotNull(message = "收货超时时间不能为空") 36 @NotNull(message = "收货超时时间不能为空")
37 private Duration receiveExpireTime; 37 private Duration receiveExpireTime;
38 38
  39 + /**
  40 + * 评论超时时间
  41 + */
  42 + @NotNull(message = "评论超时时间不能为空")
  43 + private Duration commentExpireTime;
  44 +
39 } 45 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/order/TradeOrderAutoCommentJob.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.job.order;
  2 +
  3 +import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
  4 +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
  5 +import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +import javax.annotation.Resource;
  9 +
  10 +/**
  11 + * 交易订单的自动评论 Job
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Component
  16 +@TenantJob
  17 +public class TradeOrderAutoCommentJob implements JobHandler {
  18 +
  19 + @Resource
  20 + private TradeOrderUpdateService tradeOrderUpdateService;
  21 +
  22 + @Override
  23 + public String execute(String param) {
  24 + int count = tradeOrderUpdateService.createOrderItemCommentBySystem();
  25 + return String.format("评论订单 %s 个", count);
  26 + }
  27 +
  28 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java
@@ -142,12 +142,19 @@ public interface TradeOrderUpdateService { @@ -142,12 +142,19 @@ public interface TradeOrderUpdateService {
142 void updateOrderItemWhenAfterSaleCancel(@NotNull Long id); 142 void updateOrderItemWhenAfterSaleCancel(@NotNull Long id);
143 143
144 /** 144 /**
145 - * 创建订单项的评论 145 + * 【会员】创建订单项的评论
146 * 146 *
147 * @param userId 用户编号 147 * @param userId 用户编号
148 * @param createReqVO 创建请求 148 * @param createReqVO 创建请求
149 * @return 得到评价 id 149 * @return 得到评价 id
150 */ 150 */
151 - Long createOrderItemComment(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO); 151 + Long createOrderItemCommentByMember(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO);
  152 +
  153 + /**
  154 + * 【系统】创建订单项的评论
  155 + *
  156 + * @return 被评论的订单数
  157 + */
  158 + int createOrderItemCommentBySystem();
152 159
153 } 160 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
@@ -74,7 +74,7 @@ import java.util.*; @@ -74,7 +74,7 @@ import java.util.*;
74 74
75 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 75 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
76 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 76 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
77 -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; 77 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.minusTime;
78 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; 78 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
79 79
80 /** 80 /**
@@ -496,7 +496,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -496,7 +496,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
496 @Override 496 @Override
497 public int receiveOrderBySystem() { 497 public int receiveOrderBySystem() {
498 // 1. 查询过期的待支付订单 498 // 1. 查询过期的待支付订单
499 - LocalDateTime expireTime = addTime(tradeOrderProperties.getReceiveExpireTime()); 499 + LocalDateTime expireTime = minusTime(tradeOrderProperties.getReceiveExpireTime());
500 List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndDeliveryTimeLt( 500 List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndDeliveryTimeLt(
501 TradeOrderStatusEnum.DELIVERED.getStatus(), expireTime); 501 TradeOrderStatusEnum.DELIVERED.getStatus(), expireTime);
502 if (CollUtil.isEmpty(orders)) { 502 if (CollUtil.isEmpty(orders)) {
@@ -510,7 +510,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -510,7 +510,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
510 getSelf().receiveOrderBySystem(order); 510 getSelf().receiveOrderBySystem(order);
511 count++; 511 count++;
512 } catch (Throwable e) { 512 } catch (Throwable e) {
513 - log.error("[autoReceiveOrder][order({}) 自动收货订单异常]", order.getId(), e); 513 + log.error("[receiveOrderBySystem][order({}) 自动收货订单异常]", order.getId(), e);
514 } 514 }
515 } 515 }
516 return count; 516 return count;
@@ -587,7 +587,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -587,7 +587,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
587 @Override 587 @Override
588 public int cancelOrderBySystem() { 588 public int cancelOrderBySystem() {
589 // 1. 查询过期的待支付订单 589 // 1. 查询过期的待支付订单
590 - LocalDateTime expireTime = addTime(tradeOrderProperties.getPayExpireTime()); 590 + LocalDateTime expireTime = minusTime(tradeOrderProperties.getPayExpireTime());
591 List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndCreateTimeLt( 591 List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndCreateTimeLt(
592 TradeOrderStatusEnum.UNPAID.getStatus(), expireTime); 592 TradeOrderStatusEnum.UNPAID.getStatus(), expireTime);
593 if (CollUtil.isEmpty(orders)) { 593 if (CollUtil.isEmpty(orders)) {
@@ -601,7 +601,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -601,7 +601,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
601 getSelf().cancelOrderBySystem(order); 601 getSelf().cancelOrderBySystem(order);
602 count++; 602 count++;
603 } catch (Throwable e) { 603 } catch (Throwable e) {
604 - log.error("[autoCancelOrder][order({}) 过期订单异常]", order.getId(), e); 604 + log.error("[cancelOrderBySystem][order({}) 过期订单异常]", order.getId(), e);
605 } 605 }
606 } 606 }
607 return count; 607 return count;
@@ -723,7 +723,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -723,7 +723,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
723 } 723 }
724 tradeOrderItemMapper.updateBatch(updateItems); 724 tradeOrderItemMapper.updateBatch(updateItems);
725 725
726 -  
727 // 6、更新支付订单 726 // 6、更新支付订单
728 payOrderApi.updatePayOrderPrice(order.getPayOrderId(), update.getPayPrice()); 727 payOrderApi.updatePayOrderPrice(order.getPayOrderId(), update.getPayPrice());
729 } 728 }
@@ -845,16 +844,29 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -845,16 +844,29 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
845 couponApi.returnUsedCoupon(order.getCouponId()); 844 couponApi.returnUsedCoupon(order.getCouponId());
846 } 845 }
847 846
  847 +
  848 + /**
  849 + * 判断指定订单的所有订单项,是不是都售后成功
  850 + *
  851 + * @param id 订单编号
  852 + * @return 是否都售后成功
  853 + */
  854 + private boolean isAllOrderItemAfterSaleSuccess(Long id) {
  855 + List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
  856 + return orderItems.stream().allMatch(orderItem -> Objects.equals(orderItem.getAfterSaleStatus(),
  857 + TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()));
  858 + }
  859 +
848 @Override 860 @Override
849 @Transactional(rollbackFor = Exception.class) 861 @Transactional(rollbackFor = Exception.class)
850 @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_COMMENT) 862 @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_COMMENT)
851 - public Long createOrderItemComment(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO) {  
852 - // 先通过订单项 ID,查询订单项是否存在 863 + public Long createOrderItemCommentByMember(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO) {
  864 + // 1.1 先通过订单项 ID,查询订单项是否存在
853 TradeOrderItemDO orderItem = tradeOrderItemMapper.selectByIdAndUserId(createReqVO.getOrderItemId(), userId); 865 TradeOrderItemDO orderItem = tradeOrderItemMapper.selectByIdAndUserId(createReqVO.getOrderItemId(), userId);
854 if (orderItem == null) { 866 if (orderItem == null) {
855 throw exception(ORDER_ITEM_NOT_FOUND); 867 throw exception(ORDER_ITEM_NOT_FOUND);
856 } 868 }
857 - // 校验订单相关状态 869 + // 1.2 校验订单相关状态
858 TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderItem.getOrderId(), userId); 870 TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderItem.getOrderId(), userId);
859 if (order == null) { 871 if (order == null) {
860 throw exception(ORDER_NOT_FOUND); 872 throw exception(ORDER_NOT_FOUND);
@@ -866,31 +878,91 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -866,31 +878,91 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
866 throw exception(ORDER_COMMENT_STATUS_NOT_FALSE); 878 throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
867 } 879 }
868 880
869 - // 1. 创建评价  
870 - ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItem);  
871 - Long comment = productCommentApi.createComment(productCommentCreateReqDTO); 881 + // 2. 创建评价
  882 + Long commentId = createOrderItemComment0(orderItem, createReqVO);
872 883
873 - // 2. 更新订单项评价状态  
874 - tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE)); 884 + // 3. 如果订单项都评论了,则更新订单评价状态
875 List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(order.getId()); 885 List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(order.getId());
876 if (!anyMatch(orderItems, item -> Objects.equals(item.getCommentStatus(), Boolean.FALSE))) { 886 if (!anyMatch(orderItems, item -> Objects.equals(item.getCommentStatus(), Boolean.FALSE))) {
877 - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE));  
878 - // 增加订单日志 887 + tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE)
  888 + .setFinishTime(LocalDateTime.now()));
  889 + // 增加订单日志。注意:只有在所有订单项都评价后,才会增加
879 TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus()); 890 TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus());
880 } 891 }
881 - return comment; 892 + return commentId;
  893 + }
  894 +
  895 + @Override
  896 + public int createOrderItemCommentBySystem() {
  897 + // 1. 查询过期的待支付订单
  898 + LocalDateTime expireTime = minusTime(tradeOrderProperties.getCommentExpireTime());
  899 + List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndReceiveTimeLt(
  900 + TradeOrderStatusEnum.COMPLETED.getStatus(), expireTime, false);
  901 + if (CollUtil.isEmpty(orders)) {
  902 + return 0;
  903 + }
  904 +
  905 + // 2. 遍历执行,逐个取消
  906 + int count = 0;
  907 + for (TradeOrderDO order : orders) {
  908 + try {
  909 + getSelf().createOrderItemCommentBySystemBySystem(order);
  910 + count ++;
  911 + } catch (Throwable e) {
  912 + log.error("[createOrderItemCommentBySystem][order({}) 过期订单异常]", order.getId(), e);
  913 + }
  914 + }
  915 + return count;
882 } 916 }
883 917
884 /** 918 /**
885 - * 判断指定订单的所有订单项,是不是都售后成功 919 + * 创建单个订单的评论
886 * 920 *
887 - * @param id 订单编号  
888 - * @return 是否都售后成功 921 + * @param order 订单
889 */ 922 */
890 - private boolean isAllOrderItemAfterSaleSuccess(Long id) {  
891 - List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);  
892 - return orderItems.stream().allMatch(orderItem -> Objects.equals(orderItem.getAfterSaleStatus(),  
893 - TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())); 923 + @Transactional(rollbackFor = Exception.class)
  924 + @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_COMMENT)
  925 + public void createOrderItemCommentBySystemBySystem(TradeOrderDO order) {
  926 + // 1. 查询未评论的订单项
  927 + List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderIdAndCommentStatus(order.getId(), Boolean.FALSE);
  928 + if (CollUtil.isEmpty(orderItems)) {
  929 + return;
  930 + }
  931 +
  932 + // 2. 逐个评论
  933 + for (TradeOrderItemDO orderItem : orderItems) {
  934 + // 2.1 创建评价
  935 + AppTradeOrderItemCommentCreateReqVO commentCreateReqVO = new AppTradeOrderItemCommentCreateReqVO()
  936 + .setOrderItemId(orderItem.getId()).setAnonymous(false).setContent("")
  937 + .setBenefitScores(5).setDescriptionScores(5);
  938 + createOrderItemComment0(orderItem, commentCreateReqVO);
  939 +
  940 + // 2.2 更新订单项评价状态
  941 + tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE));
  942 + }
  943 +
  944 + // 3. 所有订单项都评论了,则更新订单评价状态
  945 + tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE)
  946 + .setFinishTime(LocalDateTime.now()));
  947 + // 增加订单日志。注意:只有在所有订单项都评价后,才会增加
  948 + TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus());
  949 + }
  950 +
  951 + /**
  952 + * 创建订单项的评论的核心实现
  953 + *
  954 + * @param orderItem 订单项
  955 + * @param createReqVO 评论内容
  956 + * @return 评论编号
  957 + */
  958 + private Long createOrderItemComment0(TradeOrderItemDO orderItem, AppTradeOrderItemCommentCreateReqVO createReqVO) {
  959 + // 1. 创建评价
  960 + ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItem);
  961 + Long commentId = productCommentApi.createComment(productCommentCreateReqDTO);
  962 +
  963 + // 2. 更新订单项评价状态
  964 + tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE));
  965 + return commentId;
894 } 966 }
895 967
896 // =================== 营销相关的操作 =================== 968 // =================== 营销相关的操作 ===================
yudao-server/src/main/resources/application.yaml
@@ -205,6 +205,7 @@ yudao: @@ -205,6 +205,7 @@ yudao:
205 app-id: 1 # 商户编号 205 app-id: 1 # 商户编号
206 pay-expire-time: 2h # 支付的过期时间 206 pay-expire-time: 2h # 支付的过期时间
207 receive-expire-time: 14d # 收货的过期时间 207 receive-expire-time: 14d # 收货的过期时间
  208 + comment-expire-time: 7d # 评论的过期时间
208 express: 209 express:
209 client: kd_niao 210 client: kd_niao
210 kd-niao: 211 kd-niao: