diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java index 2ed262cde..3581fdb91 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java @@ -39,7 +39,7 @@ public interface ProductSkuApi { List getSkuListBySpuId(Collection spuIds); /** - * 更新 SKU 库存 + * 更新 SKU 库存(增加 or 减少) * * @param updateStockReqDTO 更新请求 */ diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 4b8410b83..500601442 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -58,8 +58,9 @@ public interface ErrorCodeConstants { // ========== Price 相关 1011003000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011003000, "支付价格计算异常,原因:价格小于等于 0"); - ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空"); + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空"); ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011003002, "计算快递运费异常,找不到对应的运费模板"); + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_PICK_UP_STORE_IS_EMPTY = new ErrorCode(1011003003, "计算快递运费异常,自提点为空"); // ========== 物流 Express 模块 1011004000 ========== ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在"); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java index 7754f115d..210f5c307 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java @@ -15,7 +15,6 @@ import java.util.Arrays; @AllArgsConstructor public enum DeliveryTypeEnum implements IntArrayValuable { - NULL(0, "无需物流"), EXPRESS(1, "快递发货"), PICK_UP(2, "用户自提"),; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http index 4f3de0c5d..b62e6eb1f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http @@ -15,7 +15,8 @@ Authorization: Bearer {{appToken}} tenant-id: {{appTenentId}} { - "type": 0, + "pointStatus": true, + "deliveryType": 1, "addressId": 21, "items": [ { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 888a3d4df..4bbd98a27 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.trade.controller.app.order; -import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; @@ -12,11 +11,8 @@ import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; -import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog; -import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; @@ -65,10 +61,7 @@ public class AppTradeOrderController { @PostMapping("/create") @Operation(summary = "创建订单") @PreAuthenticated - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.TEST) - public CommonResult createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO) { - TradeOrderLogUtils.setOrderInfo(10L, 1, 2, - MapUtil.builder().put("nickname", "小明").put("thing", "种土豆").build()); + public CommonResult createOrder(@Valid @RequestBody AppTradeOrderCreateReqVO createReqVO) { TradeOrderDO order = tradeOrderUpdateService.createOrder(getLoginUserId(), getClientIP(), createReqVO); return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId())); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java index 11031a884..2f4503d02 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; +import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import javax.validation.constraints.AssertTrue; + @Schema(description = "用户 App - 交易订单创建 Request VO") @Data public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO { @@ -10,4 +13,10 @@ public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO { @Schema(description = "备注", example = "这个是我的订单哟") private String remark; + @AssertTrue(message = "配送方式不能为空") + @JsonIgnore + public boolean isDeliveryTypeNotNull() { + return getDeliveryType() != null; + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java index 929a2ec19..74535d173 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java @@ -30,7 +30,7 @@ public class AppTradeOrderSettlementReqVO { private Boolean pointStatus; // ========== 配送相关相关字段 ========== - @Schema(description = "配送方式", required = true, example = "1") + @Schema(description = "配送方式", example = "1") @InEnum(value = DeliveryTypeEnum.class, message = "配送方式不正确") private Integer deliveryType; @@ -62,6 +62,8 @@ public class AppTradeOrderSettlementReqVO { @Schema(description = "砍价活动编号", example = "123") private Long bargainActivityId; + // TODO @puhui999:可以写个参数校验,如果 seckillActivityId 或 combinationActivityId 或 combinationHeadId 的情况,items 应该只有一个 + @Data @Schema(description = "用户 App - 商品项") @Valid diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index d5b9546d0..4688ca9ef 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -56,6 +56,7 @@ public interface TradeOrderConvert { @Mappings({ @Mapping(target = "id", ignore = true), + @Mapping(source = "userId", target = "userId"), @Mapping(source = "createReqVO.couponId", target = "couponId"), @Mapping(target = "remark", ignore = true), @Mapping(source = "createReqVO.remark", target = "userRemark"), @@ -89,22 +90,15 @@ public interface TradeOrderConvert { TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item); default ProductSkuUpdateStockReqDTO convert(List list) { - return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list)); - } - - default ProductSkuUpdateStockReqDTO convertNegative(List list) { - List items = TradeOrderConvert.INSTANCE.convertList(list); - items.forEach(item -> item.setIncrCount(-item.getIncrCount())); + List items = CollectionUtils.convertList(list, item -> + new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount())); + return new ProductSkuUpdateStockReqDTO(items); + } + default ProductSkuUpdateStockReqDTO convertNegative(List list) { + List items = CollectionUtils.convertList(list, item -> + new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount())); return new ProductSkuUpdateStockReqDTO(items); } - - List convertList(List list); - - @Mappings({ - @Mapping(source = "skuId", target = "id"), - @Mapping(source = "count", target = "incrCount"), - }) - ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean); default PayOrderCreateReqDTO convert(TradeOrderDO order, List orderItems, TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) { @@ -218,8 +212,9 @@ public interface TradeOrderConvert { default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, List cartList) { - TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO(); - reqBO.setUserId(userId).setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId()) + TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO().setUserId(userId) + .setCouponId(settlementReqVO.getCouponId()).setPointStatus(settlementReqVO.getPointStatus()) + .setDeliveryType(settlementReqVO.getDeliveryType()).setAddressId(settlementReqVO.getAddressId()) .setItems(new ArrayList<>(settlementReqVO.getItems().size())); // 商品项的构建 Map cartMap = convertMap(cartList, CartDO::getId); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index 9d8133ef2..bcf50c6d3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -251,12 +251,19 @@ public class TradeOrderDO extends BaseDO { * 对应 taobao 的 trade.coupon_fee 字段 */ private Integer couponPrice; - // TODO 芋艿:需要记录使用的积分; + /** + * 使用的积分 + */ + private Integer usePoint; /** * 积分抵扣的金额,单位:分 * * 对应 taobao 的 trade.point_fee 字段 */ private Integer pointPrice; +// /** +// * 奖励的积分 TODO 疯狂:可以使用这个字段哈; +// */ +// private Integer rewardPoint; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index 102418260..8f3bff38b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -47,6 +47,7 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.*; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService; import cn.iocoder.yudao.module.trade.service.cart.CartService; @@ -182,32 +183,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @Override @Transactional(rollbackFor = Exception.class) + @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE) public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { - // 1、执行订单创建前置处理器 - // TODO @puhui999:最好也抽个 beforeOrderCreate 方法;不要 BO 各自处理参数岂不美哉? - TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO); - beforeOrderCreateReqBO.setOrderType(validateActivity(createReqVO)); - beforeOrderCreateReqBO.setUserId(userId); - beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum)); - // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等 - tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO)); - - // 2. 价格计算 + // 0. 价格计算 TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO); + // 1. 订单创建前的逻辑 + beforeCreateTradeOrder(userId, createReqVO, calculateRespBO); + // 2.1 插入 TradeOrderDO 订单 TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO); // 2.2 插入 TradeOrderItemDO 订单项 List orderItems = createTradeOrderItems(order, calculateRespBO); - // 3. 订单创建完后的逻辑 + // 3. 订单创建后的逻辑 afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO); - - // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! return order; } - // TODO @puhui999:订单超时,自动取消; /** @@ -234,9 +227,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { address = validateAddress(userId, createReqVO.getAddressId()); } TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address); - String no = orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX); - order.setType(validateActivity(createReqVO)); - order.setNo(no); + order.setType(calculateRespBO.getType()); + order.setNo(orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX)); order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum)); @@ -252,71 +244,80 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { return order; } - /** - * 校验活动,并返回订单类型 - * - * @param createReqVO 请求参数 - * @return 订单类型 - */ - private Integer validateActivity(AppTradeOrderCreateReqVO createReqVO) { - if (createReqVO.getSeckillActivityId() != null) { - return TradeOrderTypeEnum.SECKILL.getType(); - } - if (createReqVO.getCombinationActivityId() != null) { - return TradeOrderTypeEnum.COMBINATION.getType(); - } - // TODO 砍价敬请期待 - return TradeOrderTypeEnum.NORMAL.getType(); - } - - private List createTradeOrderItems(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) { + private List createTradeOrderItems(TradeOrderDO tradeOrderDO, + TradePriceCalculateRespBO calculateRespBO) { List orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO); tradeOrderItemMapper.insertBatch(orderItems); return orderItems; } /** - * 执行创建完创建完订单后的逻辑 + * 订单创建前,执行前置逻辑 + * + * @param userId 用户编号 + * @param createReqVO 创建订单请求 + * @param calculateRespBO 订单价格计算结果 + */ + private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, + TradePriceCalculateRespBO calculateRespBO) { + // 1. 执行订单创建前置处理器 + TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO); + beforeOrderCreateReqBO.setOrderType(calculateRespBO.getType()); + beforeOrderCreateReqBO.setUserId(userId); + beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum)); + // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等 + tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO)); + + // 2. 下单时扣减商品库存 + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(createReqVO.getItems())); + } + + /** + * 订单创建后,执行后置逻辑 * * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 * * @param userId 用户编号 * @param createReqVO 创建订单请求 - * @param tradeOrderDO 交易订单 + * @param order 交易订单 * @param calculateRespBO 订单价格计算结果 */ private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, - TradeOrderDO tradeOrderDO, List orderItems, + TradeOrderDO order, List orderItems, TradePriceCalculateRespBO calculateRespBO) { - // 执行订单创建后置处理器 - tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(TradeOrderConvert.INSTANCE.convert(userId, createReqVO, tradeOrderDO, orderItems.get(0)))); + // 1. 执行订单创建后置处理器 + // TODO @puhui999:从通用性来说,应该不用 orderItems.get(0) + tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate( + TradeOrderConvert.INSTANCE.convert(userId, createReqVO, order, orderItems.get(0)))); - // 扣减积分 TODO 芋艿:待实现,需要前置; - // 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣 - - // 有使用优惠券时更新 TODO 芋艿:需要前置; + // 2. 有使用优惠券时更新 + // 不在前置扣减的原因,是因为优惠劵要记录使用的订单号 if (createReqVO.getCouponId() != null) { couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId) - .setOrderId(tradeOrderDO.getId())); + .setOrderId(order.getId())); } - // 下单时扣减商品库存 - productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems)); + // 3. 扣减积分 + // 不在前置扣减的原因,是因为积分扣减时,需要记录关联业务 + if (order.getUsePoint() != null && order.getUsePoint() > 0) { + memberPointApi.reducePoint(userId, calculateRespBO.getUsePoint(), + MemberPointBizTypeEnum.ORDER_USE.getType(), String.valueOf(order.getId())); + } - // 删除购物车商品 + // 4. 删除购物车商品 Set cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); if (CollUtil.isNotEmpty(cartIds)) { cartService.deleteCart(userId, cartIds); } - // 生成预支付 - createPayOrder(tradeOrderDO, orderItems, calculateRespBO); + // 5. 生成预支付 + createPayOrder(order, orderItems, calculateRespBO); - // 增加订单日志 TODO 芋艿:待实现 + // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! } - - private void createPayOrder(TradeOrderDO order, List orderItems, TradePriceCalculateRespBO calculateRespBO) { + private void createPayOrder(TradeOrderDO order, List orderItems, + TradePriceCalculateRespBO calculateRespBO) { // 创建支付单,用于后续的支付 PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert( order, orderItems, calculateRespBO, tradeOrderProperties); @@ -344,6 +345,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { } // 校验活动 // 1、拼团活动 + // TODO @puhui999:这块也抽象到 handler 里 if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录 combinationRecordApi.updateRecordStatusToInProgress(order.getUserId(), order.getId(), LocalDateTime.now()); @@ -741,6 +743,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { couponApi.returnUsedCoupon(order.getCouponId()); // 4.回滚积分:积分是支付成功后才增加的吧? 回复:每个项目不同,目前看下来,确认收货貌似更合适,我再看看其它项目的业务选择; + // TODO @疯狂:有赞是可配置(支付 or 确认收货),我们按照支付好列;然后这里的退积分,指的是下单时的积分抵扣。 // TODO 芋艿:OrderLog @@ -773,17 +776,18 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @Async protected void addUserPointAsync(Long userId, Integer payPrice, Long orderId) { - int bizType = MemberPointBizTypeEnum.ORDER_BUY.getType(); + // TODO @疯狂:具体多少积分,需要分成 2 不分:1. 支付金额;2. 商品金额 + int bizType = MemberPointBizTypeEnum.ORDER_REWARD.getType(); memberPointApi.addPoint(userId, payPrice, bizType, String.valueOf(orderId)); } @Async protected void reduceUserPointAsync(Long userId, Integer refundPrice, Long afterSaleId) { + // TODO @疯狂:退款时,按照金额比例,退还积分;https://help.youzan.com/displaylist/detail_4_4-1-49185 int bizType = MemberPointBizTypeEnum.ORDER_CANCEL.getType(); memberPointApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId)); } - @Async protected void addBrokerageAsync(Long userId, Long orderId) { MemberUserRespDTO user = memberUserApi.getUser(userId); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java index ad777b380..42a2f8139 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java @@ -37,6 +37,11 @@ public class TradeCombinationHandler implements TradeOrderHandler { @Override public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) { + // TODO @puhui999:需要判断下; + if (true) { + return; + } + // 创建砍价记录 combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO)); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java index ff5faea26..67019a49a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.trade.service.price.bo; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import lombok.Data; import javax.validation.Valid; @@ -17,13 +16,6 @@ import java.util.List; @Data public class TradePriceCalculateReqBO { - /** - * 订单类型 - * - * 枚举 {@link TradeOrderTypeEnum} - */ - private Integer type; - /** * 用户编号 * @@ -37,13 +29,12 @@ public class TradePriceCalculateReqBO { * 对应 CouponDO 的 id 编号 */ private Long couponId; - + // TODO @疯狂:需要增加一个 PriceCalculator 实现积分扣减的计算;写回到 TradePriceCalculateRespBO 的 usePoint /** - * 收货地址编号 - * - * 对应 MemberAddressDO 的 id 编号 + * 是否使用积分 */ - private Long addressId; + @NotNull(message = "是否使用积分不能为空") + private Boolean pointStatus; /** * 配送方式 @@ -51,6 +42,18 @@ public class TradePriceCalculateReqBO { * 枚举 {@link DeliveryTypeEnum} */ private Integer deliveryType; + /** + * 收货地址编号 + * + * 对应 MemberAddressDO 的 id 编号 + */ + private Long addressId; + /** + * 自提门店编号 + * + * 对应 PickUpStoreDO 的 id 编号 + */ + private Long pickUpStoreId; /** * 商品 SKU 数组 @@ -58,6 +61,30 @@ public class TradePriceCalculateReqBO { @NotNull(message = "商品数组不能为空") private List items; + // ========== 秒杀活动相关字段 ========== + /** + * 秒杀活动编号 + */ + private Long seckillActivityId; + + // ========== 拼团活动相关字段 ========== + // TODO @puhui999:是不是拼团记录的编号哈? + /** + * 拼团活动编号 + */ + private Long combinationActivityId; + + /** + * 拼团团长编号 + */ + private Long combinationHeadId; + + // ========== 砍价活动相关字段 ========== + /** + * 砍价活动编号 + */ + private Long bargainActivityId; + /** * 商品 SKU */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java index 76fb68c1f..1171cd8f2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -48,6 +48,11 @@ public class TradePriceCalculateRespBO { */ private Long couponId; + /** + * 使用的积分 + */ + private Integer usePoint; + /** * 订单价格 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index 5454c450d..7c395dbbf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.module.member.api.address.AddressApi; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService; import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; @@ -22,8 +25,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.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; /** * 运费的 {@link TradePriceCalculator} 实现类 @@ -37,20 +39,41 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { @Resource private AddressApi addressApi; + + @Resource + private DeliveryPickUpStoreService deliveryPickUpStoreService; @Resource private DeliveryExpressTemplateService deliveryExpressTemplateService; @Override public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { - // TODO @芋艿:如果门店自提,需要校验是否开启; - // 1.1 判断配送方式 - if (param.getDeliveryType() == null || DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) { + if (param.getDeliveryType() == null) { return; } - if (param.getAddressId() == null) { - throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY); + if (DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) { + calculateByPickUp(param, result); + } else if (DeliveryTypeEnum.EXPRESS.getMode().equals(param.getDeliveryType())) { + calculateExpress(param, result); + } + } + + private void calculateByPickUp(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + if (param.getPickUpStoreId() == null) { + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_PICK_UP_STORE_IS_EMPTY); + } + DeliveryPickUpStoreDO pickUpStore = deliveryPickUpStoreService.getDeliveryPickUpStore(param.getPickUpStoreId()); + if (pickUpStore == null || CommonStatusEnum.DISABLE.getStatus().equals(pickUpStore.getStatus())) { + throw exception(PICK_UP_STORE_NOT_EXISTS); + } + } + + // ========= 快递发货 ========== + + private void calculateExpress(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 1. 得到收件地址区域 + if (param.getAddressId() == null) { + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDRESS_IS_EMPTY); } - // 1.2 得到收件地址区域 AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId()); @@ -89,8 +112,12 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { for (OrderItem orderItem : orderItems) { totalCount += orderItem.getCount(); totalPrice += orderItem.getPayPrice(); - totalWeight += totalWeight + orderItem.getWeight() * orderItem.getCount(); - totalVolume += totalVolume + orderItem.getVolume() * orderItem.getCount(); + if (orderItem.getWeight() != null) { + totalWeight += totalWeight + orderItem.getWeight() * orderItem.getCount(); + } + if (orderItem.getVolume() != null) { + totalVolume += totalVolume + orderItem.getVolume() * orderItem.getCount(); + } } // 优先判断是否包邮. 如果包邮不计算快递运费 if (isExpressFree(templateBO.getChargeMode(), totalCount, totalWeight, diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java new file mode 100644 index 000000000..6bd479802 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +/** + * 使用积分的 {@link TradePriceCalculator} 实现类 + * + * @author owen + */ +@Component +@Order(TradePriceCalculator.ORDER_POINT_USE) +@Slf4j +public class TradePointUsePriceCalculator implements TradePriceCalculator { + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // TODO 疯狂:待实现,嘿嘿; + if (param.getPointStatus()) { + result.setUsePoint(10); + } else { + result.setUsePoint(0); + } + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java index 92ae9c2ee..cddc1ea21 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java @@ -6,6 +6,9 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; /** * 价格计算的计算器接口 * + * 优惠计算顺序: + * 1. 积分抵现、会员价、优惠券、粉丝专享价、满减送哪个优先计算? + * * @author 芋道源码 */ public interface TradePriceCalculator { @@ -13,12 +16,13 @@ public interface TradePriceCalculator { int ORDER_DISCOUNT_ACTIVITY = 10; int ORDER_REWARD_ACTIVITY = 20; int ORDER_COUPON = 30; + int ORDER_POINT_USE = 40; /** * 快递运费的计算 * * 放在各种营销活动、优惠劵后面 TODO */ - int ORDER_DELIVERY = 40; + int ORDER_DELIVERY = 50; void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java index bd3d3b5be..b8b9e0fb9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -4,6 +4,7 @@ import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; @@ -28,7 +29,7 @@ public class TradePriceCalculatorHelper { List spuList, List skuList) { // 创建 PriceCalculateRespDTO 对象 TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); - result.setType(param.getType()); + result.setType(getOrderType(param)); result.setPromotions(new ArrayList<>()); // 创建它的 OrderItem 属性 @@ -69,6 +70,23 @@ public class TradePriceCalculatorHelper { return result; } + /** + * 计算订单类型 + * + * @param param 计算参数 + * @return 订单类型 + */ + private static Integer getOrderType(TradePriceCalculateReqBO param) { + if (param.getSeckillActivityId() != null) { + return TradeOrderTypeEnum.SECKILL.getType(); + } + if (param.getCombinationActivityId() != null) { + return TradeOrderTypeEnum.COMBINATION.getType(); + } + // TODO 砍价敬请期待 + return TradeOrderTypeEnum.NORMAL.getType(); + } + /** * 基于订单项,重新计算 price 总价 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java index 473e3920e..b998f87b1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java @@ -45,7 +45,7 @@ public class TradePriceServiceImplTest extends BaseMockitoUnitTest { public void testCalculatePrice() { // 准备参数 TradePriceCalculateReqBO calculateReqBO = new TradePriceCalculateReqBO() - .setType(TradeOrderTypeEnum.NORMAL.getType()).setUserId(10L) + .setUserId(10L) .setCouponId(20L).setAddressId(30L) .setItems(Arrays.asList( new TradePriceCalculateReqBO.Item().setSkuId(100L).setCount(1).setSelected(true), diff --git a/yudao-module-member/yudao-module-member-api/pom.xml b/yudao-module-member/yudao-module-member-api/pom.xml index 961bfb656..1f60cd0fc 100644 --- a/yudao-module-member/yudao-module-member-api/pom.xml +++ b/yudao-module-member/yudao-module-member-api/pom.xml @@ -21,6 +21,13 @@ cn.iocoder.boot yudao-common + + + + org.springframework.boot + spring-boot-starter-validation + true + diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java index 5181211f2..3eb749fb6 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.member.api.point; import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; +import javax.validation.constraints.Min; + /** * 用户积分的 API 接口 * @@ -17,6 +19,18 @@ public interface MemberPointApi { * @param bizType 业务类型 {@link MemberPointBizTypeEnum} * @param bizId 业务编号 */ - void addPoint(Long userId, Integer point, Integer bizType, String bizId); + void addPoint(Long userId, @Min(value = 1L, message = "积分必须是正数") Integer point, + Integer bizType, String bizId); + + /** + * 减少用户积分 + * + * @param userId 用户编号 + * @param point 积分 + * @param bizType 业务类型 {@link MemberPointBizTypeEnum} + * @param bizId 业务编号 + */ + void reducePoint(Long userId, @Min(value = 1L, message = "积分必须是正数") Integer point, + Integer bizType, String bizId); } diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java index 3d314a4a2..fe76cdb52 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java @@ -17,8 +17,10 @@ import java.util.Objects; public enum MemberPointBizTypeEnum implements IntArrayValuable { SIGN(1, "签到", "签到获得 {} 积分", true), - ORDER_BUY(10, "订单消费", "下单获得 {} 积分", true), - ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false); // 退回积分 + ORDER_REWARD(10, "订单奖励", "下单获得 {} 积分", true), + ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false), // 退回积分 + ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 扣减积分 + ; /** * 类型 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java index 81eec0782..ee407eaf6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java @@ -31,4 +31,13 @@ public class MemberPointApiImpl implements MemberPointApi { memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId); } + @Override + public void reducePoint(Long userId, Integer point, Integer bizType, String bizId) { + MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType); + if (bizTypeEnum == null) { + throw exception(POINT_RECORD_BIZ_NOT_SUPPORT); + } + memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId); + } + }