diff --git a/order-service-project/order-service-api/src/main/java/cn/iocoder/mall/orderservice/rpc/cart/dto/CartItemUpdateSelectedReqDTO.java b/order-service-project/order-service-api/src/main/java/cn/iocoder/mall/orderservice/rpc/cart/dto/CartItemUpdateSelectedReqDTO.java index 075be10e9..b1227c773 100644 --- a/order-service-project/order-service-api/src/main/java/cn/iocoder/mall/orderservice/rpc/cart/dto/CartItemUpdateSelectedReqDTO.java +++ b/order-service-project/order-service-api/src/main/java/cn/iocoder/mall/orderservice/rpc/cart/dto/CartItemUpdateSelectedReqDTO.java @@ -5,7 +5,7 @@ import lombok.experimental.Accessors; import javax.validation.constraints.NotNull; import java.io.Serializable; -import java.util.List; +import java.util.Collection; /** * 购物车更新是否选中 Request DTO @@ -23,7 +23,7 @@ public class CartItemUpdateSelectedReqDTO implements Serializable { * 商品 SKU 编号列表 */ @NotNull(message = "商品 SKU 编号列表不能为空") - private List skuIds; + private Collection skuIds; /** * 是否选中 */ diff --git a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/dal/mysql/mapper/cart/CartItemMapper.java b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/dal/mysql/mapper/cart/CartItemMapper.java index 6dbf2321a..361a5d286 100644 --- a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/dal/mysql/mapper/cart/CartItemMapper.java +++ b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/dal/mysql/mapper/cart/CartItemMapper.java @@ -43,7 +43,7 @@ public interface CartItemMapper extends BaseMapper { default List selectList(CartItemListQueryBO queryBO) { return selectList(new QueryWrapperX().eq("user_id", queryBO.getUserId()) - .eq("selected", queryBO.getSelected())); + .eqIfPresent("selected", queryBO.getSelected())); } } diff --git a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/service/cart/CartService.java b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/service/cart/CartService.java index bf78f2ba7..3d4470c15 100644 --- a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/service/cart/CartService.java +++ b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/service/cart/CartService.java @@ -13,6 +13,7 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.validation.Valid; +import java.util.Collection; import java.util.List; import static cn.iocoder.mall.orderservice.enums.OrderErrorCodeConstants.CARD_ITEM_NOT_FOUND; @@ -84,7 +85,7 @@ public class CartService { * @param skuIds 商品 SKU 编号数组 * @param selected 是否选中 */ - public void updateCartItemSelected(Integer userId, List skuIds, Boolean selected) { + public void updateCartItemSelected(Integer userId, Collection skuIds, Boolean selected) { // 查询 CartItemDO 列表 List itemDOs = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds); if (skuIds.size() != itemDOs.size()) { diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java index 4ca9d94c2..b5278b047 100644 --- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java +++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java @@ -17,44 +17,8 @@ public class UsersCartController { // private CouponService couponService; // -// -// @PostMapping("update_quantity") -// public CommonResult updateQuantity(@RequestParam("skuId") Integer skuId, // TODO 芋艿,先暂用这个 VO 。等促销活动出来后,做调整 -// @RequestParam("quantity") Integer quantity) { -// // 添加到购物车 -// cartService.updateQuantity(UserSecurityContextHolder.getContext().getUserId(), -// skuId, quantity); -// // 获得目前购物车明细 -// return getCartDetail(); -// } -// -// @PostMapping("update_selected") -// public CommonResult updateSelected(@RequestParam("skuIds") Set skuIds, // TODO 芋艿,先暂用这个 VO 。等促销活动出来后,做调整 -// @RequestParam("selected") Boolean selected) { -// // 添加到购物车 -// cartService.updateSelected(UserSecurityContextHolder.getContext().getUserId(), skuIds, selected); -// // 获得目前购物车明细 -// return getCartDetail(); -// } -// -// -// private CommonResult getCartDetail() { -// // 获得购物车中选中的 -// List cartItems = cartService.list(UserSecurityContextHolder.getContext().getUserId(), null); -// // 购物车为空时,构造空的 UsersOrderConfirmCreateVO 返回 -// if (cartItems.isEmpty()) { -// UsersCartDetailVO result = new UsersCartDetailVO(); -// result.setItemGroups(Collections.emptyList()); -// result.setFee(new UsersCartDetailVO.Fee(0, 0, 0, 0)); -// return success(result); -// } -// // 计算商品价格 -// CalcOrderPriceBO calcOrder = list0(cartItems, null); -// // 执行数据拼装 -// return success(CartConvert.INSTANCE.convert2(calcOrder)); -// } // // @GetMapping("/confirm_create_order") // public CommonResult getConfirmCreateOrder(@RequestParam(value = "couponCardId", required = false) Integer couponCardId) { diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcReqDTO.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcReqDTO.java index 279649173..6790fde72 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcReqDTO.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcReqDTO.java @@ -36,7 +36,7 @@ public class PriceProductCalcReqDTO implements Serializable { */ @Data @Accessors(chain = true) - public static class Item { + public static class Item implements Serializable { /** * SKU 编号 diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcRespDTO.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcRespDTO.java index ee2f314da..d6e9c71ec 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcRespDTO.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcRespDTO.java @@ -47,7 +47,7 @@ public class PriceProductCalcRespDTO implements Serializable { */ @Data @Accessors(chain = true) - public static class ItemGroup { + public static class ItemGroup implements Serializable { /** * 优惠活动 @@ -79,7 +79,7 @@ public class PriceProductCalcRespDTO implements Serializable { @Data @Accessors(chain = true) - public static class Item { + public static class Item implements Serializable { /** * 商品 SPU 编号 @@ -149,7 +149,7 @@ public class PriceProductCalcRespDTO implements Serializable { */ @Data @Accessors(chain = true) - public static class Fee { + public static class Fee implements Serializable { /** * 购买总价 @@ -188,7 +188,7 @@ public class PriceProductCalcRespDTO implements Serializable { */ @Data @Accessors(chain = true) - public static class Postage { + public static class Postage implements Serializable { /** * 需要满足多少钱,可以包邮。单位:分 diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java index 9d895a084..98b2d2fab 100644 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java @@ -80,9 +80,9 @@ public class PriceManager { int discountTotal = 0; int presentTotal = 0; for (PriceProductCalcRespDTO.ItemGroup itemGroup : calcRespDTO.getItemGroups()) { - buyTotal += itemGroup.getItems().stream().mapToInt(PriceProductCalcRespDTO.Item::getBuyTotal).sum(); - discountTotal += itemGroup.getItems().stream().mapToInt(PriceProductCalcRespDTO.Item::getDiscountTotal).sum(); - presentTotal += itemGroup.getItems().stream().mapToInt(PriceProductCalcRespDTO.Item::getPresentTotal).sum(); + buyTotal += itemGroup.getItems().stream().mapToInt(item -> item.getSelected() ? item.getBuyTotal() : 0).sum(); + discountTotal += itemGroup.getItems().stream().mapToInt(item -> item.getSelected() ? item.getDiscountTotal() : 0).sum(); + presentTotal += itemGroup.getItems().stream().mapToInt(item -> item.getSelected() ? item.getPresentTotal() : 0).sum(); } Assert.isTrue(buyTotal - discountTotal == presentTotal, String.format("价格合计( %d - %d == %d )不正确", buyTotal, discountTotal, presentTotal)); @@ -106,6 +106,7 @@ public class PriceManager { PriceProductCalcReqDTO.Item calcOrderItem = calcProductItemDTOMap.get(sku.getId()); item.setSpuId(sku.getSpuId()).setSkuId(sku.getId()); item.setCid(spuIdCategoryIdMap.get(sku.getSpuId())); + item.setSelected(calcOrderItem.getSelected()); item.setBuyQuantity(calcOrderItem.getQuantity()); // 计算初始价格 item.setOriginPrice(sku.getPrice()); @@ -235,7 +236,8 @@ public class PriceManager { Assert.isTrue(PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType()), "传入的必须的满减送活动必须是满减送"); // 获得优惠信息 - List items = itemGroup.getItems(); + List items = itemGroup.getItems().stream().filter(PriceProductCalcRespDTO.Item::getSelected) + .collect(Collectors.toList()); Integer itemCnt = items.stream().mapToInt(PriceProductCalcRespDTO.Item::getBuyQuantity).sum(); Integer originalTotal = items.stream().mapToInt(PriceProductCalcRespDTO.Item::getPresentTotal).sum(); List privileges = activity.getFullPrivilege().getPrivileges().stream() diff --git a/promotion-service-project/promotion-service-app/src/test/java/cn/iocoder/mall/promotionservice/manager/price/PriceManagerTest.java b/promotion-service-project/promotion-service-app/src/test/java/cn/iocoder/mall/promotionservice/manager/price/PriceManagerTest.java index 565ff626c..614dd6a77 100644 --- a/promotion-service-project/promotion-service-app/src/test/java/cn/iocoder/mall/promotionservice/manager/price/PriceManagerTest.java +++ b/promotion-service-project/promotion-service-app/src/test/java/cn/iocoder/mall/promotionservice/manager/price/PriceManagerTest.java @@ -20,8 +20,8 @@ public class PriceManagerTest { @Test public void testCalcProductPrice() { PriceProductCalcReqDTO calcReqDTO = new PriceProductCalcReqDTO(); - PriceProductCalcReqDTO.Item item01 = new PriceProductCalcReqDTO.Item(33, 2); // 满足满减送的商品 - PriceProductCalcReqDTO.Item item02 = new PriceProductCalcReqDTO.Item(34, 2); // 满足限时折扣的商品 + PriceProductCalcReqDTO.Item item01 = new PriceProductCalcReqDTO.Item(33, 2, true); // 满足满减送的商品 + PriceProductCalcReqDTO.Item item02 = new PriceProductCalcReqDTO.Item(34, 2, true); // 满足限时折扣的商品 calcReqDTO.setItems(Arrays.asList(item01, item02)); PriceProductCalcRespDTO calcRespDTO = priceManager.calcProductPrice(calcReqDTO); System.out.println(calcRespDTO); diff --git a/promotion-service-project/promotion-service-app/src/test/java/cn/iocoder/mall/promotionservice/package-info.java b/promotion-service-project/promotion-service-app/src/test/java/cn/iocoder/mall/promotionservice/package-info.java deleted file mode 100644 index ab4cb2d4b..000000000 --- a/promotion-service-project/promotion-service-app/src/test/java/cn/iocoder/mall/promotionservice/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.promotionservice; diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java index a6d05afd2..ac3659822 100644 --- a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java @@ -4,6 +4,7 @@ import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder; import cn.iocoder.mall.shopweb.controller.order.vo.cart.CartDetailVO; import cn.iocoder.mall.shopweb.manager.order.cart.CartManager; +import cn.iocoder.security.annotations.RequiresAuthenticate; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -12,6 +13,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Set; + import static cn.iocoder.common.framework.vo.CommonResult.success; @Api(tags = "购物车 API") @@ -29,6 +32,7 @@ public class CartController { @ApiImplicitParam(name = "skuId", value = "商品 SKU 编号", required = true, example = "1"), @ApiImplicitParam(name = "quantity", value = "增加数量", required = true, example = "1024") }) + @RequiresAuthenticate public CommonResult addCartItem(@RequestParam("skuId") Integer skuId, @RequestParam("quantity") Integer quantity) { cartManager.addCartItem(UserSecurityContextHolder.getUserId(), skuId, quantity); @@ -37,14 +41,43 @@ public class CartController { @GetMapping("sum-quantity") @ApiOperation("查询用户在购物车中的商品数量") + @RequiresAuthenticate public CommonResult sumCartItemQuantity() { return success(cartManager.sumCartItemQuantity(UserSecurityContextHolder.getUserId())); } @GetMapping("/get-detail") @ApiOperation("查询用户的购物车的商品列表") + @RequiresAuthenticate public CommonResult getCartDetail() { return success(cartManager.getCartDetail(UserSecurityContextHolder.getUserId())); } + @PostMapping("update-quantity") + @ApiOperation("更新购物车商品数量") + @ApiImplicitParams({ + @ApiImplicitParam(name = "skuId", value = "商品 SKU 编号", required = true, example = "1"), + @ApiImplicitParam(name = "quantity", value = "增加数量", required = true, example = "1024") + }) + @RequiresAuthenticate + public CommonResult updateCartItemQuantity(@RequestParam("skuId") Integer skuId, + @RequestParam("quantity") Integer quantity) { + cartManager.updateCartItemQuantity(UserSecurityContextHolder.getUserId(), skuId, quantity); + return success(true); + } + + @PostMapping("update-selected") + @ApiOperation("更新购物车商品是否选中") + @ApiImplicitParams({ + @ApiImplicitParam(name = "skuIds", value = "商品 SKU 编号数组", required = true, example = "1,3"), + @ApiImplicitParam(name = "selected", value = "是否选中", required = true, example = "true") + }) + @RequiresAuthenticate + public CommonResult updateCartItemSelected(@RequestParam("skuIds") Set skuIds, + @RequestParam("selected") Boolean selected) { + cartManager.updateCartItemSelected(UserSecurityContextHolder.getUserId(), skuIds, selected); + // 获得目前购物车明细 + return success(true); + } + } diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/convert/order/CartConvert.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/convert/order/CartConvert.java index 26c94e3e2..2a55499cf 100644 --- a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/convert/order/CartConvert.java +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/convert/order/CartConvert.java @@ -1,9 +1,11 @@ package cn.iocoder.mall.shopweb.convert.order; import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO; import cn.iocoder.mall.shopweb.controller.order.vo.cart.CartDetailVO; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @Mapper @@ -13,6 +15,7 @@ public interface CartConvert { CartDetailVO.Fee convert(PriceProductCalcRespDTO.Fee bean); - CartDetailVO.Sku convert(PriceProductCalcRespDTO.Item item, ProductSkuRespDTO sku); + @Mapping(source = "sku.id", target = "id") + CartDetailVO.Sku convert(PriceProductCalcRespDTO.Item item, ProductSkuRespDTO sku, PromotionActivityRespDTO activity); } diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java index 43c3151b8..1c08dc5fd 100644 --- a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java @@ -3,9 +3,7 @@ package cn.iocoder.mall.shopweb.manager.order.cart; import cn.iocoder.common.framework.util.CollectionUtils; import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.orderservice.rpc.cart.CartRpc; -import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemAddReqDTO; -import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemListReqDTO; -import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemRespDTO; +import cn.iocoder.mall.orderservice.rpc.cart.dto.*; import cn.iocoder.mall.productservice.enums.sku.ProductSkuDetailFieldEnum; import cn.iocoder.mall.productservice.rpc.sku.ProductSkuRpc; import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO; @@ -64,6 +62,32 @@ public class CartManager { return sumCartItemQuantityResult.getData(); } + /** + * 更新购物车商品数量 + * + * @param userId 用户编号 + * @param skuId 商品 SKU 编号 + * @param quantity 数量 + */ + public void updateCartItemQuantity(Integer userId, Integer skuId, Integer quantity) { + CommonResult updateCartItemQuantityResult = cartRpc.updateCartItemQuantity(new CartItemUpdateQuantityReqDTO() + .setUserId(userId).setSkuId(skuId).setQuantity(quantity)); + updateCartItemQuantityResult.checkError(); + } + + /** + * 更新购物车商品是否选中 + * + * @param userId 用户编号 + * @param skuIds 商品 SKU 编号数组 + * @param selected 是否选中 + */ + public void updateCartItemSelected(Integer userId, Set skuIds, Boolean selected) { + CommonResult updateCartItemSelectedResult = cartRpc.updateCartItemSelected(new CartItemUpdateSelectedReqDTO() + .setUserId(userId).setSkuIds(skuIds).setSelected(selected)); + updateCartItemSelectedResult.checkError(); + } + /** * 查询用户的购物车的商品列表 * @@ -94,7 +118,7 @@ public class CartManager { CartDetailVO cartDetailVO = new CartDetailVO(); cartDetailVO.setFee(CartConvert.INSTANCE.convert(calcProductPriceResult.getData().getFee())); cartDetailVO.setItemGroups(new ArrayList<>()); - calcProductPriceResult.getData().getItemGroups().forEach(itemGroupDTO -> { + for (PriceProductCalcRespDTO.ItemGroup itemGroupDTO : calcProductPriceResult.getData().getItemGroups()) { CartDetailVO.ItemGroup itemGroupVO = new CartDetailVO.ItemGroup(); cartDetailVO.getItemGroups().add(itemGroupVO); // 活动信息 @@ -104,10 +128,9 @@ public class CartManager { } // 商品 SKU 信息 itemGroupVO.setItems(new ArrayList<>()); - itemGroupDTO.getItems().forEach(item -> { - itemGroupVO.getItems().add(CartConvert.INSTANCE.convert(item, productSkuMap.get(item.getSkuId()))); - }); - }); + itemGroupDTO.getItems().forEach(item -> itemGroupVO.getItems().add(CartConvert.INSTANCE.convert(item, + productSkuMap.get(item.getSkuId()), promotionActivityMap.get(item.getActivityId())))); + } return cartDetailVO; } @@ -124,7 +147,7 @@ public class CartManager { } }); }); - if (!CollectionUtils.isEmpty(activeIds)) { + if (CollectionUtils.isEmpty(activeIds)) { return Collections.emptyMap(); } // 查询促销活动列表 diff --git a/shop-web-app/src/main/resources/application.yml b/shop-web-app/src/main/resources/application.yml index 4ba879ab2..29afe9fdf 100644 --- a/shop-web-app/src/main/resources/application.yml +++ b/shop-web-app/src/main/resources/application.yml @@ -37,6 +37,8 @@ dubbo: version: 1.0.0 ProductSpuRpc: version: 1.0.0 + ProductSkuRpc: + version: 1.0.0 SearchProductRpc: version: 1.0.0 PriceRpc: