mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-28 18:05:08 +08:00
Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product
This commit is contained in:
@ -110,11 +110,6 @@ public class ProductSpuRespDTO {
|
|||||||
|
|
||||||
// ========== 物流相关字段 =========
|
// ========== 物流相关字段 =========
|
||||||
|
|
||||||
/**
|
|
||||||
* 赠送积分
|
|
||||||
*/
|
|
||||||
private Integer giveIntegral;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物流配置模板编号
|
* 物流配置模板编号
|
||||||
*
|
*
|
||||||
@ -122,6 +117,13 @@ public class ProductSpuRespDTO {
|
|||||||
*/
|
*/
|
||||||
private Long deliveryTemplateId;
|
private Long deliveryTemplateId;
|
||||||
|
|
||||||
|
// ========== 营销相关字段 =========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 赠送积分
|
||||||
|
*/
|
||||||
|
private Integer giveIntegral;
|
||||||
|
|
||||||
// ========== 统计相关字段 =========
|
// ========== 统计相关字段 =========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,10 +14,12 @@ import lombok.RequiredArgsConstructor;
|
|||||||
public enum TradeOrderOperateTypeEnum {
|
public enum TradeOrderOperateTypeEnum {
|
||||||
|
|
||||||
MEMBER_CREATE(1, "用户下单"),
|
MEMBER_CREATE(1, "用户下单"),
|
||||||
|
MEMBER_PAY(20, "用户付款成功"),
|
||||||
MEMBER_RECEIVE(30, "用户已收货"),
|
MEMBER_RECEIVE(30, "用户已收货"),
|
||||||
MEMBER_COMMENT(31, "用户评价"),
|
SYSTEM_RECEIVE(31, "到期未收货,系统自动确认收货"),
|
||||||
MEMBER_CANCEL(40, "手动取消订单"),
|
MEMBER_COMMENT(33, "用户评价"),
|
||||||
SYSTEM_CANCEL(41, "系统取消订单"),
|
MEMBER_CANCEL(40, "取消订单"),
|
||||||
|
SYSTEM_CANCEL(41, "到期未支付,系统自动取消订单"),
|
||||||
// 42 预留:管理员取消订单
|
// 42 预留:管理员取消订单
|
||||||
MEMBER_DELETE(43, "删除订单"),
|
MEMBER_DELETE(43, "删除订单"),
|
||||||
;
|
;
|
||||||
|
@ -140,7 +140,7 @@ public class AppTradeOrderController {
|
|||||||
@Operation(summary = "确认交易订单收货")
|
@Operation(summary = "确认交易订单收货")
|
||||||
@Parameter(name = "id", description = "交易订单编号")
|
@Parameter(name = "id", description = "交易订单编号")
|
||||||
public CommonResult<Boolean> receiveOrder(@RequestParam("id") Long id) {
|
public CommonResult<Boolean> receiveOrder(@RequestParam("id") Long id) {
|
||||||
tradeOrderUpdateService.receiveOrder(getLoginUserId(), id);
|
tradeOrderUpdateService.receiveOrderByMember(getLoginUserId(), id);
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ public class AppTradeOrderController {
|
|||||||
@Operation(summary = "取消交易订单")
|
@Operation(summary = "取消交易订单")
|
||||||
@Parameter(name = "id", description = "交易订单编号")
|
@Parameter(name = "id", description = "交易订单编号")
|
||||||
public CommonResult<Boolean> cancelOrder(@RequestParam("id") Long id) {
|
public CommonResult<Boolean> cancelOrder(@RequestParam("id") Long id) {
|
||||||
tradeOrderUpdateService.cancelOrder(getLoginUserId(), id);
|
tradeOrderUpdateService.cancelOrderByMember(getLoginUserId(), id);
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ public interface TradeOrderConvert {
|
|||||||
createReqDTO.setSubject(subject);
|
createReqDTO.setSubject(subject);
|
||||||
createReqDTO.setBody(subject); // TODO 芋艿:临时写死
|
createReqDTO.setBody(subject); // TODO 芋艿:临时写死
|
||||||
// 订单相关字段
|
// 订单相关字段
|
||||||
createReqDTO.setPrice(order.getPayPrice()).setExpireTime(addTime(orderProperties.getExpireTime()));
|
createReqDTO.setPrice(order.getPayPrice()).setExpireTime(addTime(orderProperties.getPayExpireTime()));
|
||||||
return createReqDTO;
|
return createReqDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ public interface TradeOrderConvert {
|
|||||||
TradeOrderProperties tradeOrderProperties,
|
TradeOrderProperties tradeOrderProperties,
|
||||||
DeliveryExpressDO express) {
|
DeliveryExpressDO express) {
|
||||||
AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems);
|
AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems);
|
||||||
orderVO.setPayExpireTime(addTime(tradeOrderProperties.getExpireTime()));
|
orderVO.setPayExpireTime(addTime(tradeOrderProperties.getPayExpireTime()));
|
||||||
if (StrUtil.isNotEmpty(order.getPayChannelCode())) {
|
if (StrUtil.isNotEmpty(order.getPayChannelCode())) {
|
||||||
orderVO.setPayChannelName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHANNEL_CODE, order.getPayChannelCode()));
|
orderVO.setPayChannelName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHANNEL_CODE, order.getPayChannelCode()));
|
||||||
}
|
}
|
||||||
|
@ -146,18 +146,20 @@ public class TradeOrderItemDO extends BaseDO {
|
|||||||
private Integer pointPrice;
|
private Integer pointPrice;
|
||||||
/**
|
/**
|
||||||
* 使用的积分
|
* 使用的积分
|
||||||
|
*
|
||||||
|
* 目的:用于后续取消或者售后订单时,需要归还赠送
|
||||||
*/
|
*/
|
||||||
private Integer usePoint;
|
private Integer usePoint;
|
||||||
/**
|
/**
|
||||||
* 赠送的积分
|
* 赠送的积分
|
||||||
|
*
|
||||||
|
* 目的:用于后续取消或者售后订单时,需要扣减赠送
|
||||||
*/
|
*/
|
||||||
private Integer givePoint;
|
private Integer givePoint;
|
||||||
/**
|
/**
|
||||||
* VIP 减免金额,单位:分
|
* VIP 减免金额,单位:分
|
||||||
*/
|
*/
|
||||||
private Integer vipPrice;
|
private Integer vipPrice;
|
||||||
// TODO @芋艿:如果商品 vip 折扣时,到底是新增一个 vipPrice 记录优惠记录,还是 vipDiscountPrice,记录 vip 的优惠;还是直接使用 vipPrice;
|
|
||||||
// 目前 crmeb 的选择,单独一个 vipPrice 记录优惠价格;感觉不一定合理,可以在看看有赞的;
|
|
||||||
|
|
||||||
// ========== 售后基本信息 ==========
|
// ========== 售后基本信息 ==========
|
||||||
|
|
||||||
|
@ -61,10 +61,16 @@ public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
|
|||||||
.eq(TradeOrderDO::getUserId, loginUserId));
|
.eq(TradeOrderDO::getUserId, loginUserId));
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<TradeOrderDO> selectListByStatusAndCreateTimeLt(Integer status, LocalDateTime expireTime) {
|
default List<TradeOrderDO> selectListByStatusAndCreateTimeLt(Integer status, LocalDateTime createTime) {
|
||||||
return selectList(new LambdaUpdateWrapper<TradeOrderDO>()
|
return selectList(new LambdaUpdateWrapper<TradeOrderDO>()
|
||||||
.eq(TradeOrderDO::getStatus, status)
|
.eq(TradeOrderDO::getStatus, status)
|
||||||
.lt(TradeOrderDO::getCreateTime, expireTime));
|
.lt(TradeOrderDO::getCreateTime, createTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<TradeOrderDO> selectListByStatusAndDeliveryTimeLt(Integer status, LocalDateTime deliveryTime) {
|
||||||
|
return selectList(new LambdaUpdateWrapper<TradeOrderDO>()
|
||||||
|
.eq(TradeOrderDO::getStatus, status)
|
||||||
|
.lt(TradeOrderDO::getDeliveryTime, deliveryTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,12 @@ public class TradeOrderProperties {
|
|||||||
* 支付超时时间
|
* 支付超时时间
|
||||||
*/
|
*/
|
||||||
@NotNull(message = "支付超时时间不能为空")
|
@NotNull(message = "支付超时时间不能为空")
|
||||||
private Duration expireTime;
|
private Duration payExpireTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收货超时时间
|
||||||
|
*/
|
||||||
|
@NotNull(message = "收货超时时间不能为空")
|
||||||
|
private Duration receiveExpireTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,10 @@ package cn.iocoder.yudao.module.trade.framework.order.core.annotations;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
|
@ -31,6 +31,16 @@ import static java.util.Collections.emptyMap;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class TradeOrderLogAspect {
|
public class TradeOrderLogAspect {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*
|
||||||
|
* 目前的使用场景:支付回调时,需要强制设置下用户编号
|
||||||
|
*/
|
||||||
|
private static final ThreadLocal<Long> USER_ID = new ThreadLocal<>();
|
||||||
|
/**
|
||||||
|
* 用户类型
|
||||||
|
*/
|
||||||
|
private static final ThreadLocal<Integer> USER_TYPE = new ThreadLocal<>();
|
||||||
/**
|
/**
|
||||||
* 订单编号
|
* 订单编号
|
||||||
*/
|
*/
|
||||||
@ -112,4 +122,9 @@ public class TradeOrderLogAspect {
|
|||||||
EXTS.set(exts);
|
EXTS.set(exts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setUserInfo(Long userId, Integer userType) {
|
||||||
|
USER_ID.set(userId);
|
||||||
|
USER_TYPE.set(userType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,4 +20,8 @@ public class TradeOrderLogUtils {
|
|||||||
TradeOrderLogAspect.setOrderInfo(id, beforeStatus, afterStatus, exts);
|
TradeOrderLogAspect.setOrderInfo(id, beforeStatus, afterStatus, exts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setUserInfo(Long userId, Integer userType) {
|
||||||
|
TradeOrderLogAspect.setUserInfo(userId, userType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ public class TradeOrderAutoCancelJob implements JobHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String execute(String param) {
|
public String execute(String param) {
|
||||||
int count = tradeOrderUpdateService.autoCancelOrder();
|
int count = tradeOrderUpdateService.cancelOrderBySystem();
|
||||||
return String.format("过期订单 %s 个", count);
|
return String.format("过期订单 %s 个", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 TradeOrderAutoReceiveJob implements JobHandler {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TradeOrderUpdateService tradeOrderUpdateService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String execute(String param) {
|
||||||
|
int count = tradeOrderUpdateService.receiveOrderBySystem();
|
||||||
|
return String.format("自动收货 %s 个", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -60,22 +60,29 @@ public interface TradeOrderUpdateService {
|
|||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @param id 订单编号
|
* @param id 订单编号
|
||||||
*/
|
*/
|
||||||
void receiveOrder(Long userId, Long id);
|
void receiveOrderByMember(Long userId, Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【会员】取消订单
|
* 【系统】自动收货交易订单
|
||||||
|
*
|
||||||
|
* @return 收货数量
|
||||||
|
*/
|
||||||
|
int receiveOrderBySystem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【会员】取消交易订单
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @param id 订单编号
|
* @param id 订单编号
|
||||||
*/
|
*/
|
||||||
void cancelOrder(Long userId, Long id);
|
void cancelOrderByMember(Long userId, Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【系统】自动取消订单
|
* 【系统】自动取消订单
|
||||||
*
|
*
|
||||||
* @return 取消数量
|
* @return 取消数量
|
||||||
*/
|
*/
|
||||||
int autoCancelOrder();
|
int cancelOrderBySystem();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【会员】删除订单
|
* 【会员】删除订单
|
||||||
|
@ -8,6 +8,7 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||||
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.module.member.api.address.AddressApi;
|
import cn.iocoder.yudao.module.member.api.address.AddressApi;
|
||||||
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
|
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
|
||||||
@ -321,38 +322,39 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_PAY)
|
||||||
public void updateOrderPaid(Long id, Long payOrderId) {
|
public void updateOrderPaid(Long id, Long payOrderId) {
|
||||||
// 校验并获得交易订单(可支付)
|
// 1. 校验并获得交易订单(可支付)
|
||||||
KeyValue<TradeOrderDO, PayOrderRespDTO> orderResult = validateOrderPayable(id, payOrderId);
|
KeyValue<TradeOrderDO, PayOrderRespDTO> orderResult = validateOrderPayable(id, payOrderId);
|
||||||
TradeOrderDO order = orderResult.getKey();
|
TradeOrderDO order = orderResult.getKey();
|
||||||
PayOrderRespDTO payOrder = orderResult.getValue();
|
PayOrderRespDTO payOrder = orderResult.getValue();
|
||||||
|
|
||||||
// 更新 TradeOrderDO 状态为已支付,等待发货
|
// 2. 更新 TradeOrderDO 状态为已支付,等待发货
|
||||||
int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(),
|
int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(),
|
||||||
new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayStatus(true)
|
new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayStatus(true)
|
||||||
.setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode()));
|
.setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode()));
|
||||||
if (updateCount == 0) {
|
if (updateCount == 0) {
|
||||||
throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
|
throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
|
||||||
}
|
}
|
||||||
// 校验活动
|
|
||||||
|
// 3. 校验活动
|
||||||
// 1、拼团活动
|
// 1、拼团活动
|
||||||
// TODO @puhui999:这块也抽象到 handler 里
|
// TODO @puhui999:这块也抽象到 handler 里
|
||||||
if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
|
if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
|
||||||
// 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
|
// 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
|
||||||
combinationRecordApi.updateRecordStatusToInProgress(order.getUserId(), order.getId(), LocalDateTime.now());
|
combinationRecordApi.updateRecordStatusToInProgress(order.getUserId(), order.getId(), LocalDateTime.now());
|
||||||
}
|
}
|
||||||
// TODO 芋艿:发送订单变化的消息
|
|
||||||
|
|
||||||
// TODO 芋艿:发送站内信
|
// 4.1 增加用户积分(赠送)
|
||||||
|
addUserPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE, order.getId());
|
||||||
// TODO 芋艿:OrderLog
|
// 4.2 增加用户经验
|
||||||
|
|
||||||
// 增加用户积分(赠送)
|
|
||||||
addUserPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_REWARD, order.getId());
|
|
||||||
// 增加用户经验
|
|
||||||
getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId());
|
getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId());
|
||||||
// 增加用户佣金
|
// 4.3 增加用户佣金
|
||||||
getSelf().addBrokerageAsync(order.getUserId(), order.getId());
|
getSelf().addBrokerageAsync(order.getUserId(), order.getId());
|
||||||
|
|
||||||
|
// 5. 记录订单日志
|
||||||
|
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus());
|
||||||
|
TradeOrderLogUtils.setUserInfo(order.getUserId(), UserTypeEnum.MEMBER.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -435,8 +437,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
|
throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:发送订单变化的消息
|
|
||||||
|
|
||||||
// 发送站内信
|
// 发送站内信
|
||||||
tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO().setOrderId(order.getId())
|
tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO().setOrderId(order.getId())
|
||||||
.setUserId(order.getUserId()).setMessage(null));
|
.setUserId(order.getUserId()).setMessage(null));
|
||||||
@ -488,10 +488,54 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_RECEIVE)
|
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_RECEIVE)
|
||||||
public void receiveOrder(Long userId, Long id) {
|
public void receiveOrderByMember(Long userId, Long id) {
|
||||||
// 校验并获得交易订单(可收货)
|
// 校验并获得交易订单(可收货)
|
||||||
TradeOrderDO order = validateOrderReceivable(userId, id);
|
TradeOrderDO order = validateOrderReceivable(userId, id);
|
||||||
|
|
||||||
|
// 收货订单
|
||||||
|
receiveOrder0(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int receiveOrderBySystem() {
|
||||||
|
// 1. 查询过期的待支付订单
|
||||||
|
LocalDateTime expireTime = addTime(tradeOrderProperties.getReceiveExpireTime());
|
||||||
|
List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndDeliveryTimeLt(
|
||||||
|
TradeOrderStatusEnum.DELIVERED.getStatus(), expireTime);
|
||||||
|
if (CollUtil.isEmpty(orders)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 遍历执行,逐个取消
|
||||||
|
int count = 0;
|
||||||
|
for (TradeOrderDO order : orders) {
|
||||||
|
try {
|
||||||
|
getSelf().receiveOrderBySystem(order);
|
||||||
|
count ++;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error("[autoReceiveOrder][order({}) 自动收货订单异常]", order.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动收货单个订单
|
||||||
|
*
|
||||||
|
* @param order 订单
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_RECEIVE)
|
||||||
|
public void receiveOrderBySystem(TradeOrderDO order) {
|
||||||
|
receiveOrder0(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收货订单的核心实现
|
||||||
|
*
|
||||||
|
* @param order 订单
|
||||||
|
*/
|
||||||
|
private void receiveOrder0(TradeOrderDO order) {
|
||||||
// 更新 TradeOrderDO 状态为已完成
|
// 更新 TradeOrderDO 状态为已完成
|
||||||
int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(),
|
int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(),
|
||||||
new TradeOrderDO().setStatus(TradeOrderStatusEnum.COMPLETED.getStatus()).setReceiveTime(LocalDateTime.now()));
|
new TradeOrderDO().setStatus(TradeOrderStatusEnum.COMPLETED.getStatus()).setReceiveTime(LocalDateTime.now()));
|
||||||
@ -499,16 +543,139 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED);
|
throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:lili 发送订单变化的消息
|
|
||||||
|
|
||||||
// TODO 芋艿:lili 发送商品被购买完成的数据
|
|
||||||
|
|
||||||
// TODO 芋艿:销售佣金的记录;
|
|
||||||
|
|
||||||
// 插入订单日志
|
// 插入订单日志
|
||||||
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus());
|
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验交易订单满足可售货的条件
|
||||||
|
*
|
||||||
|
* 1. 交易订单待收货
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param id 交易订单编号
|
||||||
|
* @return 交易订单
|
||||||
|
*/
|
||||||
|
private TradeOrderDO validateOrderReceivable(Long userId, Long id) {
|
||||||
|
// 校验订单是否存在
|
||||||
|
TradeOrderDO order = tradeOrderMapper.selectByIdAndUserId(id, userId);
|
||||||
|
if (order == null) {
|
||||||
|
throw exception(ORDER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 校验订单是否是待收货状态
|
||||||
|
if (!TradeOrderStatusEnum.isDelivered(order.getStatus())) {
|
||||||
|
throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED);
|
||||||
|
}
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CANCEL)
|
||||||
|
public void cancelOrderByMember(Long userId, Long id) {
|
||||||
|
// 1.1 校验存在
|
||||||
|
TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(id, userId);
|
||||||
|
if (order == null) {
|
||||||
|
throw exception(ORDER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 1.2 校验状态
|
||||||
|
if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus())) {
|
||||||
|
throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 取消订单
|
||||||
|
cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int cancelOrderBySystem() {
|
||||||
|
// 1. 查询过期的待支付订单
|
||||||
|
LocalDateTime expireTime = addTime(tradeOrderProperties.getPayExpireTime());
|
||||||
|
List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndCreateTimeLt(
|
||||||
|
TradeOrderStatusEnum.UNPAID.getStatus(), expireTime);
|
||||||
|
if (CollUtil.isEmpty(orders)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 遍历执行,逐个取消
|
||||||
|
int count = 0;
|
||||||
|
for (TradeOrderDO order : orders) {
|
||||||
|
try {
|
||||||
|
getSelf().cancelOrderBySystem(order);
|
||||||
|
count ++;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error("[autoCancelOrder][order({}) 过期订单异常]", order.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动取消单个订单
|
||||||
|
*
|
||||||
|
* @param order 订单
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_CANCEL)
|
||||||
|
public void cancelOrderBySystem(TradeOrderDO order) {
|
||||||
|
cancelOrder0(order, TradeOrderCancelTypeEnum.PAY_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消订单的核心实现
|
||||||
|
*
|
||||||
|
* @param order 订单
|
||||||
|
* @param cancelType 取消类型
|
||||||
|
*/
|
||||||
|
private void cancelOrder0(TradeOrderDO order, TradeOrderCancelTypeEnum cancelType) {
|
||||||
|
Long id = order.getId();
|
||||||
|
// 1. 更新 TradeOrderDO 状态为已取消
|
||||||
|
int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(),
|
||||||
|
new TradeOrderDO().setStatus(TradeOrderStatusEnum.CANCELED.getStatus())
|
||||||
|
.setCancelType(cancelType.getType()).setCancelTime(LocalDateTime.now()));
|
||||||
|
if (updateCount == 0) {
|
||||||
|
throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来;回复:从订单里拿呀
|
||||||
|
tradeOrderHandlers.forEach(handler -> handler.rollback());
|
||||||
|
|
||||||
|
// 3. 回滚库存
|
||||||
|
List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
|
||||||
|
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems));
|
||||||
|
|
||||||
|
// 4. 回滚优惠券
|
||||||
|
if (order.getCouponId() != null && order.getCouponId() > 0) {
|
||||||
|
couponApi.returnUsedCoupon(order.getCouponId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 回滚积分(抵扣的)
|
||||||
|
addUserPoint(order.getUserId(), order.getUsePoint(), MemberPointBizTypeEnum.ORDER_CANCEL, order.getId());
|
||||||
|
|
||||||
|
// 6. 增加订单日志
|
||||||
|
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_DELETE)
|
||||||
|
public void deleteOrder(Long userId, Long id) {
|
||||||
|
// 1.1 校验存在
|
||||||
|
TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(id, userId);
|
||||||
|
if (order == null) {
|
||||||
|
throw exception(ORDER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 1.2 校验状态
|
||||||
|
if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus())) {
|
||||||
|
throw exception(ORDER_DELETE_FAIL_STATUS_NOT_CANCEL);
|
||||||
|
}
|
||||||
|
// 2. 删除订单
|
||||||
|
tradeOrderMapper.deleteById(id);
|
||||||
|
|
||||||
|
// 3. 记录日志
|
||||||
|
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateOrderRemark(TradeOrderRemarkReqVO reqVO) {
|
public void updateOrderRemark(TradeOrderRemarkReqVO reqVO) {
|
||||||
// 校验并获得交易订单
|
// 校验并获得交易订单
|
||||||
@ -604,33 +771,13 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
tradeOrderMapper.updateById(update);
|
tradeOrderMapper.updateById(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验交易订单满足可售货的条件
|
|
||||||
*
|
|
||||||
* 1. 交易订单待收货
|
|
||||||
*
|
|
||||||
* @param userId 用户编号
|
|
||||||
* @param id 交易订单编号
|
|
||||||
* @return 交易订单
|
|
||||||
*/
|
|
||||||
private TradeOrderDO validateOrderReceivable(Long userId, Long id) {
|
|
||||||
// 校验订单是否存在
|
|
||||||
TradeOrderDO order = tradeOrderMapper.selectByIdAndUserId(id, userId);
|
|
||||||
if (order == null) {
|
|
||||||
throw exception(ORDER_NOT_FOUND);
|
|
||||||
}
|
|
||||||
// 校验订单是否是待收货状态
|
|
||||||
if (!TradeOrderStatusEnum.isDelivered(order.getStatus())) {
|
|
||||||
throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED);
|
|
||||||
}
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =================== Order Item ===================
|
// =================== Order Item ===================
|
||||||
|
|
||||||
|
// TODO 疯狂:帮我重构下:
|
||||||
|
// 1. updateOrderItemAfterSaleStatus 拆分成三个方法:发起;同意;拒绝。原因是,职责更清晰,操作日志也更容易记录;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
// TODO 芋艿:
|
|
||||||
public void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus,
|
public void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus,
|
||||||
Long afterSaleId, Integer refundPrice) {
|
Long afterSaleId, Integer refundPrice) {
|
||||||
// 如果退款成功,则 refundPrice 非空
|
// 如果退款成功,则 refundPrice 非空
|
||||||
@ -658,6 +805,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id);
|
TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id);
|
||||||
TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId());
|
TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId());
|
||||||
Integer orderRefundPrice = order.getRefundPrice() + refundPrice;
|
Integer orderRefundPrice = order.getRefundPrice() + refundPrice;
|
||||||
|
// TODO @疯狂:809 到 817 改成:cancelOrderByAfterSale:相当于全部售后成功后,就是要取消胆子;
|
||||||
if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单
|
if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单
|
||||||
tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
|
tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
|
||||||
.setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice).setRefundPoint(order.getRefundPoint() + orderItem.getUsePoint())
|
.setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice).setRefundPoint(order.getRefundPoint() + orderItem.getUsePoint())
|
||||||
@ -667,7 +815,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
|
|
||||||
// TODO 芋艿:要不要退优惠劵
|
// TODO 芋艿:要不要退优惠劵
|
||||||
|
|
||||||
// TODO 芋艿:站内信?
|
|
||||||
} else { // 如果部分售后,则更新退款金额
|
} else { // 如果部分售后,则更新退款金额
|
||||||
tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
|
tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
|
||||||
.setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice));
|
.setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice));
|
||||||
@ -676,6 +823,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
// TODO 芋艿:这块扣减规则,需要在考虑下
|
// TODO 芋艿:这块扣减规则,需要在考虑下
|
||||||
// 售后成功后,执行数据回滚逻辑
|
// 售后成功后,执行数据回滚逻辑
|
||||||
if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())) {
|
if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())) {
|
||||||
|
// TODO @疯狂:这里库存也要扣减下;
|
||||||
// 扣减用户积分(赠送的)
|
// 扣减用户积分(赠送的)
|
||||||
reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, afterSaleId);
|
reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, afterSaleId);
|
||||||
// 增加用户积分(返还抵扣)
|
// 增加用户积分(返还抵扣)
|
||||||
@ -723,113 +871,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
return comment;
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CANCEL)
|
|
||||||
public void cancelOrder(Long userId, Long id) {
|
|
||||||
// 1.1 校验存在
|
|
||||||
TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(id, userId);
|
|
||||||
if (order == null) {
|
|
||||||
throw exception(ORDER_NOT_FOUND);
|
|
||||||
}
|
|
||||||
// 1.2 校验状态
|
|
||||||
if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus())) {
|
|
||||||
throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 取消订单
|
|
||||||
cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int autoCancelOrder() {
|
|
||||||
// 1. 查询过期的待支付订单
|
|
||||||
LocalDateTime expireTime = addTime(tradeOrderProperties.getExpireTime());
|
|
||||||
List<TradeOrderDO> orders = tradeOrderMapper.selectListByStatusAndCreateTimeLt(
|
|
||||||
TradeOrderStatusEnum.UNPAID.getStatus(), expireTime);
|
|
||||||
if (CollUtil.isEmpty(orders)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 遍历执行,逐个取消
|
|
||||||
int count = 0;
|
|
||||||
for (TradeOrderDO order : orders) {
|
|
||||||
try {
|
|
||||||
getSelf().autoCancelOrder(order);
|
|
||||||
count ++;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
log.error("[autoCancelOrder][order({}) 过期订单异常]", order.getId(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自动取消单个订单
|
|
||||||
*
|
|
||||||
* @param order 订单
|
|
||||||
*/
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_CANCEL)
|
|
||||||
public void autoCancelOrder(TradeOrderDO order) {
|
|
||||||
cancelOrder0(order, TradeOrderCancelTypeEnum.PAY_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消订单的核心实现
|
|
||||||
*
|
|
||||||
* @param order 订单
|
|
||||||
* @param cancelType 取消类型
|
|
||||||
*/
|
|
||||||
private void cancelOrder0(TradeOrderDO order, TradeOrderCancelTypeEnum cancelType) {
|
|
||||||
Long id = order.getId();
|
|
||||||
// 1. 更新 TradeOrderDO 状态为已取消
|
|
||||||
int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(),
|
|
||||||
new TradeOrderDO().setStatus(TradeOrderStatusEnum.CANCELED.getStatus())
|
|
||||||
.setCancelType(cancelType.getType()).setCancelTime(LocalDateTime.now()));
|
|
||||||
if (updateCount == 0) {
|
|
||||||
throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来;回复:从订单里拿呀
|
|
||||||
tradeOrderHandlers.forEach(handler -> handler.rollback());
|
|
||||||
|
|
||||||
// 3. 回滚库存
|
|
||||||
List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
|
|
||||||
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems));
|
|
||||||
|
|
||||||
// 4. 回滚优惠券
|
|
||||||
if (order.getCouponId() != null && order.getCouponId() > 0) {
|
|
||||||
couponApi.returnUsedCoupon(order.getCouponId());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. 回滚积分(抵扣的)
|
|
||||||
addUserPoint(order.getUserId(), order.getUsePoint(), MemberPointBizTypeEnum.ORDER_CANCEL, order.getId());
|
|
||||||
|
|
||||||
// 6. 增加订单日志
|
|
||||||
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_DELETE)
|
|
||||||
public void deleteOrder(Long userId, Long id) {
|
|
||||||
// 1.1 校验存在
|
|
||||||
TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(id, userId);
|
|
||||||
if (order == null) {
|
|
||||||
throw exception(ORDER_NOT_FOUND);
|
|
||||||
}
|
|
||||||
// 1.2 校验状态
|
|
||||||
if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus())) {
|
|
||||||
throw exception(ORDER_DELETE_FAIL_STATUS_NOT_CANCEL);
|
|
||||||
}
|
|
||||||
// 2. 删除订单
|
|
||||||
tradeOrderMapper.deleteById(id);
|
|
||||||
|
|
||||||
// 3. 记录日志
|
|
||||||
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断指定订单的所有订单项,是不是都售后成功
|
* 判断指定订单的所有订单项,是不是都售后成功
|
||||||
*
|
*
|
||||||
@ -842,6 +883,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()));
|
TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =================== 营销相关的操作 ===================
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
protected void addUserExperienceAsync(Long userId, Integer payPrice, Long orderId) {
|
protected void addUserExperienceAsync(Long userId, Integer payPrice, Long orderId) {
|
||||||
int bizType = MemberExperienceBizTypeEnum.ORDER.getType();
|
int bizType = MemberExperienceBizTypeEnum.ORDER.getType();
|
||||||
|
@ -16,6 +16,7 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
|
||||||
|
|
||||||
|
// TODO @疯狂:这个可以搞个单测;
|
||||||
/**
|
/**
|
||||||
* 赠送积分的 {@link TradePriceCalculator} 实现类
|
* 赠送积分的 {@link TradePriceCalculator} 实现类
|
||||||
*
|
*
|
||||||
@ -25,6 +26,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
|||||||
@Order(TradePriceCalculator.ORDER_POINT_GIVE)
|
@Order(TradePriceCalculator.ORDER_POINT_GIVE)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TradePointGiveCalculator implements TradePriceCalculator {
|
public class TradePointGiveCalculator implements TradePriceCalculator {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MemberPointApi memberPointApi;
|
private MemberPointApi memberPointApi;
|
||||||
|
|
||||||
@ -54,9 +56,10 @@ public class TradePointGiveCalculator implements TradePriceCalculator {
|
|||||||
TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i);
|
TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i);
|
||||||
// 商品可能赠送了积分,所以这里要加上
|
// 商品可能赠送了积分,所以这里要加上
|
||||||
orderItem.setGivePoint(orderItem.getGivePoint() + dividePoints.get(i));
|
orderItem.setGivePoint(orderItem.getGivePoint() + dividePoints.get(i));
|
||||||
TradePriceCalculatorHelper.recountPayPrice(orderItem);
|
TradePriceCalculatorHelper.recountPayPrice(orderItem); // TODO @疯狂:这个应该不用调用哇?不影响支付金额
|
||||||
}
|
}
|
||||||
// 3.3 更新订单赠送积分
|
// 3.3 更新订单赠送积分
|
||||||
TradePriceCalculatorHelper.recountAllGivePoint(result);
|
TradePriceCalculatorHelper.recountAllGivePoint(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
|
||||||
|
|
||||||
|
// TODO @疯狂:搞个单测,嘿嘿;
|
||||||
/**
|
/**
|
||||||
* 使用积分的 {@link TradePriceCalculator} 实现类
|
* 使用积分的 {@link TradePriceCalculator} 实现类
|
||||||
*
|
*
|
||||||
@ -29,6 +30,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
|||||||
@Order(TradePriceCalculator.ORDER_POINT_USE)
|
@Order(TradePriceCalculator.ORDER_POINT_USE)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TradePointUsePriceCalculator implements TradePriceCalculator {
|
public class TradePointUsePriceCalculator implements TradePriceCalculator {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MemberPointApi memberPointApi;
|
private MemberPointApi memberPointApi;
|
||||||
@Resource
|
@Resource
|
||||||
@ -48,13 +50,14 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator {
|
|||||||
}
|
}
|
||||||
// 1.3 校验用户积分余额
|
// 1.3 校验用户积分余额
|
||||||
MemberUserRespDTO user = memberUserApi.getUser(param.getUserId());
|
MemberUserRespDTO user = memberUserApi.getUser(param.getUserId());
|
||||||
if (user.getPoint() == null || user.getPoint() < 0) {
|
if (user.getPoint() == null || user.getPoint() <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.1 计算积分优惠金额
|
// 2.1 计算积分优惠金额
|
||||||
|
// TODO @疯狂:如果计算出来,优惠金额为 0,那是不是不用执行后续逻辑哈
|
||||||
int pointPrice = calculatePointPrice(config, user.getPoint(), result);
|
int pointPrice = calculatePointPrice(config, user.getPoint(), result);
|
||||||
// 2.1 计算分摊的积分、抵扣金额
|
// 2.2 计算分摊的积分、抵扣金额
|
||||||
List<TradePriceCalculateRespBO.OrderItem> orderItems = filterList(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSelected);
|
List<TradePriceCalculateRespBO.OrderItem> orderItems = filterList(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSelected);
|
||||||
List<Integer> dividePointPrices = TradePriceCalculatorHelper.dividePrice(orderItems, pointPrice);
|
List<Integer> dividePointPrices = TradePriceCalculatorHelper.dividePrice(orderItems, pointPrice);
|
||||||
List<Integer> divideUsePoints = TradePriceCalculatorHelper.dividePrice(orderItems, result.getUsePoint());
|
List<Integer> divideUsePoints = TradePriceCalculatorHelper.dividePrice(orderItems, result.getUsePoint());
|
||||||
@ -74,7 +77,9 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator {
|
|||||||
TradePriceCalculatorHelper.recountAllPrice(result);
|
TradePriceCalculatorHelper.recountAllPrice(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @疯狂:这个最好是 is 开头;因为 check 或者 validator,更多失败,会抛出异常;
|
||||||
private boolean checkDeductPointEnable(MemberPointConfigRespDTO config) {
|
private boolean checkDeductPointEnable(MemberPointConfigRespDTO config) {
|
||||||
|
// TODO @疯狂:这个要不直接写成 return config != null && config .... 多行这样一个形式;
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -103,7 +108,7 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator {
|
|||||||
}
|
}
|
||||||
// 记录使用的积分
|
// 记录使用的积分
|
||||||
result.setUsePoint(usePoint);
|
result.setUsePoint(usePoint);
|
||||||
|
|
||||||
return pointPrice;
|
return pointPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,13 @@ public interface TradePriceCalculator {
|
|||||||
/**
|
/**
|
||||||
* 快递运费的计算
|
* 快递运费的计算
|
||||||
*
|
*
|
||||||
* 放在各种营销活动、优惠劵后面 TODO
|
* 放在各种营销活动、优惠劵后面
|
||||||
*/
|
*/
|
||||||
int ORDER_DELIVERY = 50;
|
int ORDER_DELIVERY = 50;
|
||||||
/**
|
/**
|
||||||
* 赠送积分,放最后
|
* 赠送积分,放最后
|
||||||
|
*
|
||||||
|
* 放在 {@link #ORDER_DELIVERY} 后面的原因,是运费也会产生费用,需要赠送对应积分
|
||||||
*/
|
*/
|
||||||
int ORDER_POINT_GIVE = 999;
|
int ORDER_POINT_GIVE = 999;
|
||||||
|
|
||||||
|
@ -199,6 +199,8 @@ public class TradePriceCalculatorHelper {
|
|||||||
/**
|
/**
|
||||||
* 按照支付金额,返回每个订单项的分摊金额数组
|
* 按照支付金额,返回每个订单项的分摊金额数组
|
||||||
*
|
*
|
||||||
|
* 实际上 price 不仅仅可以传递的是金额,也可以是积分。因为它的实现逻辑,就是根据 payPrice 做分摊而已
|
||||||
|
*
|
||||||
* @param orderItems 订单项数组
|
* @param orderItems 订单项数组
|
||||||
* @param price 金额
|
* @param price 金额
|
||||||
* @return 分摊金额数组,和传入的 orderItems 一一对应
|
* @return 分摊金额数组,和传入的 orderItems 一一对应
|
||||||
|
@ -87,7 +87,7 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
|
|||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
when(tradeOrderProperties.getAppId()).thenReturn(888L);
|
when(tradeOrderProperties.getAppId()).thenReturn(888L);
|
||||||
when(tradeOrderProperties.getExpireTime()).thenReturn(Duration.ofDays(1));
|
when(tradeOrderProperties.getPayExpireTime()).thenReturn(Duration.ofDays(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -306,7 +306,7 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
|
|||||||
// mock 方法(支付单)
|
// mock 方法(支付单)
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
tradeOrderUpdateService.receiveOrder(userId, id);
|
tradeOrderUpdateService.receiveOrderByMember(userId, id);
|
||||||
// 断言
|
// 断言
|
||||||
TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L);
|
TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L);
|
||||||
assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus());
|
assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus());
|
||||||
|
@ -12,6 +12,7 @@ import javax.validation.constraints.Min;
|
|||||||
*/
|
*/
|
||||||
public interface MemberPointApi {
|
public interface MemberPointApi {
|
||||||
|
|
||||||
|
// TODO @疯狂:这个我们要不要搞成通用的会员配置?MemberConfig?
|
||||||
/**
|
/**
|
||||||
* 获得积分配置
|
* 获得积分配置
|
||||||
*
|
*
|
||||||
|
@ -9,6 +9,7 @@ import lombok.Data;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class MemberPointConfigRespDTO {
|
public class MemberPointConfigRespDTO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 积分抵扣开关
|
* 积分抵扣开关
|
||||||
*/
|
*/
|
||||||
@ -27,4 +28,5 @@ public class MemberPointConfigRespDTO {
|
|||||||
* 1 元赠送多少分
|
* 1 元赠送多少分
|
||||||
*/
|
*/
|
||||||
private Integer tradeGivePoint;
|
private Integer tradeGivePoint;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,4 +51,5 @@ public class MemberUserRespDTO {
|
|||||||
* 积分
|
* 积分
|
||||||
*/
|
*/
|
||||||
private Integer point;
|
private Integer point;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,11 @@ import java.util.Objects;
|
|||||||
public enum MemberPointBizTypeEnum implements IntArrayValuable {
|
public enum MemberPointBizTypeEnum implements IntArrayValuable {
|
||||||
|
|
||||||
SIGN(1, "签到", "签到获得 {} 积分", true),
|
SIGN(1, "签到", "签到获得 {} 积分", true),
|
||||||
ORDER_REWARD(10, "订单奖励", "下单获得 {} 积分", true),
|
ORDER_GIVE(10, "订单奖励", "下单获得 {} 积分", true), // 支付订单时,赠送积分
|
||||||
ORDER_CANCEL(11, "订单取消", "订单取消,退还 {} 积分", true), // 退回积分
|
ORDER_CANCEL(11, "订单取消", "订单取消,退还 {} 积分", true), // 取消订单时,退回积分
|
||||||
ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 扣减积分
|
ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 下单时,扣减积分
|
||||||
AFTER_SALE_REFUND_USED(13, "订单退款", "订单退款,退还 {} 积分", true), // 退回积分
|
AFTER_SALE_REFUND_USED(13, "订单退款", "订单退款,退还 {} 积分", true), // 售后订单成功时,退回积分(对应 ORDER_USE 操作)
|
||||||
AFTER_SALE_DEDUCT_GIVE(14, "订单退款", "订单退款,扣除赠送的 {} 积分", false), // 扣减积分
|
AFTER_SALE_DEDUCT_GIVE(14, "订单退款", "订单退款,扣除赠送的 {} 积分", false), // 售后订单成功时,扣减积分(对应 ORDER_GIVE 操作)
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,7 +203,8 @@ yudao:
|
|||||||
trade:
|
trade:
|
||||||
order:
|
order:
|
||||||
app-id: 1 # 商户编号
|
app-id: 1 # 商户编号
|
||||||
expire-time: 2h # 支付的过期时间
|
pay-expire-time: 2h # 支付的过期时间
|
||||||
|
receive-expire-time: 14d # 收货的过期时间
|
||||||
express:
|
express:
|
||||||
client: kd_niao
|
client: kd_niao
|
||||||
kd-niao:
|
kd-niao:
|
||||||
|
Reference in New Issue
Block a user