mall:价格计算的 API 简单实现
parent
67d365475c
commit
15798cea10
@ -0,0 +1 @@
|
|||||||
|
package cn.iocoder.yudao.module.market.api.discount;
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package cn.iocoder.yudao.module.market.convert.price;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PriceConvert {
|
||||||
|
|
||||||
|
PriceConvert INSTANCE = Mappers.getMapper(PriceConvert.class);
|
||||||
|
|
||||||
|
default PriceCalculateRespDTO convert(PriceCalculateReqDTO calculateReqDTO, List<ProductSkuRespDTO> skuList) {
|
||||||
|
// 创建 PriceCalculateRespDTO 对象
|
||||||
|
PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO();
|
||||||
|
priceCalculate.setOrder(new PriceCalculateRespDTO.Order().setSkuOriginalPrice(0).setSkuPromotionPrice(0)
|
||||||
|
.setOrderPromotionPrice(0).setDeliveryPrice(0).setPayPrice(0).setItems(new ArrayList<>())
|
||||||
|
.setCouponId(calculateReqDTO.getCouponId()));
|
||||||
|
priceCalculate.setPromotions(new ArrayList<>());
|
||||||
|
// 创建它的 OrderItem 属性
|
||||||
|
Map<Long, Integer> skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(),
|
||||||
|
PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount);
|
||||||
|
skuList.forEach(sku -> {
|
||||||
|
Integer count = skuIdCountMap.get(sku.getId());
|
||||||
|
PriceCalculateRespDTO.OrderItem orderItem = new PriceCalculateRespDTO.OrderItem().setCount(count)
|
||||||
|
.setOriginalPrice(sku.getPrice()).setTotalOriginalPrice(sku.getPrice() * count).setTotalPromotionPrice(0);
|
||||||
|
orderItem.setTotalPresentPrice(orderItem.getTotalPresentPrice()).setPresentPrice(orderItem.getOriginalPrice())
|
||||||
|
.setTotalPayPrice(orderItem.getTotalPayPrice());
|
||||||
|
priceCalculate.getOrder().getItems().add(orderItem);
|
||||||
|
});
|
||||||
|
return priceCalculate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.module.market.service.price;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 价格计算 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface PriceService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算商品的价格
|
||||||
|
*
|
||||||
|
* @param calculateReqDTO 价格请求
|
||||||
|
* @return 价格相应
|
||||||
|
*/
|
||||||
|
PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package cn.iocoder.yudao.module.market.service.price;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.market.convert.price.PriceConvert;
|
||||||
|
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||||
|
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
||||||
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 价格计算 Service 实现类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class PriceServiceImpl implements PriceService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ProductSkuApi productSkuApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) {
|
||||||
|
// 获得商品 SKU 数组
|
||||||
|
List<ProductSkuRespDTO> skuList = checkProductSkus(calculateReqDTO);
|
||||||
|
// 初始化 PriceCalculateRespDTO 对象
|
||||||
|
PriceCalculateRespDTO priceCalculate = PriceConvert.INSTANCE.convert(calculateReqDTO, skuList);
|
||||||
|
|
||||||
|
// 计算【限时折扣】促销 TODO 待实现
|
||||||
|
// 计算【满减送】促销 TODO 待实现
|
||||||
|
// 计算【优惠劵】促销 TODO 待实现
|
||||||
|
return priceCalculate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProductSkuRespDTO> checkProductSkus(PriceCalculateReqDTO calculateReqDTO) {
|
||||||
|
// 获得商品 SKU 数组
|
||||||
|
Map<Long, Integer> skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(),
|
||||||
|
PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount);
|
||||||
|
List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(skuIdCountMap.keySet());
|
||||||
|
|
||||||
|
// 校验商品 SKU
|
||||||
|
skus.forEach(sku -> {
|
||||||
|
Integer count = skuIdCountMap.get(sku.getId());
|
||||||
|
if (count == null) {
|
||||||
|
throw exception(SKU_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
if (count > sku.getStock()) {
|
||||||
|
throw exception(SKU_STOCK_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return skus;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,23 +1,24 @@
|
|||||||
package cn.iocoder.yudao.module.product.api.spu;
|
package cn.iocoder.yudao.module.product.api.spu;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.product.api.sku.dto.SkuInfoRespDTO;
|
|
||||||
import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO;
|
import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 商品 SPU API 接口
|
||||||
|
*
|
||||||
* @author LeeYan9
|
* @author LeeYan9
|
||||||
* @since 2022-08-26
|
* @since 2022-08-26
|
||||||
*/
|
*/
|
||||||
public interface ProductSpuApi {
|
public interface ProductSpuApi {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据spuId列表 查询spu信息
|
* 批量查询 SPU 数组
|
||||||
*
|
*
|
||||||
* @param spuIds spu ID列表
|
* @param ids SPU 编号列表
|
||||||
* @return spu信息列表
|
* @return SPU 数组
|
||||||
*/
|
*/
|
||||||
List<SpuInfoRespDTO> getSpusByIds(Collection<Long> spuIds);
|
List<SpuInfoRespDTO> getSpuList(Collection<Long> ids);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.controller.app.base.property;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@ApiModel("用户 App - 规格 + 规格值 Response VO")
|
||||||
|
@Data
|
||||||
|
public class AppProductPropertyValueDetailRespVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "属性的编号", required = true, example = "1")
|
||||||
|
private Long propertyId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "属性的名称", required = true, example = "颜色")
|
||||||
|
private String propertyName;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "属性值的编号", required = true, example = "1024")
|
||||||
|
private Long valueId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "属性值的名称", required = true, example = "红色")
|
||||||
|
private String valueName;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.controller.app.base.sku;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品 SKU 基础 Response VO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AppProductSkuBaseRespVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "主键", required = true, example = "1024")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品 SKU 名字", required = true, example = "芋道")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "图片地址", example = "https://www.iocoder.cn/xx.png")
|
||||||
|
private String picUrl;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "库存", required = true, example = "1")
|
||||||
|
private Integer stock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 规格数组
|
||||||
|
*/
|
||||||
|
private List<AppProductPropertyValueDetailRespVO> properties;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.controller.app.base.spu;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品 SPU 基础 Response VO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AppProductSpuBaseRespVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "主键", required = true, example = "1024")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品 SPU 名字", required = true, example = "芋道")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品主图地址", example = "https://www.iocoder.cn/xx.png")
|
||||||
|
private List<String> picUrls;
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,71 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.trade.controller.app.cart;
|
|
||||||
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@Api(tags = "购物车 API")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/cart")
|
|
||||||
@Validated
|
|
||||||
public class CartController {
|
|
||||||
|
|
||||||
// @Autowired
|
|
||||||
// private CartManager cartManager;
|
|
||||||
//
|
|
||||||
// @PostMapping("add")
|
|
||||||
// @ApiOperation("添加商品到购物车")
|
|
||||||
// @ApiImplicitParams({
|
|
||||||
// @ApiImplicitParam(name = "skuId", value = "商品 SKU 编号", required = true, example = "1"),
|
|
||||||
// @ApiImplicitParam(name = "quantity", value = "增加数量", required = true, example = "1024")
|
|
||||||
// })
|
|
||||||
// @RequiresAuthenticate
|
|
||||||
// public CommonResult<Boolean> addCartItem(@RequestParam("skuId") Integer skuId,
|
|
||||||
// @RequestParam("quantity") Integer quantity) {
|
|
||||||
// cartManager.addCartItem(UserSecurityContextHolder.getUserId(), skuId, quantity);
|
|
||||||
// return success(true);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @GetMapping("sum-quantity")
|
|
||||||
// @ApiOperation("查询用户在购物车中的商品数量")
|
|
||||||
// @RequiresAuthenticate
|
|
||||||
// public CommonResult<Integer> sumCartItemQuantity() {
|
|
||||||
// return success(cartManager.sumCartItemQuantity(UserSecurityContextHolder.getUserId()));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @GetMapping("/get-detail")
|
|
||||||
// @ApiOperation("查询用户的购物车的商品列表")
|
|
||||||
// @RequiresAuthenticate
|
|
||||||
// public CommonResult<CartDetailVO> 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<Boolean> 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<Boolean> updateCartItemSelected(@RequestParam("skuIds") Set<Integer> skuIds,
|
|
||||||
// @RequestParam("selected") Boolean selected) {
|
|
||||||
// cartManager.updateCartItemSelected(UserSecurityContextHolder.getUserId(), skuIds, selected);
|
|
||||||
// // 获得目前购物车明细
|
|
||||||
// return success(true);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
### 请求 /trade/cart/add-count 接口 => 成功
|
||||||
|
POST {{appApi}}/trade/cart/add-count
|
||||||
|
tenant-id: {{appTenentId}}
|
||||||
|
Authorization: Bearer {{appToken}}
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"skuId": 1,
|
||||||
|
"count": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
### 请求 /trade/cart/update-count 接口 => 成功
|
||||||
|
PUT {{appApi}}/trade/cart/update-count
|
||||||
|
tenant-id: {{appTenentId}}
|
||||||
|
Authorization: Bearer {{appToken}}
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"skuId": 1,
|
||||||
|
"count": 5
|
||||||
|
}
|
||||||
|
|
||||||
|
### 请求 /trade/cart/update-selected 接口 => 成功
|
||||||
|
PUT {{appApi}}/trade/cart/update-selected
|
||||||
|
tenant-id: {{appTenentId}}
|
||||||
|
Authorization: Bearer {{appToken}}
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"skuIds": [1],
|
||||||
|
"selected": false
|
||||||
|
}
|
||||||
|
|
||||||
|
### 请求 /trade/cart/delete 接口 => 成功
|
||||||
|
DELETE {{appApi}}/trade/cart/delete?skuIds=1
|
||||||
|
tenant-id: {{appTenentId}}
|
||||||
|
Authorization: Bearer {{appToken}}
|
||||||
|
|
||||||
|
### 请求 /trade/cart/get-count 接口 => 成功
|
||||||
|
GET {{appApi}}/trade/cart/get-count
|
||||||
|
tenant-id: {{appTenentId}}
|
||||||
|
Authorization: Bearer {{appToken}}
|
||||||
|
|
||||||
|
### 请求 /trade/cart/get-detail 接口 => 成功
|
||||||
|
GET {{appApi}}/trade/cart/get-detail
|
||||||
|
tenant-id: {{appTenentId}}
|
||||||
|
Authorization: Bearer {{appToken}}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.controller.app.cart;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.cart.TradeCartService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
|
|
||||||
|
@Api(tags = "用户 App - 购物车")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/trade/cart")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Validated
|
||||||
|
@Slf4j
|
||||||
|
public class TradeCartController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TradeCartService cartService;
|
||||||
|
|
||||||
|
@PostMapping("/add-count")
|
||||||
|
@ApiOperation("添加商品到购物车")
|
||||||
|
@PreAuthenticated
|
||||||
|
public CommonResult<Boolean> addCartItemCount(@Valid @RequestBody AppTradeCartItemAddCountReqVO addCountReqVO) {
|
||||||
|
cartService.addCartItemCount(getLoginUserId(), addCountReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("update-count")
|
||||||
|
@ApiOperation("更新购物车商品数量")
|
||||||
|
@PreAuthenticated
|
||||||
|
public CommonResult<Boolean> updateCartItemQuantity(@Valid @RequestBody AppTradeCartItemUpdateCountReqVO updateCountReqVO) {
|
||||||
|
cartService.updateCartItemCount(getLoginUserId(), updateCountReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("update-selected")
|
||||||
|
@ApiOperation("更新购物车商品是否选中")
|
||||||
|
@PreAuthenticated
|
||||||
|
public CommonResult<Boolean> updateCartItemSelected(@Valid @RequestBody AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) {
|
||||||
|
cartService.updateCartItemSelected(getLoginUserId(), updateSelectedReqVO);
|
||||||
|
// 获得目前购物车明细
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@ApiOperation("删除购物车商品")
|
||||||
|
@ApiImplicitParam(name = "skuId", value = "商品 SKU 编号的数组", required = true, example = "1024,2048", dataTypeClass = List.class)
|
||||||
|
@PreAuthenticated
|
||||||
|
public CommonResult<Boolean> deleteCartItem(@RequestParam("skuIds") List<Long> skuIds) {
|
||||||
|
cartService.deleteCartItems(getLoginUserId(), skuIds);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("get-count")
|
||||||
|
@ApiOperation("查询用户在购物车中的商品数量")
|
||||||
|
@PreAuthenticated
|
||||||
|
public CommonResult<Integer> getCartCount() {
|
||||||
|
return success(cartService.getCartCount(getLoginUserId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-detail")
|
||||||
|
@ApiOperation("查询用户的购物车的详情")
|
||||||
|
@PreAuthenticated
|
||||||
|
public CommonResult<AppTradeCartDetailRespVO> getCartDetail() {
|
||||||
|
return success(cartService.getCartDetail(getLoginUserId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.controller.app.cart.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@ApiModel(value = "用户 App - 购物车添加购物项 Request VO")
|
||||||
|
@Data
|
||||||
|
public class AppTradeCartItemAddCountReqVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品 SKU 编号", required = true,example = "1024")
|
||||||
|
@NotNull(message = "商品 SKU 编号不能为空")
|
||||||
|
private Long skuId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品数量", required = true, example = "1", notes = "注意,这是新增数量")
|
||||||
|
@NotNull(message = "数量不能为空")
|
||||||
|
@Min(message = "数量必须大于 0", value = 1L)
|
||||||
|
private Integer count;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.controller.app.cart.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@ApiModel(value = "用户 App - 购物车更新数量 Request VO")
|
||||||
|
@Data
|
||||||
|
public class AppTradeCartItemUpdateCountReqVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1024")
|
||||||
|
@NotNull(message = "商品 SKU 编号不能为空")
|
||||||
|
private Long skuId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品数量", required = true, example = "1")
|
||||||
|
@NotNull(message = "数量不能为空")
|
||||||
|
@Min(message = "数量必须大于 0", value = 1L)
|
||||||
|
private Integer count;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.controller.app.cart.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@ApiModel(value = "用户 App - 购物车更新是否选中 Request VO")
|
||||||
|
@Data
|
||||||
|
public class AppTradeCartItemUpdateSelectedReqVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品 SKU 编号列表", required = true, example = "1024,2048")
|
||||||
|
@NotNull(message = "商品 SKU 编号列表不能为空")
|
||||||
|
private Collection<Long> skuIds;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否选中", required = true, example = "true")
|
||||||
|
@NotNull(message = "是否选中不能为空")
|
||||||
|
private Boolean selected;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.convert.cart;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface TradeCartConvert {
|
||||||
|
|
||||||
|
TradeCartConvert INSTANCE = Mappers.getMapper(TradeCartConvert.class);
|
||||||
|
|
||||||
|
default AppTradeCartDetailRespVO buildEmptyAppTradeCartDetailRespVO() {
|
||||||
|
return new AppTradeCartDetailRespVO().setItemGroups(Collections.emptyList())
|
||||||
|
.setOrder(new AppTradeCartDetailRespVO.Order().setSkuOriginalPrice(0).setSkuPromotionPrice(0)
|
||||||
|
.setOrderPromotionPrice(0).setDeliveryPrice(0).setPayPrice(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
default PriceCalculateReqDTO convert(Long userId, List<TradeCartItemDO> cartItems) {
|
||||||
|
return new PriceCalculateReqDTO().setUserId(userId)
|
||||||
|
.setItems(convertList(cartItems, cartItem -> new PriceCalculateReqDTO.Item().setSkuId(cartItem.getSkuId())
|
||||||
|
.setCount(cartItem.getSelected() ? cartItem.getCount() : 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== AppTradeCartDetailRespVO 相关 ==========
|
||||||
|
|
||||||
|
AppTradeCartDetailRespVO.Promotion convert(PriceCalculateRespDTO.Promotion bean);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(source = "cartItem.count", target = "count")
|
||||||
|
})
|
||||||
|
AppTradeCartDetailRespVO.Sku convert(PriceCalculateRespDTO.OrderItem orderItem, TradeCartItemDO cartItem);
|
||||||
|
|
||||||
|
AppTradeCartDetailRespVO.Order convert(PriceCalculateRespDTO.Order bean);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.dal.mysql.cart;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface TradeCartItemMapper extends BaseMapperX<TradeCartItemDO> {
|
||||||
|
|
||||||
|
default TradeCartItemDO selectByUserIdAndSkuId(Long userId, Long skuId) {
|
||||||
|
return selectOne(TradeCartItemDO::getUserId, userId,
|
||||||
|
TradeCartItemDO::getSkuId, skuId);
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<TradeCartItemDO> selectListByUserIdAndSkuIds(Long userId, Collection<Long> skuIds) {
|
||||||
|
return selectList(new LambdaQueryWrapper<TradeCartItemDO>().eq(TradeCartItemDO::getUserId, userId)
|
||||||
|
.in(TradeCartItemDO::getSkuId, skuIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void updateByIds(Collection<Long> ids, TradeCartItemDO updateObject) {
|
||||||
|
update(updateObject, new LambdaQueryWrapper<TradeCartItemDO>().in(TradeCartItemDO::getId, ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
default Integer selectSumByUserId(Long userId) {
|
||||||
|
// SQL sum 查询
|
||||||
|
List<Map<String, Object>> result = selectMaps(new QueryWrapper<TradeCartItemDO>()
|
||||||
|
.select("SUM(count) AS sumCount")
|
||||||
|
.eq("user_id", userId));
|
||||||
|
// 获得数量
|
||||||
|
return CollUtil.isNotEmpty(result) ? MapUtil.getInt(result.get(0), "sumCount") : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<TradeCartItemDO> selectListByUserId(Long userId, Boolean selected) {
|
||||||
|
return selectList(new LambdaQueryWrapperX<TradeCartItemDO>().eq(TradeCartItemDO::getUserId, userId)
|
||||||
|
.eqIfPresent(TradeCartItemDO::getSelected, selected));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.service.cart;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface TradeCartService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加商品到购物车
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param addCountReqVO 添加信息
|
||||||
|
*/
|
||||||
|
void addCartItemCount(Long userId, @Valid AppTradeCartItemAddCountReqVO addCountReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新购物车商品数量
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param updateCountReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新购物车商品是否选中
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param updateSelectedReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除购物车商品
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param skuIds SKU 编号的数组
|
||||||
|
*/
|
||||||
|
void deleteCartItems(Long userId, Collection<Long> skuIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户在购物车中的商品数量
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @return 商品数量
|
||||||
|
*/
|
||||||
|
Integer getCartCount(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户的购物车详情
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @return 购物车详情
|
||||||
|
*/
|
||||||
|
AppTradeCartDetailRespVO getCartDetail(Long userId);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,184 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.service.cart;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.PriceApi;
|
||||||
|
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.market.enums.common.PromotionLevelEnum;
|
||||||
|
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||||
|
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartItemMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||||
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
||||||
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH;
|
||||||
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.CARD_ITEM_NOT_FOUND;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车 Service 实现类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class TradeCartServiceImpl implements TradeCartService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TradeCartItemMapper cartItemMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ProductSkuApi productSkuApi;
|
||||||
|
@Resource
|
||||||
|
private PriceApi priceApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCartItemCount(Long userId, AppTradeCartItemAddCountReqVO addCountReqVO) {
|
||||||
|
Long skuId = addCountReqVO.getSkuId();
|
||||||
|
Integer count = addCountReqVO.getCount();
|
||||||
|
// 查询 CartItemDO
|
||||||
|
TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, addCountReqVO.getSkuId());
|
||||||
|
|
||||||
|
// 存在,则进行数量更新
|
||||||
|
if (tradeItem != null) {
|
||||||
|
checkProductSku(skuId, tradeItem.getCount() + count);
|
||||||
|
cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId())
|
||||||
|
.setSelected(true).setCount(tradeItem.getCount() + count));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不存在,则进行插入
|
||||||
|
ProductSkuRespDTO sku = checkProductSku(skuId, count);
|
||||||
|
cartItemMapper.insert(new TradeCartItemDO().setUserId(userId).setSpuId(sku.getSpuId()).setSkuId(sku.getId())
|
||||||
|
.setSelected(true).setCount(count));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO) {
|
||||||
|
// 校验 TradeCartItemDO 存在
|
||||||
|
TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, updateCountReqVO.getSkuId());
|
||||||
|
if (tradeItem == null) {
|
||||||
|
throw exception(CARD_ITEM_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 校验商品 SKU
|
||||||
|
checkProductSku(updateCountReqVO.getSkuId(), updateCountReqVO.getCount());
|
||||||
|
|
||||||
|
// 更新数量
|
||||||
|
cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId()).setCount(updateCountReqVO.getCount()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) {
|
||||||
|
// 查询 CartItemDO 列表
|
||||||
|
List<TradeCartItemDO> cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, updateSelectedReqVO.getSkuIds());
|
||||||
|
if (CollUtil.isEmpty(cartItems)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新选中
|
||||||
|
cartItemMapper.updateByIds(CollectionUtils.convertList(cartItems, TradeCartItemDO::getId),
|
||||||
|
new TradeCartItemDO().setSelected(updateSelectedReqVO.getSelected()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车删除商品
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param skuIds 商品 SKU 编号的数组
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void deleteCartItems(Long userId, Collection<Long> skuIds) {
|
||||||
|
// 查询 CartItemDO 列表
|
||||||
|
List<TradeCartItemDO> cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds);
|
||||||
|
if (CollUtil.isEmpty(cartItems)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量标记删除
|
||||||
|
cartItemMapper.deleteBatchIds(CollectionUtils.convertSet(cartItems, TradeCartItemDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getCartCount(Long userId) {
|
||||||
|
return cartItemMapper.selectSumByUserId(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AppTradeCartDetailRespVO getCartDetail(Long userId) {
|
||||||
|
// 获得购物车的商品
|
||||||
|
List<TradeCartItemDO> cartItems = cartItemMapper.selectListByUserId(userId, null);
|
||||||
|
// 如果未空,则返回空结果
|
||||||
|
if (CollUtil.isEmpty(cartItems)) {
|
||||||
|
return TradeCartConvert.INSTANCE.buildEmptyAppTradeCartDetailRespVO();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用价格服务,计算价格
|
||||||
|
PriceCalculateRespDTO priceCalculate = priceApi.calculatePrice(TradeCartConvert.INSTANCE.convert(userId, cartItems));
|
||||||
|
|
||||||
|
// 转换返回
|
||||||
|
Map<Long, TradeCartItemDO> cartItemMap = convertMap(cartItems, TradeCartItemDO::getSkuId);
|
||||||
|
Map<Long, PriceCalculateRespDTO.OrderItem> orderItemMap = convertMap(priceCalculate.getOrder().getItems(),
|
||||||
|
PriceCalculateRespDTO.OrderItem::getSkuId);
|
||||||
|
List<AppTradeCartDetailRespVO.ItemGroup> itemGroups = new ArrayList<>(cartItems.size());
|
||||||
|
// ① 场景一,营销活动,订单级别 TODO 芋艿:待测试
|
||||||
|
priceCalculate.getPromotions().stream().filter(promotion -> PromotionLevelEnum.ORDER.getLevel().equals(promotion.getLevel()))
|
||||||
|
.forEach(promotion -> {
|
||||||
|
AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>())
|
||||||
|
.setPromotion(TradeCartConvert.INSTANCE.convert(promotion));
|
||||||
|
itemGroups.add(itemGroup);
|
||||||
|
promotion.getItems().forEach(promotionItem -> {
|
||||||
|
PriceCalculateRespDTO.OrderItem orderItem = orderItemMap.remove(promotionItem.getSkuId());
|
||||||
|
Assert.notNull(orderItem, "商品 SKU({}) 对应的订单项不能为空", promotionItem.getSkuId());
|
||||||
|
TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId());
|
||||||
|
itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// ② 场景二,营销活动,商品级别
|
||||||
|
orderItemMap.values().forEach(orderItem -> {
|
||||||
|
AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>(1)).setPromotion(null);
|
||||||
|
itemGroups.add(itemGroup);
|
||||||
|
TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId());
|
||||||
|
itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu
|
||||||
|
});
|
||||||
|
return new AppTradeCartDetailRespVO().setItemGroups(itemGroups)
|
||||||
|
.setOrder(TradeCartConvert.INSTANCE.convert(priceCalculate.getOrder()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验商品 SKU 是否合法
|
||||||
|
* 1. 是否存在
|
||||||
|
* 2. 是否下架
|
||||||
|
* 3. 库存不足
|
||||||
|
*
|
||||||
|
* @param skuId 商品 SKU 编号
|
||||||
|
* @param count 商品数量
|
||||||
|
* @return 商品 SKU
|
||||||
|
*/
|
||||||
|
private ProductSkuRespDTO checkProductSku(Long skuId, Integer count) {
|
||||||
|
ProductSkuRespDTO sku = productSkuApi.getSku(skuId);
|
||||||
|
if (sku == null || CommonStatusEnum.DISABLE.getStatus().equals(sku.getStatus())) {
|
||||||
|
throw exception(SKU_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
if (count > sku.getStock()) {
|
||||||
|
throw exception(SKU_STOCK_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
return sku;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue