fix:优化拼团与订单集成逻辑

This commit is contained in:
puhui999 2023-07-24 17:29:51 +08:00
parent 8d13ecc9c8
commit 7957cfa50d
7 changed files with 70 additions and 19 deletions

View File

@ -24,7 +24,8 @@ public interface CombinationApi {
* @param userId 用户编号 * @param userId 用户编号
* @param orderId 订单编号 * @param orderId 订单编号
*/ */
Integer getRecordStatus(Long userId, Long orderId); boolean validateRecordStatusIsSuccess(Long userId, Long orderId);
/** /**
* 更新开团记录状态 * 更新开团记录状态
@ -41,6 +42,7 @@ public interface CombinationApi {
* @param userId 用户编号 * @param userId 用户编号
* @param orderId 订单编号 * @param orderId 订单编号
* @param status 状态值 * @param status 状态值
* @return
*/ */
void updateRecordStatusAndStartTime(Long userId, Long orderId, Integer status); void updateRecordStatusAndStartTime(Long userId, Long orderId, Integer status);

View File

@ -23,8 +23,8 @@ public class CombinationApiImpl implements CombinationApi {
} }
@Override @Override
public Integer getRecordStatus(Long userId, Long orderId) { public boolean validateRecordStatusIsSuccess(Long userId, Long orderId) {
return activityService.getRecordStatus(userId, orderId); return activityService.validateRecordStatusIsSuccess(userId, orderId);
} }
@Override @Override

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity; package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -72,7 +73,9 @@ public class CombinationRecordDO extends BaseDO {
*/ */
private String avatar; private String avatar;
/** /**
* 开团状态 正在开团 拼团成功 拼团失败 * 开团状态
*
* 关联 {@link CombinationRecordStatusEnum}
*/ */
private Integer status; private Integer status;
/** /**

View File

@ -1,9 +1,12 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity; package cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationRecordDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationRecordDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/** /**
* 拼团记录 Mapper * 拼团记录 Mapper
* *
@ -16,4 +19,13 @@ public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO
return selectOne(CombinationRecordDO::getUserId, userId, CombinationRecordDO::getOrderId, orderId); return selectOne(CombinationRecordDO::getUserId, userId, CombinationRecordDO::getOrderId, orderId);
} }
default List<CombinationRecordDO> selectListByHeadIdAndStatus(Long headId, Integer status) {
return selectList(new LambdaQueryWrapperX<CombinationRecordDO>().eq(CombinationRecordDO::getHeadId, headId)
.eq(CombinationRecordDO::getStatus, status));
}
default List<CombinationRecordDO> selectListByStatus(Integer status) {
return selectList(new LambdaQueryWrapperX<CombinationRecordDO>().eq(CombinationRecordDO::getStatus, status));
}
} }

View File

@ -99,6 +99,7 @@ public interface CombinationActivityService {
* @param orderId 订单编号 * @param orderId 订单编号
* @param status 状态 * @param status 状态
* @param startTime 开始时间 * @param startTime 开始时间
* @return
*/ */
void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime); void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime);
@ -116,5 +117,5 @@ public interface CombinationActivityService {
* @param orderId 订单编号 * @param orderId 订单编号
* @return 拼团状态 * @return 拼团状态
*/ */
Integer getRecordStatus(Long userId, Long orderId); boolean validateRecordStatusIsSuccess(Long userId, Long orderId);
} }

View File

@ -24,7 +24,9 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationa
import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationActivityMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationActivityMapper;
import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationProductMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationProductMapper;
import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationRecordMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationRecordMapper;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -217,14 +219,27 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime) { public void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime) {
CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId); CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
// 更新状态 // 更新状态
recordDO.setStatus(status); recordDO.setStatus(status);
// 更新开始时间 // 更新开始时间
recordDO.setStartTime(startTime); recordDO.setStartTime(startTime);
recordMapper.updateById(recordDO); recordMapper.updateById(recordDO);
// 更新拼团参入人数
List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status);
if (CollUtil.isNotEmpty(recordDOs)) {
recordDOs.forEach(item -> {
item.setUserCount(recordDOs.size());
// 校验拼团是否满足要求
if (recordDOs.size() >= recordDO.getUserSize()) {
item.setStatus(CombinationRecordStatusEnum.SUCCESS.getStatus());
}
});
}
recordMapper.updateBatch(recordDOs);
} }
private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) { private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) {
@ -249,9 +264,18 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
} }
@Override @Override
public Integer getRecordStatus(Long userId, Long orderId) { public boolean validateRecordStatusIsSuccess(Long userId, Long orderId) {
CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId); CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
return recordDO.getStatus(); return ObjectUtil.equal(recordDO.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus());
}
/**
* APP 端获取开团记录
*
* @return 开团记录
*/
public List<CombinationRecordDO> getRecordList() {
return recordMapper.selectListByStatus(CombinationRecordStatusEnum.ONGOING.getStatus());
} }
} }

View File

@ -164,13 +164,10 @@ public class TradeOrderServiceImpl implements TradeOrderService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
// 1. 用户收件地址的校验
AddressRespDTO address = validateAddress(userId, createReqVO.getAddressId());
// 2. 价格计算 // 2. 价格计算
TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO); TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO);
// 3.1 插入 TradeOrderDO 订单 // 3.1 插入 TradeOrderDO 订单
TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO, address); TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO);
// 3.2 插入 TradeOrderItemDO 订单项 // 3.2 插入 TradeOrderItemDO 订单项
List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO); List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO);
// 订单创建完后的逻辑 // 订单创建完后的逻辑
@ -183,6 +180,10 @@ public class TradeOrderServiceImpl implements TradeOrderService {
combinationApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user) combinationApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user)
.setStatus(CombinationRecordStatusEnum.NOT_PAY.getStatus())); .setStatus(CombinationRecordStatusEnum.NOT_PAY.getStatus()));
} }
// TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
if (ObjectUtil.equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
}
// TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
return order; return order;
@ -221,7 +222,13 @@ public class TradeOrderServiceImpl implements TradeOrderService {
} }
private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO, private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
TradePriceCalculateRespBO calculateRespBO, AddressRespDTO address) { TradePriceCalculateRespBO calculateRespBO) {
// 用户选择物流配送的时候才需要填写收货地址
AddressRespDTO address = new AddressRespDTO();
if (ObjectUtil.equal(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getMode())) {
// 用户收件地址的校验
address = validateAddress(userId, createReqVO.getAddressId());
}
TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address); TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address);
order.setType(validateActivity(createReqVO)); order.setType(validateActivity(createReqVO));
order.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的; order.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的;
@ -232,7 +239,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
// 支付信息 // 支付信息
order.setAdjustPrice(0).setPayStatus(false); order.setAdjustPrice(0).setPayStatus(false);
// 物流信息 TODO 芋艿暂时写死物流方式应该是前端选择的 // 物流信息 TODO 芋艿暂时写死物流方式应该是前端选择的
order.setDeliveryType(DeliveryTypeEnum.EXPRESS.getMode()).setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); order.setDeliveryType(createReqVO.getDeliveryType()).setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus());
// 退款信息 // 退款信息
order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0); order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0);
tradeOrderMapper.insert(order); tradeOrderMapper.insert(order);
@ -260,7 +267,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
TradePriceCalculateRespBO calculateRespBO) { TradePriceCalculateRespBO calculateRespBO) {
// 下单时扣减商品库存 // 下单时扣减商品库存
productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(orderItems))); productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(orderItems)));
// TODO puhui扣减活动库存
// 删除购物车商品 TODO 芋艿待实现 // 删除购物车商品 TODO 芋艿待实现
// 扣减积分抵扣金额 TODO 芋艿待实现 // 扣减积分抵扣金额 TODO 芋艿待实现
@ -271,7 +278,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
.setOrderId(tradeOrderDO.getId())); .setOrderId(tradeOrderDO.getId()));
} }
// 生成预支付 TODO puhui: 活动支付金额怎么算 // 生成预支付
createPayOrder(tradeOrderDO, orderItems, calculateRespBO); createPayOrder(tradeOrderDO, orderItems, calculateRespBO);
// 增加订单日志 TODO 芋艿待实现 // 增加订单日志 TODO 芋艿待实现
@ -289,6 +296,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void updateOrderPaid(Long id, Long payOrderId) { public void updateOrderPaid(Long id, Long payOrderId) {
// 校验并获得交易订单可支付 // 校验并获得交易订单可支付
KeyValue<TradeOrderDO, PayOrderRespDTO> orderResult = validateOrderPayable(id, payOrderId); KeyValue<TradeOrderDO, PayOrderRespDTO> orderResult = validateOrderPayable(id, payOrderId);
@ -305,7 +313,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
// 校验活动 // 校验活动
// 1拼团活动 // 1拼团活动
if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
// 更新拼团状态 TODO puhui999订单支付失败或订单过期删除这条拼团记录 // 更新拼团状态 TODO puhui999订单支付失败或订单支付过期删除这条拼团记录
combinationApi.updateRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.ONGOING.getStatus()); combinationApi.updateRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.ONGOING.getStatus());
} }
// TODO 芋艿发送订单变化的消息 // TODO 芋艿发送订单变化的消息
@ -498,10 +506,11 @@ public class TradeOrderServiceImpl implements TradeOrderService {
if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) { if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE); throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE);
} }
// 校验订单拼团是否成功 // 订单类型拼团
if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
// 校验订单拼团是否成功
// TODO 用户 ID 使用当前登录用户的还是订单保存的 // TODO 用户 ID 使用当前登录用户的还是订单保存的
if (ObjectUtil.notEqual(combinationApi.getRecordStatus(order.getUserId(), order.getId()), CombinationRecordStatusEnum.SUCCESS.getStatus())) { if (combinationApi.validateRecordStatusIsSuccess(order.getUserId(), order.getId())) {
throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS); throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
} }
} }