Commit f7fe9ad7b0c19f2c2fc12bc518b34ee991ac5283
1 parent
da162853
1. 商城:调整购物车的失效逻辑实现,基于 SPU 是否下架
2. 商城:增加购物车失效的重选逻辑
Showing
11 changed files
with
103 additions
and
56 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java
| 1 | package cn.iocoder.yudao.module.product.api.sku.dto; | 1 | package cn.iocoder.yudao.module.product.api.sku.dto; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 4 | import lombok.Data; | 3 | import lombok.Data; |
| 5 | 4 | ||
| 6 | import java.util.List; | 5 | import java.util.List; |
| @@ -22,10 +21,6 @@ public class ProductSkuRespDTO { | @@ -22,10 +21,6 @@ public class ProductSkuRespDTO { | ||
| 22 | * SPU 编号 | 21 | * SPU 编号 |
| 23 | */ | 22 | */ |
| 24 | private Long spuId; | 23 | private Long spuId; |
| 25 | - /** | ||
| 26 | - * SPU 名字 | ||
| 27 | - */ | ||
| 28 | - private String spuName; | ||
| 29 | 24 | ||
| 30 | /** | 25 | /** |
| 31 | * 属性数组 | 26 | * 属性数组 |
| @@ -52,12 +47,6 @@ public class ProductSkuRespDTO { | @@ -52,12 +47,6 @@ public class ProductSkuRespDTO { | ||
| 52 | */ | 47 | */ |
| 53 | private String picUrl; | 48 | private String picUrl; |
| 54 | /** | 49 | /** |
| 55 | - * SKU 状态 | ||
| 56 | - * <p> | ||
| 57 | - * 枚举 {@link CommonStatusEnum} | ||
| 58 | - */ | ||
| 59 | - private Integer status; | ||
| 60 | - /** | ||
| 61 | * 库存 | 50 | * 库存 |
| 62 | */ | 51 | */ |
| 63 | private Integer stock; | 52 | private Integer stock; |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
| @@ -14,7 +14,6 @@ public interface ErrorCodeConstants { | @@ -14,7 +14,6 @@ public interface ErrorCodeConstants { | ||
| 14 | // ========== Order 模块 1-011-000-000 ========== | 14 | // ========== Order 模块 1-011-000-000 ========== |
| 15 | ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在"); | 15 | ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在"); |
| 16 | ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖"); | 16 | ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖"); |
| 17 | - ErrorCode ORDER_CREATE_SKU_NOT_SALE = new ErrorCode(1011000003, "商品 SKU 不可售卖"); | ||
| 18 | ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足"); | 17 | ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足"); |
| 19 | ErrorCode ORDER_CREATE_SPU_NOT_FOUND = new ErrorCode(1011000005, "商品 SPU 不可售卖"); | 18 | ErrorCode ORDER_CREATE_SPU_NOT_FOUND = new ErrorCode(1011000005, "商品 SPU 不可售卖"); |
| 20 | ErrorCode ORDER_CREATE_ADDRESS_NOT_FOUND = new ErrorCode(1011000006, "收货地址不存在"); | 19 | ErrorCode ORDER_CREATE_ADDRESS_NOT_FOUND = new ErrorCode(1011000006, "收货地址不存在"); |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java
| @@ -17,12 +17,12 @@ public class AppProductSkuBaseRespVO { | @@ -17,12 +17,12 @@ public class AppProductSkuBaseRespVO { | ||
| 17 | @Schema(description = "主键", required = true, example = "1024") | 17 | @Schema(description = "主键", required = true, example = "1024") |
| 18 | private Long id; | 18 | private Long id; |
| 19 | 19 | ||
| 20 | - @Schema(description = "商品 SKU 名字", required = true, example = "芋道") | ||
| 21 | - private String name; | ||
| 22 | - | ||
| 23 | @Schema(description = "图片地址", example = "https://www.iocoder.cn/xx.png") | 20 | @Schema(description = "图片地址", example = "https://www.iocoder.cn/xx.png") |
| 24 | private String picUrl; | 21 | private String picUrl; |
| 25 | 22 | ||
| 23 | + @Schema(description = "销售价格,单位:分", required = true, example = "100") | ||
| 24 | + private Integer price; | ||
| 25 | + | ||
| 26 | @Schema(description = "库存", required = true, example = "1") | 26 | @Schema(description = "库存", required = true, example = "1") |
| 27 | private Integer stock; | 27 | private Integer stock; |
| 28 | 28 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 4 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | 4 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; |
| 5 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; | 5 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; |
| 6 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; | 6 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; |
| 7 | +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; | ||
| 7 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; | 8 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; |
| 8 | import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; | 9 | import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; |
| 9 | import io.swagger.v3.oas.annotations.Operation; | 10 | import io.swagger.v3.oas.annotations.Operation; |
| @@ -42,11 +43,19 @@ public class TradeCartController { | @@ -42,11 +43,19 @@ public class TradeCartController { | ||
| 42 | @PutMapping("/update") | 43 | @PutMapping("/update") |
| 43 | @Operation(summary = "更新购物车商品") | 44 | @Operation(summary = "更新购物车商品") |
| 44 | @PreAuthenticated | 45 | @PreAuthenticated |
| 45 | - public CommonResult<Boolean> updateCartItemQuantity(@Valid @RequestBody AppTradeCartUpdateReqVO updateReqVO) { | 46 | + public CommonResult<Boolean> updateCart(@Valid @RequestBody AppTradeCartUpdateReqVO updateReqVO) { |
| 46 | cartService.updateCart(getLoginUserId(), updateReqVO); | 47 | cartService.updateCart(getLoginUserId(), updateReqVO); |
| 47 | return success(true); | 48 | return success(true); |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 51 | + @PutMapping("/reset") | ||
| 52 | + @Operation(summary = "重置购物车商品") | ||
| 53 | + @PreAuthenticated | ||
| 54 | + public CommonResult<Boolean> resetCart(@Valid @RequestBody AppTradeCartResetReqVO updateReqVO) { | ||
| 55 | + cartService.resetCart(getLoginUserId(), updateReqVO); | ||
| 56 | + return success(true); | ||
| 57 | + } | ||
| 58 | + | ||
| 50 | @DeleteMapping("/delete") | 59 | @DeleteMapping("/delete") |
| 51 | @Operation(summary = "删除购物车商品") | 60 | @Operation(summary = "删除购物车商品") |
| 52 | @Parameter(name = "ids", description = "购物车商品编号", required = true, example = "1024,2048") | 61 | @Parameter(name = "ids", description = "购物车商品编号", required = true, example = "1024,2048") |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.trade.controller.app.cart.vo; | ||
| 2 | - | ||
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | -import lombok.Data; | ||
| 5 | - | ||
| 6 | -import javax.validation.constraints.NotNull; | ||
| 7 | -import java.util.Collection; | ||
| 8 | - | ||
| 9 | -@Schema(description = "用户 App - 购物车更新是否选中 Request VO") | ||
| 10 | -@Data | ||
| 11 | -public class AppTradeCartItemUpdateSelectedReqVO { | ||
| 12 | - | ||
| 13 | - @Schema(description = "商品 SKU 编号列表", required = true, example = "1024,2048") | ||
| 14 | - @NotNull(message = "商品 SKU 编号列表不能为空") | ||
| 15 | - private Collection<Long> skuIds; | ||
| 16 | - | ||
| 17 | - @Schema(description = "是否选中", required = true, example = "true") | ||
| 18 | - @NotNull(message = "是否选中不能为空") | ||
| 19 | - private Boolean selected; | ||
| 20 | - | ||
| 21 | -} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartResetReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.app.cart.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import javax.validation.constraints.Min; | ||
| 7 | +import javax.validation.constraints.NotNull; | ||
| 8 | + | ||
| 9 | +@Schema(description = "用户 App - 购物车重置 Request VO") | ||
| 10 | +@Data | ||
| 11 | +public class AppTradeCartResetReqVO { | ||
| 12 | + | ||
| 13 | + @Schema(description = "编号", required = true, example = "1024") | ||
| 14 | + @NotNull(message = "编号不能为空") | ||
| 15 | + private Long id; | ||
| 16 | + | ||
| 17 | + @Schema(description = "商品 SKU 编号", required = true,example = "1024") | ||
| 18 | + @NotNull(message = "商品 SKU 编号不能为空") | ||
| 19 | + private Long skuId; | ||
| 20 | + | ||
| 21 | + @Schema(description = "商品数量", required = true, example = "1") | ||
| 22 | + @NotNull(message = "数量不能为空") | ||
| 23 | + @Min(message = "数量必须大于 0", value = 1L) | ||
| 24 | + private Integer count; | ||
| 25 | + | ||
| 26 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java
| @@ -34,17 +34,17 @@ public interface TradeCartConvert { | @@ -34,17 +34,17 @@ public interface TradeCartConvert { | ||
| 34 | ProductSpuRespDTO spu = spuMap.get(cart.getSpuId()); | 34 | ProductSpuRespDTO spu = spuMap.get(cart.getSpuId()); |
| 35 | ProductSkuRespDTO sku = skuMap.get(cart.getSkuId()); | 35 | ProductSkuRespDTO sku = skuMap.get(cart.getSkuId()); |
| 36 | cartVO.setSpu(convert(spu)).setSku(convert(sku)); | 36 | cartVO.setSpu(convert(spu)).setSku(convert(sku)); |
| 37 | - // 如果 spu 或 sku 不存在,或者 spu 被禁用,说明是非法的,或者 sku 库存不足 | 37 | + // 如果 SPU 不存在,或者下架,或者库存不足,说明是无效的 |
| 38 | if (spu == null | 38 | if (spu == null |
| 39 | - || sku == null | ||
| 40 | || !ProductSpuStatusEnum.isEnable(spu.getStatus()) | 39 | || !ProductSpuStatusEnum.isEnable(spu.getStatus()) |
| 41 | - || sku.getStock() <= 0) { | 40 | + || spu.getStock() <= 0) { |
| 42 | invalidList.add(cartVO); | 41 | invalidList.add(cartVO); |
| 43 | } else { | 42 | } else { |
| 43 | + // 虽然 SKU 可能也会不存在,但是可以通过购物车重新选择 | ||
| 44 | validList.add(cartVO); | 44 | validList.add(cartVO); |
| 45 | } | 45 | } |
| 46 | }); | 46 | }); |
| 47 | - return new AppTradeCartListRespVO().setValidList(validList).setValidList(invalidList); | 47 | + return new AppTradeCartListRespVO().setValidList(validList).setInvalidList(invalidList); |
| 48 | } | 48 | } |
| 49 | AppProductSpuBaseRespVO convert(ProductSpuRespDTO spu); | 49 | AppProductSpuBaseRespVO convert(ProductSpuRespDTO spu); |
| 50 | AppProductSkuBaseRespVO convert(ProductSkuRespDTO sku); | 50 | AppProductSkuBaseRespVO convert(ProductSkuRespDTO sku); |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java
| @@ -45,8 +45,11 @@ public interface TradeCartMapper extends BaseMapperX<TradeCartDO> { | @@ -45,8 +45,11 @@ public interface TradeCartMapper extends BaseMapperX<TradeCartDO> { | ||
| 45 | .eq(TradeCartDO::getUserId, userId)); | 45 | .eq(TradeCartDO::getUserId, userId)); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | - default List<TradeCartDO> selectListByUserId(Long userId) { | ||
| 49 | - return selectList(TradeCartDO::getUserId, userId); | 48 | + default List<TradeCartDO> selectListByUserId(Long userId, Boolean addStatus, Boolean orderStatus) { |
| 49 | + return selectList(new LambdaQueryWrapper<TradeCartDO>() | ||
| 50 | + .eq(TradeCartDO::getUserId, userId) | ||
| 51 | + .eq(TradeCartDO::getAddStatus, addStatus) | ||
| 52 | + .eq(TradeCartDO::getOrderStatus, orderStatus)); | ||
| 50 | } | 53 | } |
| 51 | 54 | ||
| 52 | default void updateByIds(Collection<Long> ids, TradeCartDO updateObject) { | 55 | default void updateByIds(Collection<Long> ids, TradeCartDO updateObject) { |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java
| 1 | package cn.iocoder.yudao.module.trade.service.cart; | 1 | package cn.iocoder.yudao.module.trade.service.cart; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; | ||
| 4 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; | 3 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; |
| 4 | +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; | ||
| 5 | +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; | ||
| 5 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; | 6 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; |
| 6 | 7 | ||
| 7 | import javax.validation.Valid; | 8 | import javax.validation.Valid; |
| @@ -32,6 +33,16 @@ public interface TradeCartService { | @@ -32,6 +33,16 @@ public interface TradeCartService { | ||
| 32 | void updateCart(Long userId, AppTradeCartUpdateReqVO updateCountReqVO); | 33 | void updateCart(Long userId, AppTradeCartUpdateReqVO updateCountReqVO); |
| 33 | 34 | ||
| 34 | /** | 35 | /** |
| 36 | + * 重置购物车商品 | ||
| 37 | + * | ||
| 38 | + * 使用场景:在一个购物车项对应的商品失效(例如说 SPU 被下架),可以重新选择对应的 SKU | ||
| 39 | + * | ||
| 40 | + * @param userId 用户编号 | ||
| 41 | + * @param updateReqVO 重置信息 | ||
| 42 | + */ | ||
| 43 | + void resetCart(Long userId, AppTradeCartResetReqVO updateReqVO); | ||
| 44 | + | ||
| 45 | + /** | ||
| 35 | * 删除购物车商品 | 46 | * 删除购物车商品 |
| 36 | * | 47 | * |
| 37 | * @param userId 用户编号 | 48 | * @param userId 用户编号 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java
| 1 | package cn.iocoder.yudao.module.trade.service.cart; | 1 | package cn.iocoder.yudao.module.trade.service.cart; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 5 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | 4 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 6 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 5 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 7 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | 6 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| 8 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | 7 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 9 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; | 8 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; |
| 10 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; | 9 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; |
| 10 | +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; | ||
| 11 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; | 11 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; |
| 12 | import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert; | 12 | import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert; |
| 13 | import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | 13 | import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; |
| 14 | import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartMapper; | 14 | import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartMapper; |
| 15 | import org.springframework.stereotype.Service; | 15 | import org.springframework.stereotype.Service; |
| 16 | +import org.springframework.transaction.annotation.Transactional; | ||
| 16 | import org.springframework.validation.annotation.Validated; | 17 | import org.springframework.validation.annotation.Validated; |
| 17 | 18 | ||
| 18 | import javax.annotation.Resource; | 19 | import javax.annotation.Resource; |
| @@ -86,6 +87,28 @@ public class TradeCartServiceImpl implements TradeCartService { | @@ -86,6 +87,28 @@ public class TradeCartServiceImpl implements TradeCartService { | ||
| 86 | .setCount(updateReqVO.getCount())); | 87 | .setCount(updateReqVO.getCount())); |
| 87 | } | 88 | } |
| 88 | 89 | ||
| 90 | + @Override | ||
| 91 | + @Transactional(rollbackFor = Exception.class) | ||
| 92 | + public void resetCart(Long userId, AppTradeCartResetReqVO resetReqVO) { | ||
| 93 | + // 第一步:删除原本的购物项 | ||
| 94 | + TradeCartDO oldCart = cartMapper.selectById(resetReqVO.getId(), userId); | ||
| 95 | + if (oldCart == null) { | ||
| 96 | + throw exception(CARD_ITEM_NOT_FOUND); | ||
| 97 | + } | ||
| 98 | + cartMapper.deleteById(oldCart.getId()); | ||
| 99 | + | ||
| 100 | + // 第二步:添加新的购物项 | ||
| 101 | + TradeCartDO newCart = cartMapper.selectByUserIdAndSkuId(userId, resetReqVO.getSkuId(), | ||
| 102 | + true, false); | ||
| 103 | + if (newCart != null) { | ||
| 104 | + updateCart(userId, new AppTradeCartUpdateReqVO() | ||
| 105 | + .setId(newCart.getId()).setCount(resetReqVO.getCount())); | ||
| 106 | + } else { | ||
| 107 | + addCart(userId, new AppTradeCartAddReqVO().setAddStatus(true) | ||
| 108 | + .setSkuId(resetReqVO.getSkuId()).setCount(resetReqVO.getCount())); | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + | ||
| 89 | /** | 112 | /** |
| 90 | * 购物车删除商品 | 113 | * 购物车删除商品 |
| 91 | * | 114 | * |
| @@ -111,8 +134,8 @@ public class TradeCartServiceImpl implements TradeCartService { | @@ -111,8 +134,8 @@ public class TradeCartServiceImpl implements TradeCartService { | ||
| 111 | 134 | ||
| 112 | @Override | 135 | @Override |
| 113 | public AppTradeCartListRespVO getCartList(Long userId) { | 136 | public AppTradeCartListRespVO getCartList(Long userId) { |
| 114 | - // 获得购物车的商品 | ||
| 115 | - List<TradeCartDO> carts = cartMapper.selectListByUserId(userId); | 137 | + // 获得购物车的商品,只查询未下单的 |
| 138 | + List<TradeCartDO> carts = cartMapper.selectListByUserId(userId, true, false); | ||
| 116 | carts.sort(Comparator.comparing(TradeCartDO::getId).reversed()); | 139 | carts.sort(Comparator.comparing(TradeCartDO::getId).reversed()); |
| 117 | // 如果未空,则返回空结果 | 140 | // 如果未空,则返回空结果 |
| 118 | if (CollUtil.isEmpty(carts)) { | 141 | if (CollUtil.isEmpty(carts)) { |
| @@ -122,12 +145,26 @@ public class TradeCartServiceImpl implements TradeCartService { | @@ -122,12 +145,26 @@ public class TradeCartServiceImpl implements TradeCartService { | ||
| 122 | 145 | ||
| 123 | // 查询 SPU、SKU 列表 | 146 | // 查询 SPU、SKU 列表 |
| 124 | List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(convertSet(carts, TradeCartDO::getSpuId)); | 147 | List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(convertSet(carts, TradeCartDO::getSpuId)); |
| 125 | - List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(convertSet(carts, TradeCartDO::getSpuId)); | 148 | + List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(convertSet(carts, TradeCartDO::getSkuId)); |
| 149 | + | ||
| 150 | + // 如果 SPU 被删除,则删除购物车对应的商品。延迟删除 | ||
| 151 | + deleteCartIfSpuDeleted(carts, spus); | ||
| 126 | 152 | ||
| 127 | // 拼接数据 | 153 | // 拼接数据 |
| 128 | return TradeCartConvert.INSTANCE.convertList(carts, spus, skus); | 154 | return TradeCartConvert.INSTANCE.convertList(carts, spus, skus); |
| 129 | } | 155 | } |
| 130 | 156 | ||
| 157 | + private void deleteCartIfSpuDeleted(List<TradeCartDO> carts, List<ProductSpuRespDTO> spus) { | ||
| 158 | + // 如果 SPU 被删除,则删除购物车对应的商品。延迟删除 | ||
| 159 | + carts.removeIf(cart -> { | ||
| 160 | + if (spus.stream().noneMatch(spu -> spu.getId().equals(cart.getSpuId()))) { | ||
| 161 | + cartMapper.deleteById(cart.getId()); | ||
| 162 | + return true; | ||
| 163 | + } | ||
| 164 | + return false; | ||
| 165 | + }); | ||
| 166 | + } | ||
| 167 | + | ||
| 131 | /** | 168 | /** |
| 132 | * 校验商品 SKU 是否合法 | 169 | * 校验商品 SKU 是否合法 |
| 133 | * 1. 是否存在 | 170 | * 1. 是否存在 |
| @@ -140,7 +177,7 @@ public class TradeCartServiceImpl implements TradeCartService { | @@ -140,7 +177,7 @@ public class TradeCartServiceImpl implements TradeCartService { | ||
| 140 | */ | 177 | */ |
| 141 | private ProductSkuRespDTO checkProductSku(Long skuId, Integer count) { | 178 | private ProductSkuRespDTO checkProductSku(Long skuId, Integer count) { |
| 142 | ProductSkuRespDTO sku = productSkuApi.getSku(skuId); | 179 | ProductSkuRespDTO sku = productSkuApi.getSku(skuId); |
| 143 | - if (sku == null || CommonStatusEnum.DISABLE.getStatus().equals(sku.getStatus())) { | 180 | + if (sku == null) { |
| 144 | throw exception(SKU_NOT_EXISTS); | 181 | throw exception(SKU_NOT_EXISTS); |
| 145 | } | 182 | } |
| 146 | if (count > sku.getStock()) { | 183 | if (count > sku.getStock()) { |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
| @@ -5,7 +5,6 @@ import cn.hutool.core.util.IdUtil; | @@ -5,7 +5,6 @@ import cn.hutool.core.util.IdUtil; | ||
| 5 | import cn.hutool.core.util.ObjectUtil; | 5 | import cn.hutool.core.util.ObjectUtil; |
| 6 | import cn.hutool.core.util.StrUtil; | 6 | import cn.hutool.core.util.StrUtil; |
| 7 | import cn.iocoder.yudao.framework.common.core.KeyValue; | 7 | import cn.iocoder.yudao.framework.common.core.KeyValue; |
| 8 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 9 | import cn.iocoder.yudao.framework.common.enums.TerminalEnum; | 8 | import cn.iocoder.yudao.framework.common.enums.TerminalEnum; |
| 10 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 11 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 10 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| @@ -125,15 +124,10 @@ public class TradeOrderServiceImpl implements TradeOrderService { | @@ -125,15 +124,10 @@ public class TradeOrderServiceImpl implements TradeOrderService { | ||
| 125 | if (items.size() != skus.size()) { | 124 | if (items.size() != skus.size()) { |
| 126 | throw exception(ORDER_CREATE_SKU_NOT_FOUND); | 125 | throw exception(ORDER_CREATE_SKU_NOT_FOUND); |
| 127 | } | 126 | } |
| 128 | - // 校验是否禁用 or 库存不足 | 127 | + // 校验库存不足 |
| 129 | Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId); | 128 | Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId); |
| 130 | items.forEach(item -> { | 129 | items.forEach(item -> { |
| 131 | ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); | 130 | ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); |
| 132 | - // SKU 禁用 | ||
| 133 | - if (ObjectUtil.notEqual(CommonStatusEnum.ENABLE.getStatus(), sku.getStatus())) { | ||
| 134 | - throw exception(ORDER_CREATE_SKU_NOT_SALE); | ||
| 135 | - } | ||
| 136 | - // SKU 库存不足 | ||
| 137 | if (item.getCount() > sku.getStock()) { | 131 | if (item.getCount() > sku.getStock()) { |
| 138 | throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); | 132 | throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); |
| 139 | } | 133 | } |