后端:商品确认下单的信息 api 接口,后续需要结合促销,完善这个接口。
This commit is contained in:
@@ -1,18 +1,25 @@
|
||||
package cn.iocoder.mall.order.application.controller.users;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.order.api.CartService;
|
||||
import cn.iocoder.mall.order.api.OrderService;
|
||||
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||
import cn.iocoder.mall.order.api.bo.OrderCreateBO;
|
||||
import cn.iocoder.mall.order.api.bo.OrderPageBO;
|
||||
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
|
||||
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
|
||||
import cn.iocoder.mall.order.api.dto.OrderQueryDTO;
|
||||
import cn.iocoder.mall.order.application.convert.CartConvert;
|
||||
import cn.iocoder.mall.order.application.convert.OrderConvertAPP;
|
||||
import cn.iocoder.mall.order.application.po.user.OrderCreatePO;
|
||||
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
|
||||
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* 订单API(users)
|
||||
*
|
||||
@@ -23,8 +30,10 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequestMapping("users/order")
|
||||
public class UsersOrderController {
|
||||
|
||||
@Autowired
|
||||
@Reference(validation = "true")
|
||||
private OrderService orderService;
|
||||
@Reference(validation = "true")
|
||||
private CartService cartService;
|
||||
|
||||
@GetMapping("order_page")
|
||||
public CommonResult<OrderPageBO> getOrderPage(@Validated OrderQueryDTO orderQueryDTO) {
|
||||
@@ -40,4 +49,19 @@ public class UsersOrderController {
|
||||
orderCreateDTO.setUserId(userId);
|
||||
return orderService.createOrder(orderCreateDTO);
|
||||
}
|
||||
|
||||
@GetMapping("/confirm_create_order")
|
||||
public CommonResult<UsersOrderConfirmCreateVO> getConfirmCreateOrder(@RequestParam("skuId") Integer skuId,
|
||||
@RequestParam("quantity") Integer quantity) {
|
||||
// 创建 CalcOrderPriceDTO 对象,并执行价格计算
|
||||
CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO()
|
||||
.setItems(Collections.singletonList(new CalcOrderPriceDTO.Item(skuId, quantity, true)));
|
||||
CommonResult<CalcOrderPriceBO> calcOrderPriceResult = cartService.calcOrderPrice(calcOrderPriceDTO);
|
||||
if (calcOrderPriceResult.isError()) {
|
||||
return CommonResult.error(calcOrderPriceResult);
|
||||
}
|
||||
// 执行数据拼装
|
||||
return CommonResult.success(CartConvert.INSTANCE.convert(calcOrderPriceResult.getData()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.iocoder.mall.order.application.convert;
|
||||
|
||||
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface CartConvert {
|
||||
|
||||
CartConvert INSTANCE = Mappers.getMapper(CartConvert.class);
|
||||
|
||||
UsersOrderConfirmCreateVO convert(CalcOrderPriceBO calcOrderPriceBO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package cn.iocoder.mall.order.application.vo;
|
||||
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrAndValuePairBO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UsersOrderConfirmCreateVO {
|
||||
|
||||
/**
|
||||
* 商品分组数组
|
||||
*/
|
||||
private List<ItemGroup> itemGroups;
|
||||
/**
|
||||
* 费用
|
||||
*/
|
||||
private Fee fee;
|
||||
|
||||
/**
|
||||
* 商品分组
|
||||
*
|
||||
* 多个商品,参加同一个活动,从而形成分组。
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class ItemGroup {
|
||||
|
||||
// TODO 优惠活动
|
||||
private Object activity;
|
||||
/**
|
||||
* 商品数组
|
||||
*/
|
||||
private List<Sku> items;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Sku {
|
||||
|
||||
// SKU 自带信息
|
||||
/**
|
||||
* sku 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* SPU 信息
|
||||
*/
|
||||
private Spu spu;
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String picURL;
|
||||
/**
|
||||
* 规格值数组
|
||||
*/
|
||||
private List<ProductAttrAndValuePairBO> attrs; // TODO 后面改下
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
// 非 SKU 自带信息
|
||||
|
||||
/**
|
||||
* 购买数量
|
||||
*/
|
||||
private Integer buyQuantity;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Spu {
|
||||
|
||||
/**
|
||||
* SPU 编号
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*
|
||||
* 数组,以逗号分隔
|
||||
*
|
||||
* 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张
|
||||
*/
|
||||
private List<String> picUrls;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 费用(合计)
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Fee {
|
||||
|
||||
/**
|
||||
* 总价
|
||||
*/
|
||||
private Integer originalTotal;
|
||||
/**
|
||||
* 优惠总价
|
||||
*
|
||||
* 注意,满多少元包邮,不算在优惠中。
|
||||
*/
|
||||
private Integer discountTotal;
|
||||
/**
|
||||
* 邮费
|
||||
*/
|
||||
private Integer postageTotal;
|
||||
/**
|
||||
* 最终价格
|
||||
*
|
||||
* 计算公式 = 总价 - 优惠总价 + 邮费
|
||||
*/
|
||||
private Integer presentTotal;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 邮费信息
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Postage {
|
||||
|
||||
/**
|
||||
* 需要满足多少钱,可以包邮。单位:分
|
||||
*/
|
||||
private Integer threshold;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,8 +16,13 @@
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>common-framework</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
@@ -34,5 +39,6 @@
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package cn.iocoder.mall.order.api;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||
import cn.iocoder.mall.order.api.bo.CartBO;
|
||||
import cn.iocoder.mall.order.api.bo.CartItemBO;
|
||||
import cn.iocoder.mall.order.api.bo.OrderCreateBO;
|
||||
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
@@ -78,6 +80,14 @@ public interface CartService {
|
||||
|
||||
// ========== 购物车与订单相关的逻辑 ==========
|
||||
|
||||
/**
|
||||
* 计算订单金额,返回计算结果
|
||||
*
|
||||
* @param calcOrderPriceDTO 计算订单金额 DTO
|
||||
* @return 计算订单金额结果
|
||||
*/
|
||||
CommonResult<CalcOrderPriceBO> calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO);
|
||||
|
||||
/**
|
||||
* 获得购物车明细
|
||||
*
|
||||
|
||||
@@ -38,14 +38,6 @@ public interface OrderService {
|
||||
*/
|
||||
CommonResult<OrderRecipientBO> getOrderRecipientBO(Integer orderId);
|
||||
|
||||
/**
|
||||
* 计算订单金额,返回计算结果
|
||||
*
|
||||
* @param calcOrderPriceDTO 计算订单金额 DTO
|
||||
* @return 计算订单金额结果
|
||||
*/
|
||||
CalcOrderPriceBO calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO);
|
||||
|
||||
/**
|
||||
* 订单 - 创建
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.iocoder.mall.order.api.bo;
|
||||
|
||||
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@@ -45,10 +46,16 @@ public class CalcOrderPriceBO {
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Item {
|
||||
|
||||
// TODO 信息要相当完整
|
||||
public static class Item extends ProductSkuDetailBO { // TODO 芋艿,此处先偷懒继承
|
||||
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
private Boolean selected;
|
||||
/**
|
||||
* 购买数量
|
||||
*/
|
||||
private Integer buyQuantity;
|
||||
|
||||
}
|
||||
|
||||
@@ -80,6 +87,15 @@ public class CalcOrderPriceBO {
|
||||
*/
|
||||
private Integer presentTotal;
|
||||
|
||||
public Fee() {
|
||||
}
|
||||
|
||||
public Fee(Integer originalTotal, Integer discountTotal, Integer postageTotal, Integer presentTotal) {
|
||||
this.originalTotal = originalTotal;
|
||||
this.discountTotal = discountTotal;
|
||||
this.postageTotal = postageTotal;
|
||||
this.presentTotal = presentTotal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,7 @@ public enum OrderErrorCodeEnum {
|
||||
|
||||
// order item
|
||||
ORDER_ITEM_ONLY_ONE(1008000004, "订单Item只有一个!"),
|
||||
|
||||
ORDER_ITEM_SOME_NOT_EXISTS(-1, "有不存在的商品"), // TODO 芋艿 后面改下错误码
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@ public class CalcOrderPriceDTO {
|
||||
/**
|
||||
* 商品数组
|
||||
*/
|
||||
private List<Integer> items;
|
||||
private List<Item> items;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
private static class Item {
|
||||
public static class Item {
|
||||
|
||||
/**
|
||||
* SKU 编号
|
||||
@@ -36,6 +36,14 @@ public class CalcOrderPriceDTO {
|
||||
*/
|
||||
private Boolean selected;
|
||||
|
||||
public Item() {
|
||||
}
|
||||
|
||||
public Item(Integer skuId, Integer quantity, Boolean selected) {
|
||||
this.skuId = skuId;
|
||||
this.quantity = quantity;
|
||||
this.selected = selected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.iocoder.mall.order.biz.convert;
|
||||
|
||||
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface CartConvert {
|
||||
|
||||
CartConvert INSTANCE = Mappers.getMapper(CartConvert.class);
|
||||
|
||||
CalcOrderPriceBO.Item convert(ProductSkuDetailBO sku);
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package cn.iocoder.mall.order.biz.mock;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
||||
@@ -17,8 +18,9 @@ import java.util.List;
|
||||
* @time 2019-03-24 15:24
|
||||
*/
|
||||
public class ProductSpuServiceMock implements ProductSpuService {
|
||||
|
||||
@Override
|
||||
public CommonResult<ProductSpuDetailBO> getProductSpu(Integer id) {
|
||||
public CommonResult<ProductSpuDetailBO> getProductSpuDetail(Integer id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -46,4 +48,10 @@ public class ProductSpuServiceMock implements ProductSpuService {
|
||||
public CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<List<ProductSkuDetailBO>> getProductSkuDetailList(Collection<Integer> ids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
package cn.iocoder.mall.order.biz.service;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.order.api.CartService;
|
||||
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||
import cn.iocoder.mall.order.api.bo.CartBO;
|
||||
import cn.iocoder.mall.order.api.bo.CartItemBO;
|
||||
import cn.iocoder.mall.order.api.bo.OrderCreateBO;
|
||||
import cn.iocoder.mall.order.api.constant.OrderErrorCodeEnum;
|
||||
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
|
||||
import cn.iocoder.mall.order.biz.convert.CartConvert;
|
||||
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 购物车服务 Service 实现类
|
||||
*/
|
||||
@Service
|
||||
@com.alibaba.dubbo.config.annotation.Service(validation = "true")
|
||||
public class CartServiceImpl implements CartService {
|
||||
|
||||
@Reference(validation = "true")
|
||||
private ProductSpuService productSpuService;
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> add(Integer userId, Integer skuId, Integer quantity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updateQuantity(Integer userId, Integer skuId, Integer quantity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updateSelected(Integer userId, Integer skuId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> delete(Integer userId, List<Integer> skuIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> deleteAll(Integer userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Integer> count(Integer userId, String nobody, Integer shopId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CartItemBO> list(Integer userId, Boolean selected) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<CalcOrderPriceBO> calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO) {
|
||||
// 校验商品都存在
|
||||
Map<Integer, CalcOrderPriceDTO.Item> calcOrderItemMap = calcOrderPriceDTO.getItems().stream()
|
||||
.collect(Collectors.toMap(CalcOrderPriceDTO.Item::getSkuId, item -> item));
|
||||
List<ProductSkuDetailBO> skus = productSpuService.getProductSkuDetailList(calcOrderItemMap.keySet()).getData();
|
||||
if (skus.size() != calcOrderPriceDTO.getItems().size()) {
|
||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_ITEM_SOME_NOT_EXISTS.getCode());
|
||||
}
|
||||
// TODO 库存相关
|
||||
// TODO 获得促销活动
|
||||
// TODO 处理促销相关信息
|
||||
// 拼装结果
|
||||
CalcOrderPriceBO calcOrderPriceBO = new CalcOrderPriceBO();
|
||||
// 1. 商品分组
|
||||
CalcOrderPriceBO.ItemGroup itemGroup0 = new CalcOrderPriceBO.ItemGroup()
|
||||
.setItems(new ArrayList<>());
|
||||
for (ProductSkuDetailBO sku : skus) {
|
||||
CalcOrderPriceBO.Item item = CartConvert.INSTANCE.convert(sku);
|
||||
// 将是否选中,购物数量,复制到 item 中
|
||||
CalcOrderPriceDTO.Item calcOrderItem = calcOrderItemMap.get(sku.getId());
|
||||
item.setSelected(calcOrderItem.getSelected());
|
||||
item.setBuyQuantity(calcOrderItem.getQuantity());
|
||||
// 添加到 itemGroup 中
|
||||
itemGroup0.getItems().add(item);
|
||||
}
|
||||
calcOrderPriceBO.setItemGroups(Collections.singletonList(itemGroup0));
|
||||
// 2. 计算价格
|
||||
CalcOrderPriceBO.Fee fee = new CalcOrderPriceBO.Fee(0, 0, 0, 0);
|
||||
for (CalcOrderPriceBO.ItemGroup itemGroup : calcOrderPriceBO.getItemGroups()) {
|
||||
int originalTotal = 0;
|
||||
for (CalcOrderPriceBO.Item item : itemGroup.getItems()) {
|
||||
if (!item.getSelected()) { // 未选中,则不计算到其中
|
||||
continue;
|
||||
}
|
||||
originalTotal += item.getPrice() * item.getBuyQuantity();
|
||||
}
|
||||
fee.setOriginalTotal(fee.getOriginalTotal() + originalTotal);
|
||||
fee.setPresentTotal(fee.getOriginalTotal()); // TODO 芋艿,后续要计算优惠价格
|
||||
}
|
||||
calcOrderPriceBO.setFee(fee);
|
||||
// 返回
|
||||
return CommonResult.success(calcOrderPriceBO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<CartBO> details(Integer userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<OrderCreateBO> createOrder(Integer userId) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -157,11 +157,6 @@ public class OrderServiceImpl implements OrderService {
|
||||
return CommonResult.success(orderRecipientBO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalcOrderPriceBO calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<OrderCreateBO> createOrder(OrderCreateDTO orderCreateDTO) {
|
||||
|
||||
Reference in New Issue
Block a user