1. 订单服务,修改为交易服务

2. 迁移订单创建 rpc 接口
This commit is contained in:
YunaiV 2020-11-26 18:40:07 +08:00
parent 8f8f4d72b5
commit db4ee1ed7e
122 changed files with 1499 additions and 4067 deletions

View File

@ -48,4 +48,8 @@ public class CollectionUtils {
return org.springframework.util.CollectionUtils.containsAny(source, candidates);
}
public static <T> T getFirst(List<T> from) {
return !isEmpty(from) ? from.get(0) : null;
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>order</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-service-impl</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-sdk</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>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>pay-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>order-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>promotion-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Registry 和 Config 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Transaction 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</dependency>
<!-- MQ 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
</dependency>
<!-- Job 相关 -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,41 +0,0 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.common.framework.dataobject.BaseDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 订单关闭
*
* - 注意订单只有在用户为付款前取消
*
* - 取消订单这里是取消整个订单不能对订单 item 单独做取消
*
* @author Sin
* @time 2019-03-30 16:20
*/
@Data
@Accessors(chain = true)
public class OrderCancelDO extends BaseDO {
/**
* id
*/
private Integer id;
/**
* 订单id
*/
private Integer orderId;
/**
* 订单编号
*/
private String orderNo;
/**
* 关闭订单原因字典
*/
private Integer reason;
/**
* 原因如果选择其他原因保存在这
*/
private String otherReason;
}

View File

@ -1,105 +0,0 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 订单
*
* @author Sin
* @time 2019-03-16 13:49
*/
@Data
@Accessors(chain = true)
@TableName(value = "orders")
public class OrderDO extends DeletableDO {
/**
* id
*/
private Integer id;
/**
* 用户编号
*/
private Integer userId;
/**
* 订单编号
*/
private String orderNo;
/**
* 购买商品总金额单位
*/
private Integer buyPrice;
/**
* 优惠总金额单位
*/
private Integer discountPrice;
/**
* 物流金额 ()
*/
private Integer logisticsPrice;
/**
* 最终金额单位
*
* buyPrice + logisticsPrice - discountPrice = presentPrice
*/
private Integer presentPrice;
/**
* 实际已支付金额单位
*
* 初始时金额为 0 等到支付成功后会进行更新
*/
private Integer payAmount;
///
/// 时间信息
/**
* 付款时间待发货
*/
private Date paymentTime;
/**
* 发货时间待收货
*/
private Date deliveryTime;
/**
* 收货时间已签收
*/
private Date receiverTime;
/**
* 成交时间用户确认收货 -> status = 已完成
*/
private Date closingTime;
///
/// 其他
/**
* 是否退货
*
* - 1没有
* - 2换货
* - 3退货
* - 4换货 + 退货
*/
private Integer hasReturnExchange;
/**
* 状态(如果有多个商品分开发货需要全部商品发完才会改变状态)
*
* - 1待付款
* - 2待发货
* - 3待收获
* - 4已完成
* - 5已关闭
*/
private Integer status;
/**
* 备注
*/
private String remark;
}

View File

@ -1,144 +0,0 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 订单 item
*
* @author Sin
* @time 2019-03-16 14:03
*/
@Data
@Accessors(chain = true)
public class OrderItemDO extends DeletableDO {
/**
* 编号
*/
private Integer id;
/**
* 订单编号
*/
private Integer orderId;
/**
* 订单号
*/
private String orderNo;
/**
* 商品编号
*/
private Integer skuId;
/**
* 物流id
*/
private Integer orderLogisticsId;
/**
* 商品名称
*/
private String skuName;
/**
* 商品图片
*/
private String skuImage;
/**
* 数量
*/
private Integer quantity;
/**
* 原始单价单位
*/
private Integer originPrice;
/**
* 购买单价单位
*/
private Integer buyPrice;
/**
* 最终价格单位
*/
private Integer presentPrice;
/**
* 购买总金额单位
*
* 用途类似 {@link #presentTotal}
*/
private Integer buyTotal;
/**
* 优惠总金额单位
*/
private Integer discountTotal;
/**
* 最终总金额单位
*
* 注意presentPrice * quantity 不一定等于 presentTotal
* 因为存在无法整除的情况
* 举个例子presentPrice = 8.33 quantity = 3 的情况presentTotal 有可能是 24.99 也可能是 25
* 所以需要存储一个该字段
*/
private Integer presentTotal;
// 如上字段举个例子
// 假设购买三个 quantity = 3
// originPrice = 15
// 使用限时折扣单品优惠8 buyPrice = 12
// 开始算总的价格
// buyTotal = buyPrice * quantity = 12 * 3 = 36
// discountTotal 假设有满减送分组优惠 20 10 并且使用优惠劵满 1.01 1 discountTotal = 10 + 1 = 11
// presentTotal = buyTotal - discountTotal = 24 - 11 = 13
// 最终 presentPrice = presentTotal / quantity = 13 / 3 = 4.33
///
/// 时间信息
/**
* 付款时间
*/
private Date paymentTime;
/**
* 发货时间
*/
private Date deliveryTime;
/**
* 收货时间
*/
private Date receiverTime;
/**
* 成交时间
*/
private Date closingTime;
///
/// 其他
/**
* 是否退货
*
* - 1没有
* - 2换货
* - 3退货
* - 4换货 + 退货
*/
private Integer hasReturnExchange;
/**
* 发货方式
*
* - 1 未选择
* - 2 在线下单
* - 3 自己联系快递
* - 4 无物流
*/
private Integer deliveryType;
/**
* 状态
*
* - 1待付款
* - 2待发货
* - 3已发货
* - 4已完成
* - 5已关闭
*/
private Integer status;
}

View File

@ -1,48 +0,0 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.common.framework.dataobject.BaseDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 订单收件人信息 order_recipient (配送信息)
*
* @author Sin
* @time 2019-03-31 11:37
*/
@Data
@Accessors(chain = true)
public class OrderRecipientDO extends BaseDO {
/**
* 编号
*/
private Integer id;
/**
* 订单id
*/
private Integer orderId;
/**
* 收件区域编号
*/
private String areaNo;
/**
* 收件人名称
*/
private String name;
/**
* 收件手机号
*/
private String mobile;
/**
* 配送类型
*
* - 1 快递
*/
private Integer type;
/**
* 收件详细地址
*/
private String address;
}

View File

@ -210,151 +210,6 @@ public class OrderServiceImpl implements OrderService {
return CommonResult.success(orderInfoBO);
}
@Override
@GlobalTransactional
// @Transactional // 使用 Seata 分布事务后无需在使用 @Transactional 注解
public CommonResult<OrderCreateBO> createOrder(OrderCreateDTO orderCreateDTO) {
Integer userId = orderCreateDTO.getUserId();
List<OrderCreateDTO.OrderItem> orderItemDTOList = orderCreateDTO.getOrderItems();
List<OrderItemDO> orderItemDOList = OrderItemConvert.INSTANCE.convert(orderItemDTOList);
// 获取商品信息
Set<Integer> skuIds = orderItemDOList.stream().map(OrderItemDO::getSkuId).collect(Collectors.toSet());
List<ProductSkuDetailBO> productList = productSpuService.getProductSkuDetailList(skuIds);
if (orderItemDTOList.size() != productList.size()) { // 校验获得的数量是否匹配
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_GOODS_INFO_INCORRECT.getCode());
}
// 价格计算
CalcOrderPriceBO calcOrderPrice = calcOrderPrice(productList, orderCreateDTO);
// 设置 orderItem
Map<Integer, ProductSkuDetailBO> productSpuBOMap = productList
.stream().collect(Collectors.toMap(ProductSkuDetailBO::getId, o -> o)); // 商品 SKU 信息的集合
Map<Integer, CalcOrderPriceBO.Item> priceItemMap = new HashMap<>(); // 商品 SKU 价格的映射
calcOrderPrice.getItemGroups().forEach(itemGroup ->
itemGroup.getItems().forEach(item -> priceItemMap.put(item.getId(), item)));
// 遍历 orderItemDOList 数组将商品信息商品价格设置到其中
for (OrderItemDO orderItemDO : orderItemDOList) {
ProductSkuDetailBO productSkuDetailBO = productSpuBOMap.get(orderItemDO.getSkuId());
if (productSkuDetailBO.getQuantity() <= 0) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_INSUFFICIENT_INVENTORY.getCode());
}
if (productSkuDetailBO.getPrice() <= 0) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GOODS_AMOUNT_INCORRECT.getCode());
}
// 设置 SKU 信息
orderItemDO.setSkuImage(Optional.ofNullable(productSkuDetailBO.getSpu().getPicUrls().get(0)).get());
orderItemDO.setSkuName(productSkuDetailBO.getSpu().getName());
// 设置价格信息
CalcOrderPriceBO.Item priceItem = priceItemMap.get(orderItemDO.getSkuId());
Assert.notNull(priceItem, "商品计算价格为空");
orderItemDO.setOriginPrice(priceItem.getOriginPrice())
.setBuyPrice(priceItem.getBuyPrice())
.setPresentPrice(priceItem.getPresentPrice())
.setBuyTotal(priceItem.getBuyTotal())
.setDiscountTotal(priceItem.getDiscountTotal())
.setPresentTotal(priceItem.getPresentTotal());
}
// 标记优惠劵已使用
if (orderCreateDTO.getCouponCardId() != null) {
couponService.useCouponCard(userId, orderCreateDTO.getCouponCardId());
}
// TODO 芋艿扣除库存
// order
// TODO: 2019-04-11 Sin 订单号需要生成规则
// TODO FROM 芋艿 to 小范可以考虑抽象成一个方法下面几个也是
String orderNo = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
// Integer totalAmount = orderCommon.calculatedAmount(orderItemDOList);
// Integer totalPrice = orderCommon.calculatedPrice(orderItemDOList);
// Integer totalLogisticsPrice = orderCommon.calculatedLogisticsPrice(orderItemDOList);
OrderDO orderDO = new OrderDO()
.setUserId(userId)
.setOrderNo(orderNo)
.setBuyPrice(calcOrderPrice.getFee().getBuyTotal())
.setDiscountPrice(calcOrderPrice.getFee().getDiscountTotal())
.setLogisticsPrice(calcOrderPrice.getFee().getPostageTotal())
.setPresentPrice(calcOrderPrice.getFee().getPresentTotal())
.setPayAmount(0)
.setClosingTime(null)
.setDeliveryTime(null)
.setPaymentTime(null)
.setStatus(OrderStatusEnum.WAITING_PAYMENT.getValue())
.setHasReturnExchange(OrderHasReturnExchangeEnum.NO.getValue())
.setRemark(Optional.ofNullable(orderCreateDTO.getRemark()).orElse(""));
orderDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
// orderDO.setCreateTime(new Date());
// orderDO.setUpdateTime(null);
orderMapper.insert(orderDO);
// 收件人信息
CommonResult<UserAddressBO> userAddressResult = userAddressService.getAddress(userId, orderCreateDTO.getUserAddressId());
if (userAddressResult.isError()) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_USER_ADDRESS_FAIL.getCode());
}
UserAddressBO userAddressBO = userAddressResult.getData();
OrderRecipientDO orderRecipientDO = OrderRecipientConvert.INSTANCE.convert(userAddressBO);
orderRecipientDO
.setOrderId(orderDO.getId())
.setType(OrderRecipientTypeEnum.EXPRESS.getValue())
.setCreateTime(new Date())
.setUpdateTime(null);
orderRecipientMapper.insert(orderRecipientDO);
// order item
orderItemDOList.forEach(orderItemDO -> {
orderItemDO
.setOrderId(orderDO.getId())
.setOrderNo(orderDO.getOrderNo())
.setPaymentTime(null)
.setDeliveryTime(null)
.setReceiverTime(null)
.setClosingTime(null)
.setHasReturnExchange(OrderStatusEnum.WAITING_PAYMENT.getValue())
.setDeliveryType(OrderDeliveryTypeEnum.NONE.getValue())
.setStatus(OrderStatusEnum.WAITING_PAYMENT.getValue())
.setDeleted(DeletedStatusEnum.DELETED_NO.getValue())
.setCreateTime(new Date())
.setUpdateTime(null);
});
// 一次性插入
orderItemMapper.insert(orderItemDOList);
// 创建预订单
createPayTransaction(orderDO, orderItemDOList, orderCreateDTO.getIp());
// if (commonResult.isError()) {
// //手动开启事务回滚
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_PAY_FAIL.getValue());
// }
// TODO: 2019-03-17 Sin 需要发送 创建成果 MQ 消息业务扩展和统计
return CommonResult.success(
new OrderCreateBO()
.setId(orderDO.getId())
.setOrderNo(orderDO.getOrderNo())
.setPayAmount(orderDO.getPayAmount())
);
}
private CalcOrderPriceBO calcOrderPrice(List<ProductSkuDetailBO> skus, OrderCreateDTO orderCreateDTO) {
// 创建计算的 DTO
CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO()
.setUserId(orderCreateDTO.getUserId())
.setItems(new ArrayList<>(skus.size()))
.setCouponCardId(orderCreateDTO.getCouponCardId());
for (OrderCreateDTO.OrderItem item : orderCreateDTO.getOrderItems()) {
calcOrderPriceDTO.getItems().add(new CalcOrderPriceDTO.Item(item.getSkuId(), item.getQuantity(), true));
}
// 执行计算
return cartService.calcOrderPrice(calcOrderPriceDTO);
}
private PayTransactionBO createPayTransaction(OrderDO order, List<OrderItemDO> orderItems, String ip) {
// TODO sin 支付订单 orderSubject 暂时取第一个子订单商品信息
String orderSubject = orderItems.get(0).getSkuName();

View File

@ -1 +0,0 @@
package cn.iocoder.mall.orderservice.manager;

View File

@ -1,46 +0,0 @@
package cn.iocoder.mall.order.biz.enums.cart;
import java.util.Arrays;
public enum CartItemStatusEnum {
ENABLE(1, "正常"),
DELETE_BY_MANUAL(2, "主动删除"),
DELETE_BY_ORDER(3, "下单删除"),
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CartItemStatusEnum::getValue).toArray();
/**
* 状态值
*/
private Integer value;
/**
* 状态名
*/
private String name;
CartItemStatusEnum(Integer value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return value;
}
public CartItemStatusEnum setValue(Integer value) {
this.value = value;
return this;
}
public String getName() {
return name;
}
public CartItemStatusEnum setName(String name) {
this.name = name;
return this;
}
}

View File

@ -1,68 +0,0 @@
package cn.iocoder.mall.order.biz.enums.order;
/**
* 订单错误码
*
* 错误码区间 [1-008-000-000 ~ 1-008-000-000]
*
* @author Sin
* @time 2019-03-23 11:23
*/
public enum OrderErrorCodeEnum {
// order
ORDER_NOT_EXISTENT(1008000000, "获取订单不存在!"),
ORDER_GET_SKU_FAIL(1008000001, "获取商品失败!"),
ORDER_GET_SKU_NOT_EXISTENT(1008000002, "获取的商品不存在!"),
ORDER_PAY_AMOUNT_NOT_NEGATIVE(1008000003, "支付金额不能为负数!"),
ORDER_STATUS_NOT_CANCEL(1008000004, "订单状态不能取消!"),
ORDER_DELIVERY_INCORRECT_DATA(1008000005, "订单发货数据不正确!"),
ORDER_INSUFFICIENT_INVENTORY(1008000006, "库存不足!"),
ORDER_GOODS_AMOUNT_INCORRECT(1008000007, "商品金额非法!"),
ORDER_GET_GOODS_INFO_INCORRECT(1008000008, "获取额商品信息不正确!"),
ORDER_GET_USER_ADDRESS_FAIL(1008000009, "获取用户地址失败!"),
ORDER_GET_PAY_FAIL(1008000010, "调用pay失败!"),
ORDER_NOT_USER_ORDER(1008000011, "不是该用户的订单!"),
ORDER_UNABLE_CONFIRM_ORDER(1008000012, "状态不对不能确认订单!"),
ORDER_CREATE_CART_IS_EMPTY(1008000013, "购物车无选中的商品,无法创建订单"),
ORDER_STATUS_NOT_WAITING_PAYMENT(1008000014, "订单不处于等待支付状态"),
ORDER_PAY_AMOUNT_ERROR(1008000015, "订单金额不正确"),
// order item
ORDER_ITEM_ONLY_ONE(1008000200, "订单Item只有一个!"),
ORDER_ITEM_SOME_NOT_EXISTS(1008000201, "有不存在的商品!"),
// 订单退货
ORDER_RETURN_NO_RETURN_APPLY(1008000400, "未退货申请"),
ORDER_RETURN_NOT_EXISTENT(1008000401, "退货订单不存在"),
ORDER_RETURN_REFUND_FAILED(1008000402, "退款失败"),
// ========== 购物车 ==========
CARD_ITEM_NOT_FOUND(1008003000, "购物车项不存在"),
CARD_ITEM_SKU_NOT_FOUND(1008003001, "商品不存在"),
CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH(1008003002, "商品库存不足"),
// 工具类服务 1008004000
DICT_SERVER_INVOKING_FAIL(1008004000, "字典服务调用失败!"),
ORDER_LOGISTICS_INVOKING_FAIL(1008004001, "订单物流调用失败!"),
;
private final int code;
private final String message;
OrderErrorCodeEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}

View File

@ -1,37 +0,0 @@
package cn.iocoder.mall.order.biz.enums.order;
/**
* 订单 - 是否退换货状态
*
* @author Sin
* @time 2019-03-22 21:34
*/
public enum OrderHasReturnExchangeEnum {
NO(1, "没有"),
RETURN_GOODS(2, "退货"),
EXCHANGE_GOODS(3, "换货"),
RETURN_EXCHANGE_GOODS(4, "退换货");
/**
* 状态值
*/
private Integer value;
/**
* 状态名
*/
private String name;
OrderHasReturnExchangeEnum(Integer value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -1,45 +0,0 @@
package cn.iocoder.mall.order.biz.enums.order;
/**
* 订单退货 status
*
* @author Sin
* @time 2019-03-30 15:56
*/
public enum OrderReturnStatusEnum {
/**
* 状态
*
* - 1退货申请
* - 2申请成功
* - 3申请失败
* - 4退货中
* - 5已收货
* - 6拒绝退款
*/
RETURN_APPLICATION(1, "退货申请"),
APPLICATION_SUCCESSFUL(2, "申请成功"),
APPLICATION_FAIL(3, "申请失败"),
RETURN_IN(4, "退货中"),
ORDER_RECEIPT(5, "确认收货"),
RETURN_SUCCESS(6, "退货成功"),
;
private final int value;
private final String name;
OrderReturnStatusEnum(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -1,31 +0,0 @@
package cn.iocoder.mall.order.biz.enums.order;
/**
* 订单退货 类型
*
* @author Sin
* @time 2019-03-30 15:42
*/
public enum OrderReturnTypeEnum {
ORDER(1, "订单"),
ORDER_ITEM(2, "订单item"),
;
private final int value;
private final String name;
OrderReturnTypeEnum(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.mall.order.biz.enums.order;
/**
* 订单 - status
*
* @author Sin
* @time 2019-03-16 14:06
*/
public enum OrderStatusEnum {
WAITING_PAYMENT(1, "等待付款"),
WAIT_SHIPMENT(2, "等待发货"),
ALREADY_SHIPMENT(3, "已发货"),
COMPLETED(4, "已完成"),
CLOSED(5, "已关闭");
/**
* 状态值
*/
private Integer value;
/**
* 状态名
*/
private String name;
OrderStatusEnum(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -1,6 +0,0 @@
/**
* 该项目主要用于暴露一些共享的枚举类等
*
* 例如说RPC 接口提供错误码给调用方
*/
package cn.iocoder.mall.order.biz;

View File

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>system</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-biz</artifactId>
<dependencies>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>order-biz-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- mongodb 相关-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,28 +0,0 @@
package cn.iocoder.mall.order.biz.config;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@MapperScan("cn.iocoder.mall.order.biz.dao") // 扫描对应的 Mapper 接口
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理为什么使用 proxyTargetClass 参数参见 https://blog.csdn.net/huang_550/article/details/76492600
public class DatabaseConfiguration {
// 数据库连接池 Druid
@Bean
public ISqlInjector sqlInjector() {
return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除
}
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor(); // MyBatis Plus 分页插件
}
}

View File

@ -1,43 +0,0 @@
package cn.iocoder.mall.order.biz.dao.cart;
import cn.iocoder.mall.order.biz.dataobject.CartItemDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface CartMapper {
//
// CartItemDO selectById(@Param("id") Integer id);
//
// List<CartItemDO> selectByIds(@Param("ids") Collection<Integer> ids);
//
// CartItemDO selectByUserIdAndSkuIdAndStatus(@Param("userId") Integer userId,
// @Param("skuId") Integer skuId,
// @Param("status") Integer status);
//
// Integer selectQuantitySumByUserIdAndStatus(@Param("userId") Integer userId,
// @Param("status") Integer status);
//
// List<CartItemDO> selectByUserIdAndStatusAndSelected(@Param("userId") Integer userId,
// @Param("status") Integer status,
// @Param("selected") Boolean selected);
////
//// List<CartItemDO> selectListByTitleLike(@Param("title") String title,
//// @Param("offset") Integer offset,
//// @Param("limit") Integer limit);
//
//// Integer selectCountByTitleLike(@Param("title") String title);
//
// void insert(CartItemDO cartItemDO);
//
// int update(CartItemDO cartItemDO);
//
// int updateQuantity(@Param("id") Integer id,
// @Param("quantityIncr") Integer quantityIncr);
//
// int updateListByUserIdAndSkuId(@Param("userId") Integer userId,
// @Param("skuIds") Collection<Integer> skuIds,
// @Param("selected") Boolean selected,
// @Param("status") Integer status);
}

View File

@ -1,41 +0,0 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.mall.mybatis.core.dataobject.BaseDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 订单关闭
*
* - 注意订单只有在用户为付款前取消
*
* - 取消订单这里是取消整个订单不能对订单 item 单独做取消
*
* @author Sin
* @time 2019-03-30 16:20
*/
@Data
@Accessors(chain = true)
public class OrderCancelDO extends BaseDO {
/**
* id
*/
private Integer id;
/**
* 订单id
*/
private Integer orderId;
/**
* 订单编号
*/
private String orderNo;
/**
* 关闭订单原因字典
*/
private Integer reason;
/**
* 原因如果选择其他原因保存在这
*/
private String otherReason;
}

View File

@ -1,104 +0,0 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 订单
*
* @author Sin
* @time 2019-03-16 13:49
*/
@Data
@Accessors(chain = true)
@TableName(value = "orders")
public class OrderDO extends DeletableDO {
/**
* id
*/
private Integer id;
/**
* 用户编号
*/
private Integer userId;
/**
* 订单编号
*/
private String orderNo;
/**
* 购买商品总金额单位
*/
private Integer buyPrice;
/**
* 优惠总金额单位
*/
private Integer discountPrice;
/**
* 物流金额 ()
*/
private Integer logisticsPrice;
/**
* 最终金额单位
*
* buyPrice + logisticsPrice - discountPrice = presentPrice
*/
private Integer presentPrice;
/**
* 实际已支付金额单位
*
* 初始时金额为 0 等到支付成功后会进行更新
*/
private Integer payAmount;
///
/// 时间信息
/**
* 付款时间待发货
*/
private Date paymentTime;
/**
* 发货时间待收货
*/
private Date deliveryTime;
/**
* 收货时间已签收
*/
private Date receiverTime;
/**
* 成交时间用户确认收货 -> status = 已完成
*/
private Date closingTime;
///
/// 其他
/**
* 是否退货
*
* - 1没有
* - 2换货
* - 3退货
* - 4换货 + 退货
*/
private Integer hasReturnExchange;
/**
* 状态(如果有多个商品分开发货需要全部商品发完才会改变状态)
*
* - 1待付款
* - 2待发货
* - 3待收获
* - 4已完成
* - 5已关闭
*/
private Integer status;
/**
* 备注
*/
private String remark;
}

View File

@ -1,46 +0,0 @@
package cn.iocoder.mall.order.biz.dataobject;
/**
* 订单优惠明细
*/
// TODO 芋艿 后续在完善
public class OrderPreferentialDO {
/**
* 编号
*/
private Integer id;
/**
* 类型
*
* 1 - 促销活动
* 2 - 优惠劵
*/
private Integer type;
// TODO 芋艿 优惠劵编号 or 促销活动编号
/**
* 订单编号
*/
private Integer orderId;
/**
* 商品 SPU 编号
*/
private Integer spuId;
/**
* 商品 SKU 编号
*/
private Integer skuId;
/**
* 商品数量
*/
private Integer quantity;
/**
* 传入时的价格
*/
private Integer originTotal;
/**
* 总优惠价格
*/
private Integer discountTotal;
}

View File

@ -1,48 +0,0 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.mall.mybatis.core.dataobject.BaseDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 订单收件人信息 order_recipient (配送信息)
*
* @author Sin
* @time 2019-03-31 11:37
*/
@Data
@Accessors(chain = true)
public class OrderRecipientDO extends BaseDO {
/**
* 编号
*/
private Integer id;
/**
* 订单id
*/
private Integer orderId;
/**
* 收件区域编号
*/
private String areaNo;
/**
* 收件人名称
*/
private String name;
/**
* 收件手机号
*/
private String mobile;
/**
* 配送类型
*
* - 1 快递
*/
private Integer type;
/**
* 收件详细地址
*/
private String address;
}

View File

@ -1,111 +0,0 @@
package cn.iocoder.mall.order.biz.service;
public interface CartService {
// // ========== 购物车与订单相关的逻辑 ==========
//
// /**
// * 计算订单金额返回计算结果
// *
// * @param calcOrderPriceDTO 计算订单金额 DTO
// * @return 计算订单金额结果
// */
// CalcOrderPriceBO calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO);
//
// /**
// * 计算指定商品 SKU 的金额并返回计算结果
// *
// * TODO 芋艿此处只会计算限时折扣带来的价格变化
// *
// * @param skuId 商品 SKU 编号
// * @return 计算订单金额结果
// */
// CalcSkuPriceBO calcSkuPrice(Integer skuId); // ========== 购物车 Item 的逻辑 ==========
//
// /**
// * 添加商品至购物车
// *
// * @param userId 用户编号
// * @param skuId 商品 SKU 编号
// * @param quantity 数量
// * @return 是否成功
// */
// Boolean add(Integer userId, Integer skuId, Integer quantity);
//
// /**
// * 购物车更新商品数量
// *
// * @param userId 用户编号
// * @param skuId 商品 SKU 编号
// * @param quantity 数量
// * @return 是否成功
// */
// Boolean updateQuantity(Integer userId, Integer skuId, Integer quantity);
//
// /**
// * 购物车更新商品是否选中
// *
// * @param userId 用户编号
// * @param skuIds 商品 SKU 编号数组
// * @param selected 是否选中
// * @return 是否成功
// */
// Boolean updateSelected(Integer userId, Collection<Integer> skuIds, Boolean selected);
//
// /**
// * 购物车删除商品
// *
// * @param userId 用户编号
// * @param skuIds 商品 SKU 编号的数组
// *
// * @return 是否成功
// */
// Boolean deleteList(Integer userId, List<Integer> skuIds);
//
// /**
// * 清空购物车
// *
// * @param userId 用户编号
// * @return 是否成功
// */
// Boolean deleteAll(Integer userId);
//
// /**
// * 查询用户在购物车中的商品数量
// *
// * @param userId 用户编号
// * @return 商品数量
// */
// Integer count(Integer userId);
//
// /**
// * 显示买家购物车中的商品列表并根据 selected 进行过滤
// *
// * @param userId 用户编号
// * @param selected 是否选中若为空则不进行筛选
// * @return 购物车中商品列表信息
// */
// List<CartItemBO> list(Integer userId, @Nullable Boolean selected);
//
// // ========== 购物车与订单相关的逻辑 ==========
//
// /**
// * 计算订单金额返回计算结果
// *
// * @param calcOrderPriceDTO 计算订单金额 DTO
// * @return 计算订单金额结果
// */
// CalcOrderPriceBO calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO);
//
// /**
// * 计算指定商品 SKU 的金额并返回计算结果
// *
// * TODO 芋艿此处只会计算限时折扣带来的价格变化
// *
// * @param skuId 商品 SKU 编号
// * @return 计算订单金额结果
// */
// CalcSkuPriceBO calcSkuPrice(Integer skuId);
}

View File

@ -1,156 +0,0 @@
package cn.iocoder.mall.order.biz.service;
/**
* 订单 service
*
* @author Sin
* @time 2019-03-16 13:15
*/
public interface OrderService {
// /**
// * 订单 page
// *
// * @param orderQueryDTO
// * @return
// */
// CommonResult<OrderPageBO> getOrderPage(OrderQueryDTO orderQueryDTO);
//
// /**
// * 获取订单items
// *
// * @param orderId
// * @return
// */
// CommonResult<List<OrderItemBO>> getOrderItems(Integer orderId);
//
// /**
// * 订单收件人信息
// *
// * @param orderId
// * @return
// */
// CommonResult<OrderRecipientBO> getOrderRecipientBO(Integer orderId);
//
// /**
// * 订单info
// *
// * @param userId
// * @param orderId
// * @return
// */
// CommonResult<OrderInfoBO> info(Integer userId, Integer orderId);
//
// /**
// * 订单 - 创建
// *
// * @param orderCreateDTO
// * @return
// */
// CommonResult<OrderCreateBO> createOrder(OrderCreateDTO orderCreateDTO);
//
// /**
// * 订单item - 更新
// *
// * @param orderItemUpdateDTO
// *
// */
// CommonResult updateOrderItem(OrderItemUpdateDTO orderItemUpdateDTO);
//
// /**
// * 更新订单item - payAmount(实付金额)
// *
// * @param orderId
// * @param orderItemId
// * @param payAmount
// * @return
// */
// CommonResult updateOrderItemPayAmount(Integer orderId, Integer orderItemId, Integer payAmount);
//
// /**
// * 订单 - 取消订单
// *
// * @param orderId
// * @return
// */
// CommonResult cancelOrder(Integer orderId, Integer reasons, String otherReasons);
//
// /**
// * 订单发货
// *
// * @param orderDelivery
// * @return
// */
// CommonResult<OrderRecipientBO> orderDelivery(OrderDeliveryDTO orderDelivery);
//
// /**
// * 更新订单 - 备注
// *
// * @param orderId
// * @param remake
// * @return
// */
// CommonResult updateOrderRemake(Integer orderId, String remake);
//
// /**
// * 删除订单item
// *
// * @param orderItemDeletedDTO
// * @return
// */
// CommonResult deleteOrderItem(OrderItemDeletedDTO orderItemDeletedDTO);
//
// /**
// * 用户确认订单
// *
// * @param userId
// * @param orderId
// * @return
// */
// CommonResult confirmReceiving(Integer userId, Integer orderId);
//
// /**
// * 更新订单 - 收件这信息
// *
// * 包含
// * - 详细地址
// * - 区域编号
// * - 联系人电话
// * - 联系人姓名
// */
// CommonResult updateLogistics(OrderLogisticsUpdateDTO orderLogisticsDTO);
//
// /**
// * 删除订单 // TODO FROM 芋艿 to 小范删除订单不要使用 deleted 字段对于用户是删除实际是隐藏
// *
// * @param id
// */
// CommonResult deleteOrder(Integer id);
//
// /**
// * 更新订单支付成功
// *
// * 如果成功则返回 success
// * 如果失败则返回具体原因
// *
// * @param orderId 订单编号
// * @param payAmount 支付的订单金额
// * @return 支付结果
// */
// String updatePaySuccess(String orderId, Integer payAmount);
//
// /**
// * 监听确认收货
// *
// * mq 更新 status
// */
// CommonResult listenerConfirmGoods();
//
// /**
// * 监听换货
// *
// * mq 更新 status
// */
// CommonResult listenerExchangeGoods();
}

View File

@ -1,488 +0,0 @@
package cn.iocoder.mall.order.biz.service.impl;
import cn.iocoder.mall.order.biz.service.CartService;
import org.springframework.stereotype.Service;
/**
* 购物车服务 Service 实现类
*/
@Service
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.CartService.version}")
public class CartServiceImpl implements CartService {
// @Reference(validation = "true", version = "${dubbo.consumer.PromotionActivityService.version}")
// private ProductSpuService productSpuService;
// @Reference(validation = "true", version = "${dubbo.consumer.PromotionActivityService.version}")
// private PromotionActivityService promotionActivityService;
// @Reference(validation = "true", version = "${dubbo.consumer.CouponService.version}")
// private CouponService couponService;
//
// @Autowired
// private CartMapper cartMapper;
//
// @Override
// @SuppressWarnings("Duplicates")
// public Boolean add(Integer userId, Integer skuId, Integer quantity) {
// // 查询 SKU 是否合法
// ProductSkuBO sku = productSpuService.getProductSku(skuId);
// if (sku == null
// || CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
// throw ServiceExceptionUtil.exception(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
// }
// // TODO 芋艿后续基于商品是否上下架进一步完善
// // 查询 CartItemDO
// CartItemDO item = cartMapper.selectByUserIdAndSkuIdAndStatus(userId, skuId, CartItemStatusEnum.ENABLE.getValue());
// // 存在则进行数量更新
// if (item != null) {
// return updateQuantity0(item, sku, quantity);
// }
// // 不存在则进行插入
// return add0(userId, sku, quantity);
// }
//
// private Boolean add0(Integer userId, ProductSkuBO sku, Integer quantity) {
// // 校验库存
// if (quantity > sku.getQuantity()) {
// throw ServiceExceptionUtil.exception(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
// }
// // 创建 CartItemDO 对象并进行保存
// CartItemDO item = new CartItemDO()
// // 基础字段
// .setStatus(CartItemStatusEnum.ENABLE.getValue()).setSelected(true)
// // 买家信息
// .setUserId(userId)
// // 商品信息
// .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setQuantity(quantity);
// item.setCreateTime(new Date());
// cartMapper.insert(item);
// // 返回成功
// return true;
// }
//
// @Override
// @SuppressWarnings("Duplicates")
// public Boolean updateQuantity(Integer userId, Integer skuId, Integer quantity) {
// // 查询 SKU 是否合法
// ProductSkuBO sku = productSpuService.getProductSku(skuId);
// if (sku == null
// || CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
// throw ServiceExceptionUtil.exception(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
// }
// // 查询 CartItemDO
// CartItemDO item = cartMapper.selectByUserIdAndSkuIdAndStatus(userId, skuId, CartItemStatusEnum.ENABLE.getValue());
// if (item == null) {
// throw ServiceExceptionUtil.exception(OrderErrorCodeEnum.CARD_ITEM_NOT_FOUND.getCode());
// }
// // TODO 芋艿后续基于商品是否上下架进一步完善
// return updateQuantity0(item, sku, quantity);
// }
//
// private Boolean updateQuantity0(CartItemDO item, ProductSkuBO sku, Integer quantity) {
// // 校验库存
// if (item.getQuantity() + quantity > sku.getQuantity()) {
// throw ServiceExceptionUtil.exception(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
// }
// // 更新 CartItemDO
// cartMapper.updateQuantity(item.getId(), quantity);
// // 返回成功
// return true;
// }
//
// @Override
// public Boolean updateSelected(Integer userId, Collection<Integer> skuIds, Boolean selected) {
// // 更新 CartItemDO
// cartMapper.updateListByUserIdAndSkuId(userId, skuIds, selected, null);
// // 返回成功
// return true;
// }
//
// @Override
// public Boolean deleteList(Integer userId, List<Integer> skuIds) {
// // 更新 CartItemDO
// cartMapper.updateListByUserIdAndSkuId(userId, skuIds, null, CartItemStatusEnum.DELETE_BY_MANUAL.getValue());
// // 返回成功
// return true;
// }
//
// @Override
// public Boolean deleteAll(Integer userId) {
// return null;
// }
//
// @Override
// public Integer count(Integer userId) {
// return cartMapper.selectQuantitySumByUserIdAndStatus(userId, CartItemStatusEnum.ENABLE.getValue());
// }
//
// @Override
// public List<CartItemBO> list(Integer userId, Boolean selected) {
// List<CartItemDO> items = cartMapper.selectByUserIdAndStatusAndSelected(userId, CartItemStatusEnum.ENABLE.getValue(), selected);
// return CartConvert.INSTANCE.convert(items);
// }
//
// @Override
// public CalcOrderPriceBO calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO) {
// // TODO 芋艿补充一些表单校验例如说需要传入用户编号
// // 校验商品都存在
// Map<Integer, CalcOrderPriceDTO.Item> calcOrderItemMap = calcOrderPriceDTO.getItems().stream()
// .collect(Collectors.toMap(CalcOrderPriceDTO.Item::getSkuId, item -> item)); // KEYskuId
// List<ProductSkuDetailBO> skus = productSpuService.getProductSkuDetailList(calcOrderItemMap.keySet());
// if (skus.size() != calcOrderPriceDTO.getItems().size()) {
// throw ServiceExceptionUtil.exception(OrderErrorCodeEnum.ORDER_ITEM_SOME_NOT_EXISTS.getCode());
// }
// // TODO 库存相关
// // 查询促销活动
// List<PromotionActivityBO> activityList = promotionActivityService.getPromotionActivityListBySpuIds(
// skus.stream().map(sku -> sku.getSpu().getId()).collect(Collectors.toSet()),
// Collections.singletonList(PromotionActivityStatusEnum.RUN.getValue()));
// // 拼装结果主要是计算价格
// CalcOrderPriceBO calcOrderPriceBO = new CalcOrderPriceBO();
// // 1. 创建初始的每一项的数组
// List<CalcOrderPriceBO.Item> items = initCalcOrderPriceItems(skus, calcOrderItemMap);
// // 2. 计算限时折扣促销
// modifyPriceByTimeLimitDiscount(items, activityList);
// // 3. 计算满减送促销
// List<CalcOrderPriceBO.ItemGroup> itemGroups = groupByFullPrivilege(items, activityList);
// calcOrderPriceBO.setItemGroups(itemGroups);
// // 4. 计算优惠劵
// if (calcOrderPriceDTO.getCouponCardId() != null) {
// Integer result = modifyPriceByCouponCard(calcOrderPriceDTO.getUserId(), calcOrderPriceDTO.getCouponCardId(), itemGroups);
// calcOrderPriceBO.setCouponCardDiscountTotal(result);
// }
// // 5. 计算最终的价格
// int buyTotal = 0;
// int discountTotal = 0;
// int presentTotal = 0;
// for (CalcOrderPriceBO.ItemGroup itemGroup : calcOrderPriceBO.getItemGroups()) {
// 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));
// calcOrderPriceBO.setFee(new CalcOrderPriceBO.Fee(buyTotal, discountTotal, 0, presentTotal));
// // 返回
// return calcOrderPriceBO;
// }
//
// @Override
// @SuppressWarnings("Duplicates")
// public CalcSkuPriceBO calcSkuPrice(Integer skuId) {
// // 查询 SKU 是否合法
// ProductSkuBO sku = productSpuService.getProductSku(skuId);
// if (sku == null
// || CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
// throw ServiceExceptionUtil.exception(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
// }
// // 查询促销活动
// List<PromotionActivityBO> activityList = promotionActivityService.getPromotionActivityListBySpuId(sku.getSpuId(),
// Arrays.asList(PromotionActivityStatusEnum.WAIT.getValue(), PromotionActivityStatusEnum.RUN.getValue()));
// if (activityList.isEmpty()) { // 如果无促销活动则直接返回默认结果即可
// return new CalcSkuPriceBO().setOriginalPrice(sku.getPrice()).setBuyPrice(sku.getPrice());
// }
// // 如果有促销活动则开始做计算 TODO 芋艿因为现在暂时只有限时折扣 + 满减送所以写的比较简单先
// PromotionActivityBO fullPrivilege = findPromotionActivityByType(activityList, PromotionActivityTypeEnum.FULL_PRIVILEGE);
// PromotionActivityBO timeLimitedDiscount = findPromotionActivityByType(activityList, PromotionActivityTypeEnum.TIME_LIMITED_DISCOUNT);
// Integer presentPrice = calcSkuPriceByTimeLimitDiscount(sku, timeLimitedDiscount);
// // 返回结果
// return new CalcSkuPriceBO().setFullPrivilege(fullPrivilege).setTimeLimitedDiscount(timeLimitedDiscount)
// .setOriginalPrice(sku.getPrice()).setBuyPrice(presentPrice);
// }
//
// private List<CalcOrderPriceBO.Item> initCalcOrderPriceItems(List<ProductSkuDetailBO> skus,
// Map<Integer, CalcOrderPriceDTO.Item> calcOrderItemMap) {
// List<CalcOrderPriceBO.Item> items = new ArrayList<>();
// for (ProductSkuDetailBO sku : skus) {
// CalcOrderPriceBO.Item item = CartConvert.INSTANCE.convert(sku);
// items.add(item);
// // 将是否选中购物数量复制到 item
// CalcOrderPriceDTO.Item calcOrderItem = calcOrderItemMap.get(sku.getId());
// item.setSelected(calcOrderItem.getSelected());
// item.setBuyQuantity(calcOrderItem.getQuantity());
// // 计算初始价格
// item.setOriginPrice(sku.getPrice());
// item.setBuyPrice(sku.getPrice());
// item.setPresentPrice(sku.getPrice());
// item.setBuyTotal(sku.getPrice() * calcOrderItem.getQuantity());
// item.setDiscountTotal(0);
// item.setPresentTotal(item.getBuyTotal());
// }
// return items;
// }
//
// private void modifyPriceByTimeLimitDiscount(List<CalcOrderPriceBO.Item> items, List<PromotionActivityBO> activityList) {
// for (CalcOrderPriceBO.Item item : items) {
// // 获得符合条件的限时折扣
// PromotionActivityBO timeLimitedDiscount = activityList.stream()
// .filter(activity -> PromotionActivityTypeEnum.TIME_LIMITED_DISCOUNT.getValue().equals(activity.getActivityType())
// && activity.getTimeLimitedDiscount().getItems().stream().anyMatch(item0 -> item0.getSpuId().equals(item.getSpu().getId())))
// .findFirst().orElse(null);
// if (timeLimitedDiscount == null) {
// continue;
// }
// // 计算价格
// ProductSkuBO sku = new ProductSkuBO().setId(item.getId()).setSpuId(item.getSpu().getId()).setPrice(item.getPrice());
// Integer newPrice = calcSkuPriceByTimeLimitDiscount(sku, timeLimitedDiscount);
// if (newPrice.equals(item.getPrice())) {
// continue;
// }
// // 设置优惠
// item.setActivity(timeLimitedDiscount);
// // 设置价格
// item.setBuyPrice(newPrice);
// item.setBuyTotal(newPrice * item.getBuyQuantity());
// item.setPresentTotal(item.getBuyTotal() - item.getDiscountTotal());
// item.setPresentPrice(item.getPresentTotal() / item.getBuyQuantity());
// }
// }
//
// private List<CalcOrderPriceBO.ItemGroup> groupByFullPrivilege(List<CalcOrderPriceBO.Item> items, List<PromotionActivityBO> activityList) {
// List<CalcOrderPriceBO.ItemGroup> itemGroups = new ArrayList<>();
// // 获得所有满减送促销
// List<PromotionActivityBO> fullPrivileges = activityList.stream()
// .filter(activity -> PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType()))
// .collect(Collectors.toList());
// // 基于满减送促销进行分组
// if (!fullPrivileges.isEmpty()) {
// items = new ArrayList<>(items); // 因为下面会修改数组进行浅拷贝避免影响传入的 items
// for (PromotionActivityBO fullPrivilege : fullPrivileges) {
// // 创建 fullPrivilege 对应的分组
// CalcOrderPriceBO.ItemGroup itemGroup = new CalcOrderPriceBO.ItemGroup()
// .setActivity(fullPrivilege)
// .setItems(new ArrayList<>());
// // 筛选商品到分组中
// for (Iterator<CalcOrderPriceBO.Item> iterator = items.iterator(); iterator.hasNext(); ) {
// CalcOrderPriceBO.Item item = iterator.next();
// if (!isSpuMatchFullPrivilege(item.getSpu().getId(), fullPrivilege)) {
// continue;
// }
// itemGroup.getItems().add(item);
// iterator.remove();
// }
// // 如果匹配到则添加到 itemGroups
// if (!itemGroup.getItems().isEmpty()) {
// itemGroups.add(itemGroup);
// }
// }
// }
// // 处理未参加活动的商品形成一个分组
// if (!items.isEmpty()) {
// itemGroups.add(new CalcOrderPriceBO.ItemGroup().setItems(items));
// }
// // 计算每个分组的价格
// for (CalcOrderPriceBO.ItemGroup itemGroup : itemGroups) {
// itemGroup.setActivityDiscountTotal(calcSkuPriceByFullPrivilege(itemGroup));
// }
// // 返回结果
// return itemGroups;
// }
//
// private Integer modifyPriceByCouponCard(Integer userId, Integer couponCardId, List<CalcOrderPriceBO.ItemGroup> itemGroups) {
// Assert.isTrue(couponCardId != null, "优惠劵编号不能为空");
// // 查询优惠劵
// CouponCardDetailBO couponCard = couponService.getCouponCardDetail(userId, couponCardId);
// // 获得匹配的商品
// List<CalcOrderPriceBO.Item> items = new ArrayList<>();
// if (RangeTypeEnum.ALL.getValue().equals(couponCard.getRangeType())) {
//// totalPrice = spus.stream().mapToInt(spu -> spu.getPrice() * spu.getQuantity()).sum();
// itemGroups.forEach(itemGroup -> items.addAll(itemGroup.getItems()));
// } else if (RangeTypeEnum.PRODUCT_INCLUDE_PART.getValue().equals(couponCard.getRangeType())) {
// itemGroups.forEach(itemGroup -> items.forEach(item -> {
// if (couponCard.getRangeValues().contains(item.getSpu().getId())) {
// items.add(item);
// }
// }));
// } else if (RangeTypeEnum.PRODUCT_EXCLUDE_PART.getValue().equals(couponCard.getRangeType())) {
// itemGroups.forEach(itemGroup -> items.forEach(item -> {
// if (!couponCard.getRangeValues().contains(item.getSpu().getId())) {
// items.add(item);
// }
// }));
// } else if (RangeTypeEnum.CATEGORY_INCLUDE_PART.getValue().equals(couponCard.getRangeType())) {
// itemGroups.forEach(itemGroup -> items.forEach(item -> {
// if (couponCard.getRangeValues().contains(item.getSpu().getCid())) {
// items.add(item);
// }
// }));
// } else if (RangeTypeEnum.CATEGORY_EXCLUDE_PART.getValue().equals(couponCard.getRangeType())) {
// itemGroups.forEach(itemGroup -> items.forEach(item -> {
// if (!couponCard.getRangeValues().contains(item.getSpu().getCid())) {
// items.add(item);
// }
// }));
// }
// // 判断是否符合条件
// int originalTotal = items.stream().mapToInt(CalcOrderPriceBO.Item::getPresentTotal).sum(); // 此处指的是以优惠劵视角的原价
// if (originalTotal == 0 || originalTotal < couponCard.getPriceAvailable()) {
// throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_NOT_MATCH.getCode()); // TODO 芋艿这种情况会出现错误码的提示无法格式化出来另外这块的最佳实践找人讨论下
// }
// // 计算价格
// // 获得到优惠信息进行价格计算
// int presentTotal;
// if (PreferentialTypeEnum.PRICE.getValue().equals(couponCard.getPreferentialType())) { // 减价
// // 计算循环次数这样后续优惠的金额就是相乘了
// presentTotal = originalTotal - couponCard.getPriceOff();
// Assert.isTrue(presentTotal > 0, "计算后,价格为负数:" + presentTotal);
// } else if (PreferentialTypeEnum.DISCOUNT.getValue().equals(couponCard.getPreferentialType())) { // 打折
// presentTotal = originalTotal * couponCard.getPercentOff() / 100;
// if (couponCard.getDiscountPriceLimit() != null // 代表不限制优惠上限
// && originalTotal - presentTotal > couponCard.getDiscountPriceLimit()) {
// presentTotal = originalTotal - couponCard.getDiscountPriceLimit();
// }
// } else {
// throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", couponCard.toString()));
// }
// int discountTotal = originalTotal - presentTotal;
// Assert.isTrue(discountTotal > 0, "计算后,不产生优惠:" + discountTotal);
// // 按比例拆分 presentTotal
// splitDiscountPriceToItems(items, discountTotal, presentTotal);
// // 返回优惠金额
// return originalTotal - presentTotal;
// }
//
// /**
// * 计算指定 SKU 在限时折扣下的价格
// *
// * @param sku SKU
// * @param timeLimitedDiscount 限时折扣促销
// * 传入的该活动要保证该 SKU 在该促销下一定有优惠
// * @return 计算后的价格
// */
// private Integer calcSkuPriceByTimeLimitDiscount(ProductSkuBO sku, PromotionActivityBO timeLimitedDiscount) {
// if (timeLimitedDiscount == null) {
// return sku.getPrice();
// }
// // 获得对应的优惠项
// PromotionActivityBO.TimeLimitedDiscount.Item item = timeLimitedDiscount.getTimeLimitedDiscount().getItems().stream()
// .filter(item0 -> item0.getSpuId().equals(sku.getSpuId()))
// .findFirst().orElse(null);
// if (item == null) {
// throw new IllegalArgumentException(String.format("折扣活动(%s) 不存在商品(%s) 的优惠配置",
// timeLimitedDiscount.toString(), sku.toString()));
// }
// // 计算价格
// if (PreferentialTypeEnum.PRICE.getValue().equals(item.getPreferentialType())) { // 减价
// int presentPrice = sku.getPrice() - item.getPreferentialValue();
// return presentPrice >= 0 ? presentPrice : sku.getPrice(); // 如果计算优惠价格小于 0 则说明无法使用优惠
// }
// if (PreferentialTypeEnum.DISCOUNT.getValue().equals(item.getPreferentialType())) { // 打折
// return sku.getPrice() * item.getPreferentialValue() / 100;
// }
// throw new IllegalArgumentException(String.format("折扣活动(%s) 的优惠类型不正确", timeLimitedDiscount.toString()));
// }
//
// private Integer calcSkuPriceByFullPrivilege(CalcOrderPriceBO.ItemGroup itemGroup) {
// if (itemGroup.getActivity() == null) {
// return null;
// }
// PromotionActivityBO activity = itemGroup.getActivity();
// Assert.isTrue(PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType()),
// "传入的必须的满减送活动必须是满减送");
// // 获得优惠信息
// List<CalcOrderPriceBO.Item> items = itemGroup.getItems().stream().filter(CalcOrderPriceBO.Item::getSelected)
// .collect(Collectors.toList());
// Integer itemCnt = items.stream().mapToInt(CalcOrderPriceBO.Item::getBuyQuantity).sum();
// Integer originalTotal = items.stream().mapToInt(CalcOrderPriceBO.Item::getPresentTotal).sum();
// List<PromotionActivityBO.FullPrivilege.Privilege> privileges = activity.getFullPrivilege().getPrivileges().stream()
// .filter(privilege -> {
// if (MeetTypeEnum.PRICE.getValue().equals(privilege.getMeetType())) {
// return originalTotal >= privilege.getMeetValue();
// }
// if (MeetTypeEnum.QUANTITY.getValue().equals(privilege.getMeetType())) {
// return itemCnt >= privilege.getMeetValue();
// }
// throw new IllegalArgumentException(String.format("满减送活动(%s) 的匹配(%s)不正确", itemGroup.getActivity().toString(), privilege.toString()));
// }).collect(Collectors.toList());
// // 获得不到优惠信息返回原始价格
// if (privileges.isEmpty()) {
// return null;
// }
// // 获得到优惠信息进行价格计算
// PromotionActivityBO.FullPrivilege.Privilege privilege = privileges.get(privileges.size() - 1);
// Integer presentTotal;
// if (PreferentialTypeEnum.PRICE.getValue().equals(privilege.getPreferentialType())) { // 减价
// // 计算循环次数这样后续优惠的金额就是相乘了
// Integer cycleCount = 1;
// if (activity.getFullPrivilege().getCycled()) {
// if (MeetTypeEnum.PRICE.getValue().equals(privilege.getMeetType())) {
// cycleCount = originalTotal / privilege.getMeetValue();
// } else if (MeetTypeEnum.QUANTITY.getValue().equals(privilege.getMeetType())) {
// cycleCount = itemCnt / privilege.getMeetValue();
// }
// }
// presentTotal = originalTotal - cycleCount * privilege.getMeetValue();
// if (presentTotal < 0) { // 如果计算优惠价格小于 0 则说明无法使用优惠
// presentTotal = originalTotal;
// }
// } else if (PreferentialTypeEnum.DISCOUNT.getValue().equals(privilege.getPreferentialType())) { // 打折
// presentTotal = originalTotal * privilege.getPreferentialValue() / 100;
// } else {
// throw new IllegalArgumentException(String.format("满减送促销(%s) 的优惠类型不正确", activity.toString()));
// }
// int discountTotal = originalTotal - presentTotal;
// if (discountTotal == 0) {
// return null;
// }
// // 按比例拆分 presentTotal
//// for (int i = 0; i < items.size(); i++) {
//// CalcOrderPriceBO.Item item = items.get(i);
//// Integer discountPart;
//// if (i < items.size() - 1) { // 减一的原因是因为拆分时如果按照比例可能会出现.所以最后一个使用反减
//// discountPart = (int) (discountTotal * (1.0D * item.getPresentTotal() / presentTotal));
//// discountTotal -= discountPart;
//// } else {
//// discountPart = discountTotal;
//// }
//// Assert.isTrue(discountPart > 0, "优惠金额必须大于 0");
//// item.setDiscountTotal(item.getDiscountTotal() + discountPart);
//// item.setPresentTotal(item.getBuyTotal() - item.getDiscountTotal());
//// item.setPresentPrice(item.getPresentTotal() / item.getBuyQuantity());
//// }
// splitDiscountPriceToItems(items, discountTotal, presentTotal);
// // 返回优惠金额
// return originalTotal - presentTotal;
// }
//
// private void splitDiscountPriceToItems(List<CalcOrderPriceBO.Item> items, Integer discountTotal, Integer presentTotal) {
// for (int i = 0; i < items.size(); i++) {
// CalcOrderPriceBO.Item item = items.get(i);
// Integer discountPart;
// if (i < items.size() - 1) { // 减一的原因是因为拆分时如果按照比例可能会出现.所以最后一个使用反减
// discountPart = (int) (discountTotal * (1.0D * item.getPresentTotal() / presentTotal));
// discountTotal -= discountPart;
// } else {
// discountPart = discountTotal;
// }
// Assert.isTrue(discountPart > 0, "优惠金额必须大于 0");
// item.setDiscountTotal(item.getDiscountTotal() + discountPart);
// item.setPresentTotal(item.getBuyTotal() - item.getDiscountTotal());
// item.setPresentPrice(item.getPresentTotal() / item.getBuyQuantity());
// }
// }
//
// private PromotionActivityBO findPromotionActivityByType(List<PromotionActivityBO> activityList, PromotionActivityTypeEnum type) {
// return activityList.stream()
// .filter(activity -> type.getValue().equals(activity.getActivityType()))
// .findFirst().orElse(null);
// }
//
// private List<PromotionActivityBO> findPromotionActivityListByType(List<PromotionActivityBO> activityList, PromotionActivityTypeEnum type) {
// return activityList.stream()
// .filter(activity -> type.getValue().equals(activity.getActivityType()))
// .collect(Collectors.toList());
// }
//
// private boolean isSpuMatchFullPrivilege(Integer spuId, PromotionActivityBO activity) {
// Assert.isTrue(PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType()),
// "传入的必须的促销活动必须是满减送");
// PromotionActivityBO.FullPrivilege fullPrivilege = activity.getFullPrivilege();
// if (RangeTypeEnum.ALL.getValue().equals(fullPrivilege.getRangeType())) {
// return true;
// } else if (RangeTypeEnum.PRODUCT_INCLUDE_PART.getValue().equals(fullPrivilege.getRangeType())) {
// return fullPrivilege.getRangeValues().contains(spuId);
// } else {
// throw new IllegalArgumentException(String.format("促销活动(%s) 可用范围的类型是不正确", activity.toString()));
// }
// }
}

View File

@ -1,604 +0,0 @@
package cn.iocoder.mall.order.biz.service.impl;
import cn.iocoder.mall.order.biz.service.OrderService;
import org.springframework.stereotype.Service;
/**
* 订单 service impl
*
* @author Sin
* @time 2019-03-16 15:08
*/
@Service
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.OrderService.version}")
public class OrderServiceImpl implements OrderService {
// /**
// * 支付过期时间 120 分钟
// */
// public static final int PAY_EXPIRE_TIME = 120;
//
// @Autowired
// private OrderMapper orderMapper;
// @Autowired
// private OrderItemMapper orderItemMapper;
// @Autowired
// private OrderLogisticsMapper orderLogisticsMapper;
// @Autowired
// private OrderLogisticsDetailMapper orderLogisticsDetailMapper;
// @Autowired
// private OrderRecipientMapper orderRecipientMapper;
// @Autowired
// private OrderCancelMapper orderCancelMapper;
// @Autowired
// private OrderReturnMapper orderReturnMapper;
//
// @Autowired
// private CartServiceImpl cartService;
//
// @Reference(validation = "true", version = "${dubbo.consumer.PromotionActivityService.version}")
// private ProductSpuService productSpuService;
// @Reference(validation = "true", version = "${dubbo.consumer.UserAddressService.version}")
// private UserAddressService userAddressService;
// @Reference(validation = "true", version = "${dubbo.consumer.PayTransactionService.version}")
// private PayTransactionService payTransactionService;
// @Reference(validation = "true", version = "${dubbo.consumer.CouponService.version}")
// private CouponService couponService;
//
// @Override
// public CommonResult<OrderPageBO> getOrderPage(OrderQueryDTO orderQueryDTO) {
//
// int totalCount = orderMapper.selectPageCount(orderQueryDTO);
// if (totalCount == 0) { // TODO FROM 芋艿 TO 小范 Collections.EMPTY_LIST 改成 Collections.emptyList()
// return CommonResult.success(new OrderPageBO().setOrders(Collections.EMPTY_LIST).setTotal(0));
// }
//
// // 获取订单数据
// List<OrderDO> orderDOList = orderMapper.selectPage(orderQueryDTO);
//
// if (CollectionUtils.isEmpty(orderDOList)) {
// return CommonResult.success(new OrderPageBO().setOrders(Collections.EMPTY_LIST).setTotal(totalCount));
// }
//
// // 获取订单 id
// Set<Integer> orderIds = orderDOList.stream()
// .map(orderDO -> orderDO.getId()) // TODO FROM 芋艿 to 小范记得用 Lambda
// .collect(Collectors.toSet());
//
// // 获取配送信息
// List<OrderRecipientDO> orderRecipientDOList = orderRecipientMapper.selectByOrderIds(orderIds);
// List<OrderRecipientBO> orderRecipientBOList = OrderRecipientConvert.INSTANCE.convert(orderRecipientDOList);
// Map<Integer, OrderRecipientBO> orderRecipientBOMap
// = orderRecipientBOList.stream().collect(Collectors.toMap(OrderRecipientBO::getOrderId, obj -> obj));
//
// // 获取 订单的 items
// List<OrderItemDO> orderItemDOList = orderItemMapper
// .selectByDeletedAndOrderIds(orderIds, DeletedStatusEnum.DELETED_NO.getValue());
//
// List<OrderItemBO> orderItemBOList = OrderItemConvert.INSTANCE.convertOrderItemDO(orderItemDOList);
// Map<Integer, List<OrderItemBO>> orderItemBOMultimap = orderItemBOList.stream().collect(
// Collectors.toMap(
// OrderItemBO::getOrderId,
// item -> Lists.newArrayList(item),
// (oldVal, newVal) -> {
// oldVal.addAll(newVal);
// return oldVal;
// }
// )
// );
//
// // 转换 orderDO OrderBO并设置 item
// List<OrderBO> orderPageBOList = OrderConvert.INSTANCE.convertPageBO(orderDOList);
// List<OrderBO> result = orderPageBOList.stream().map(orderBO -> {
// if (orderItemBOMultimap.containsKey(orderBO.getId())) {
// orderBO.setOrderItems(orderItemBOMultimap.get(orderBO.getId()));
// }
// if (orderRecipientBOMap.containsKey(orderBO.getId())) {
// orderBO.setOrderRecipient(orderRecipientBOMap.get(orderBO.getId()));
// }
// return orderBO;
// }).collect(Collectors.toList());
// return CommonResult.success(
// new OrderPageBO()
// .setTotal(totalCount)
// .setOrders(result)
// );
// }
//
// @Override
// public CommonResult<List<OrderItemBO>> getOrderItems(Integer orderId) {
// if (orderMapper.selectById(orderId) == null) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode());
// }
//
// List<OrderItemDO> orderItemDOList = orderItemMapper
// .selectByDeletedAndOrderId(DeletedStatusEnum.DELETED_NO.getValue(), orderId);
//
// List<OrderItemBO> orderItemBOList = OrderItemConvert.INSTANCE.convertOrderItemBO(orderItemDOList);
// return CommonResult.success(orderItemBOList);
// }
//
// @Override
// public CommonResult<OrderRecipientBO> getOrderRecipientBO(Integer orderId) {
// if (orderMapper.selectById(orderId) == null) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode());
// }
//
// OrderRecipientDO orderRecipientDO = orderRecipientMapper.selectByOrderId(orderId);
// OrderRecipientBO orderRecipientBO = OrderRecipientConvert.INSTANCE.convert(orderRecipientDO);
// return CommonResult.success(orderRecipientBO);
// }
//
// @Override
// public CommonResult<OrderInfoBO> info(Integer userId, Integer orderId) {
// OrderDO orderDO = orderMapper.selectById(orderId);
// if (orderDO == null) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode());
// }
//
// List<OrderItemDO> itemDOList = orderItemMapper
// .selectByDeletedAndOrderId(DeletedStatusEnum.DELETED_NO.getValue(), orderId);
//
// List<OrderInfoBO.OrderItem> orderItems
// = OrderItemConvert.INSTANCE.convertOrderInfoWithOrderItem(itemDOList);
//
// Set<Integer> orderLogisticsIds = itemDOList.stream()
// .filter(o -> o.getOrderLogisticsId() != null)
// .map(o -> o.getOrderLogisticsId())
// .collect(Collectors.toSet());
//
//
//
// // 收件人信息
// OrderRecipientDO orderRecipientDO = orderRecipientMapper.selectByOrderId(orderId);
//
// // 订单物流信息
// OrderLogisticsDetailDO orderLogisticsDetailDO = null;
// if (!CollectionUtils.isEmpty(orderLogisticsIds)) {
// orderLogisticsDetailDO = orderLogisticsDetailMapper.selectLast(orderLogisticsIds);
// }
//
// // 检查是否申请退货
// OrderReturnDO orderReturnDO = orderReturnMapper.selectByOrderId(orderId);
//
// // convert 信息
// OrderInfoBO.LogisticsDetail logisticsDetail
// = OrderLogisticsDetailConvert.INSTANCE.convertLogisticsDetail(orderLogisticsDetailDO);
//
// OrderInfoBO.Recipient recipient = OrderRecipientConvert.INSTANCE.convertOrderInfoRecipient(orderRecipientDO);
// OrderInfoBO orderInfoBO = OrderConvert.INSTANCE.convert(orderDO);
// orderInfoBO.setRecipient(recipient);
// orderInfoBO.setOrderItems(orderItems);
// orderInfoBO.setLatestLogisticsDetail(logisticsDetail);
//
// // 是否退货
// if (orderReturnDO != null) {
// orderInfoBO.setHasOrderReturn(orderReturnDO.getStatus());
// } else {
// orderInfoBO.setHasOrderReturn(-1);
// }
// return CommonResult.success(orderInfoBO);
// }
//
// @Override
// @GlobalTransactional
//// @Transactional // 使用 Seata 分布事务后无需在使用 @Transactional 注解
// public CommonResult<OrderCreateBO> createOrder(OrderCreateDTO orderCreateDTO) {
// Integer userId = orderCreateDTO.getUserId();
// List<OrderCreateDTO.OrderItem> orderItemDTOList = orderCreateDTO.getOrderItems();
// List<OrderItemDO> orderItemDOList = OrderItemConvert.INSTANCE.convert(orderItemDTOList);
//
// // 获取商品信息
// Set<Integer> skuIds = orderItemDOList.stream().map(OrderItemDO::getSkuId).collect(Collectors.toSet());
// List<ProductSkuDetailBO> productList = productSpuService.getProductSkuDetailList(skuIds);
// if (orderItemDTOList.size() != productList.size()) { // 校验获得的数量是否匹配
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_GOODS_INFO_INCORRECT.getCode());
// }
//
// // 价格计算
// CalcOrderPriceBO calcOrderPrice = calcOrderPrice(productList, orderCreateDTO);
//
// // 设置 orderItem
// Map<Integer, ProductSkuDetailBO> productSpuBOMap = productList
// .stream().collect(Collectors.toMap(ProductSkuDetailBO::getId, o -> o)); // 商品 SKU 信息的集合
// Map<Integer, CalcOrderPriceBO.Item> priceItemMap = new HashMap<>(); // 商品 SKU 价格的映射
// calcOrderPrice.getItemGroups().forEach(itemGroup ->
// itemGroup.getItems().forEach(item -> priceItemMap.put(item.getId(), item)));
// // 遍历 orderItemDOList 数组将商品信息商品价格设置到其中
// for (OrderItemDO orderItemDO : orderItemDOList) {
// ProductSkuDetailBO productSkuDetailBO = productSpuBOMap.get(orderItemDO.getSkuId());
// if (productSkuDetailBO.getQuantity() <= 0) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_INSUFFICIENT_INVENTORY.getCode());
// }
// if (productSkuDetailBO.getPrice() <= 0) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GOODS_AMOUNT_INCORRECT.getCode());
// }
// // 设置 SKU 信息
// orderItemDO.setSkuImage(Optional.ofNullable(productSkuDetailBO.getSpu().getPicUrls().get(0)).get());
// orderItemDO.setSkuName(productSkuDetailBO.getSpu().getName());
// // 设置价格信息
// CalcOrderPriceBO.Item priceItem = priceItemMap.get(orderItemDO.getSkuId());
// Assert.notNull(priceItem, "商品计算价格为空");
// orderItemDO.setOriginPrice(priceItem.getOriginPrice())
// .setBuyPrice(priceItem.getBuyPrice())
// .setPresentPrice(priceItem.getPresentPrice())
// .setBuyTotal(priceItem.getBuyTotal())
// .setDiscountTotal(priceItem.getDiscountTotal())
// .setPresentTotal(priceItem.getPresentTotal());
// }
//
// // 标记优惠劵已使用
// if (orderCreateDTO.getCouponCardId() != null) {
// couponService.useCouponCard(userId, orderCreateDTO.getCouponCardId());
// }
//
// // TODO 芋艿扣除库存
//
// // order
//
// // TODO: 2019-04-11 Sin 订单号需要生成规则
// // TODO FROM 芋艿 to 小范可以考虑抽象成一个方法下面几个也是
// String orderNo = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
//// Integer totalAmount = orderCommon.calculatedAmount(orderItemDOList);
//// Integer totalPrice = orderCommon.calculatedPrice(orderItemDOList);
//// Integer totalLogisticsPrice = orderCommon.calculatedLogisticsPrice(orderItemDOList);
// OrderDO orderDO = new OrderDO()
// .setUserId(userId)
// .setOrderNo(orderNo)
// .setBuyPrice(calcOrderPrice.getFee().getBuyTotal())
// .setDiscountPrice(calcOrderPrice.getFee().getDiscountTotal())
// .setLogisticsPrice(calcOrderPrice.getFee().getPostageTotal())
// .setPresentPrice(calcOrderPrice.getFee().getPresentTotal())
// .setPayAmount(0)
// .setClosingTime(null)
// .setDeliveryTime(null)
// .setPaymentTime(null)
// .setStatus(OrderStatusEnum.WAITING_PAYMENT.getValue())
// .setHasReturnExchange(OrderHasReturnExchangeEnum.NO.getValue())
// .setRemark(Optional.ofNullable(orderCreateDTO.getRemark()).orElse(""));
// orderDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
//// orderDO.setCreateTime(new Date());
//// orderDO.setUpdateTime(null);
// orderMapper.insert(orderDO);
//
// // 收件人信息
// CommonResult<UserAddressBO> userAddressResult = userAddressService.getAddress(userId, orderCreateDTO.getUserAddressId());
// if (userAddressResult.isError()) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_USER_ADDRESS_FAIL.getCode());
// }
// UserAddressBO userAddressBO = userAddressResult.getData();
// OrderRecipientDO orderRecipientDO = OrderRecipientConvert.INSTANCE.convert(userAddressBO);
// orderRecipientDO
// .setOrderId(orderDO.getId())
// .setType(OrderRecipientTypeEnum.EXPRESS.getValue())
// .setCreateTime(new Date())
// .setUpdateTime(null);
// orderRecipientMapper.insert(orderRecipientDO);
//
// // order item
// orderItemDOList.forEach(orderItemDO -> {
// orderItemDO
// .setOrderId(orderDO.getId())
// .setOrderNo(orderDO.getOrderNo())
// .setPaymentTime(null)
// .setDeliveryTime(null)
// .setReceiverTime(null)
// .setClosingTime(null)
// .setHasReturnExchange(OrderStatusEnum.WAITING_PAYMENT.getValue())
// .setDeliveryType(OrderDeliveryTypeEnum.NONE.getValue())
// .setStatus(OrderStatusEnum.WAITING_PAYMENT.getValue())
// .setDeleted(DeletedStatusEnum.DELETED_NO.getValue())
// .setCreateTime(new Date())
// .setUpdateTime(null);
// });
// // 一次性插入
// orderItemMapper.insert(orderItemDOList);
//
// // 创建预订单
// createPayTransaction(orderDO, orderItemDOList, orderCreateDTO.getIp());
//
//// if (commonResult.isError()) {
//// //手动开启事务回滚
//// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_PAY_FAIL.getValue());
//// }
//
// // TODO: 2019-03-17 Sin 需要发送 创建成果 MQ 消息业务扩展和统计
// return CommonResult.success(
// new OrderCreateBO()
// .setId(orderDO.getId())
// .setOrderNo(orderDO.getOrderNo())
// .setPayAmount(orderDO.getPayAmount())
// );
// }
//
// private CalcOrderPriceBO calcOrderPrice(List<ProductSkuDetailBO> skus, OrderCreateDTO orderCreateDTO) {
// // 创建计算的 DTO
// CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO()
// .setUserId(orderCreateDTO.getUserId())
// .setItems(new ArrayList<>(skus.size()))
// .setCouponCardId(orderCreateDTO.getCouponCardId());
// for (OrderCreateDTO.OrderItem item : orderCreateDTO.getOrderItems()) {
// calcOrderPriceDTO.getItems().add(new CalcOrderPriceDTO.Item(item.getSkuId(), item.getQuantity(), true));
// }
// // 执行计算
// return cartService.calcOrderPrice(calcOrderPriceDTO);
// }
//
// private PayTransactionBO createPayTransaction(OrderDO order, List<OrderItemDO> orderItems, String ip) {
// // TODO sin 支付订单 orderSubject 暂时取第一个子订单商品信息
// String orderSubject = orderItems.get(0).getSkuName();
// Date expireTime = DateUtil.addDate(Calendar.MINUTE, PAY_EXPIRE_TIME);
// return payTransactionService.createTransaction(
// new PayTransactionCreateDTO()
// .setCreateIp(ip)
// .setAppId(PayAppId.APP_ID_SHOP_ORDER)
// .setOrderId(order.getId().toString())
// .setExpireTime(expireTime)
// .setPrice(order.getPresentPrice())
// .setOrderSubject(orderSubject)
// .setOrderMemo("测试备注") // TODO 芋艿后面补充
// .setOrderDescription("测试描述") // TODO 芋艿后面补充
// );
// }
//
// @Override // TODO 芋艿需要确认下这个方法的用途因为涉及修改价格和数量
// public CommonResult updateOrderItem(OrderItemUpdateDTO orderUpdateDTO) {
// OrderItemDO orderItemDO = OrderItemConvert.INSTANCE.convert(orderUpdateDTO);
// orderItemMapper.updateById(orderItemDO);
//
// // TODO: 2019-03-24 sin 需要重新计算金额
// // TODO: 2019-03-24 sin 需要记录日志
// return CommonResult.success(null);
// }
//
// @Override
// @Transactional
// public CommonResult updateOrderItemPayAmount(Integer orderId, Integer orderItemId, Integer payAmount) {
// OrderDO orderDO = orderMapper.selectById(orderId);
// if (orderDO == null) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode());
// }
// if (payAmount < 0) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_PAY_AMOUNT_NOT_NEGATIVE.getCode());
// }
//
// // 先更新金额
// orderItemMapper.updateById(new OrderItemDO().setId(orderItemId)
//// .setPayAmount(payAmount) TODO 芋艿这里要修改
// );
//
// // 再重新计算订单金额
// List<OrderItemDO> orderItemDOList = orderItemMapper
// .selectByDeletedAndOrderId(DeletedStatusEnum.DELETED_NO.getValue(), orderId);
//// Integer price = orderCommon.calculatedPrice(orderItemDOList);
//// Integer amount = orderCommon.calculatedAmount(orderItemDOList);
// Integer price = -1; // TODO 芋艿这里要修改价格
// Integer amount = -1;
// orderMapper.updateById(
// new OrderDO()
// .setId(orderId)
//// .setPrice(price) TODO 芋艿这里要修改
// .setPayAmount(amount)
// );
// return CommonResult.success(null);
// }
//
// @Override
// @Transactional // TODO 芋艿要校验下 userId 不然可以取消任何用户的订单列
// public CommonResult cancelOrder(Integer orderId, Integer reason, String otherReason) {
// // 关闭订单在用户还未付款的时候可操作
// OrderDO orderDO = orderMapper.selectById(orderId);
// if (orderDO == null) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode());
// }
//
// // 检查专题只有待付款状态才能操作
// if (!orderDO.getStatus().equals(OrderStatusEnum.WAITING_PAYMENT.getValue())) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_STATUS_NOT_CANCEL.getCode());
// }
//
// OrderCancelDO orderCancelDO
// = (OrderCancelDO) new OrderCancelDO()
// .setOrderId(orderDO.getId())
// .setOrderNo(orderDO.getOrderNo())
// .setReason(reason)
// .setOtherReason(otherReason)
// .setCreateTime(new Date())
// .setUpdateTime(null);
//
// // 关闭订单修改状态 item
// // TODO FROM 芋艿 TO 小范更新的时候where 里面带下 status 避免并发的问题
// orderItemMapper.updateByOrderId(
// orderId,
// new OrderItemDO().setStatus(OrderStatusEnum.CLOSED.getValue())
// );
//
// // 关闭订单修改状态 order
// orderMapper.updateById(new OrderDO().setId(orderId).setStatus(OrderStatusEnum.CLOSED.getValue()));
// // 保存取消订单原因
// orderCancelMapper.insert(orderCancelDO);
// return CommonResult.success(null);
// }
//
// @Override
// @Transactional // TODO FROM 芋艿 TO 小范泛型一定要明确哈
// public CommonResult orderDelivery(OrderDeliveryDTO orderDelivery) {
// List<Integer> orderItemIds = orderDelivery.getOrderItemIds();
//
// // 获取所有订单 items // TODO FROM 芋艿 TO 小范deleted 是默认条件所以 by 里面可以不带哈
// List<OrderItemDO> allOrderItems = orderItemMapper.selectByDeletedAndOrderId(orderDelivery.getOrderId(), DeletedStatusEnum.DELETED_NO.getValue());
//
// // 当前需要发货订单检查 id status
// List<OrderItemDO> needDeliveryOrderItems = allOrderItems.stream()
// .filter(orderItemDO -> orderItemIds.contains(orderItemDO.getId())
// && OrderStatusEnum.WAIT_SHIPMENT.getValue() == orderItemDO.getStatus())
// .collect(Collectors.toList()); // TODO 芋艿如果这里只是比对数字可以用 Lambda 求和不需要弄成一个集合的
// // 发货订单检查
// if (needDeliveryOrderItems.size() != orderItemIds.size()) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_DELIVERY_INCORRECT_DATA.getCode());
// }
//
// OrderRecipientDO orderRecipientDO = orderRecipientMapper.selectByOrderId(orderDelivery.getOrderId());
// OrderLogisticsDO orderLogisticsDO = OrderLogisticsConvert.INSTANCE.convert(orderRecipientDO);
// // 保存物流信息
// orderLogisticsDO
// .setLogisticsNo(orderDelivery.getLogisticsNo())
// .setLogistics(orderDelivery.getLogistics())
// .setCreateTime(new Date())
// .setUpdateTime(null);
// orderLogisticsMapper.insert(orderLogisticsDO);
//
// // 关联订单item 物流信息
// // TODO FROM 芋艿 TO 小范更新的时候where 里面带下 status 避免并发的问题然后判断下更新数量不对就抛出异常
// orderItemMapper.updateByIds(
// orderItemIds,
// new OrderItemDO()
// .setOrderLogisticsId(orderLogisticsDO.getId())
// .setStatus(OrderStatusEnum.ALREADY_SHIPMENT.getValue())
// );
//
// // 子订单是否全部发货如果发完就更新 order
// List<OrderItemDO> unShippedOrderItems = allOrderItems.stream()
// .filter(orderItemDO -> OrderStatusEnum.WAIT_SHIPMENT.getValue() == orderItemDO.getStatus()
// && !orderItemIds.contains(orderItemDO.getId()))
// .collect(Collectors.toList());
// if (unShippedOrderItems.size() <= 0) {
// // TODO FROM 芋艿 TO 小范更新的时候where 里面带下 status 避免并发的问题
// orderMapper.updateById(
// new OrderDO()
// .setId(orderDelivery.getOrderId())
// .setStatus(OrderStatusEnum.ALREADY_SHIPMENT.getValue())
// );
// }
// // 返回成功
// return CommonResult.success(null);
// }
//
// @Override
// public CommonResult updateOrderRemake(Integer orderId, String remake) {
// // 此处不做订单校验直接设置备注即可
// orderMapper.updateById(new OrderDO().setId(orderId).setRemark(remake));
// return CommonResult.success(null);
// }
//
// @Override
// @Transactional // TODO FROM 芋艿 to 小范先不做这个功能电商一班不存在这个功能哈
// public CommonResult deleteOrderItem(OrderItemDeletedDTO orderItemDeletedDTO) {
// Integer orderId = orderItemDeletedDTO.getOrderId();
// List<Integer> orderItemIds = orderItemDeletedDTO.getOrderItemIds();
//
// // 获取当前有效的订单 item
// List<OrderItemDO> orderItemDOList = orderItemMapper
// .selectByDeletedAndOrderId(DeletedStatusEnum.DELETED_NO.getValue(), orderId);
//
// List<OrderItemDO> effectiveOrderItems = orderItemDOList.stream()
// .filter(orderItemDO -> !orderItemIds.contains(orderItemDO.getId()))
// .collect(Collectors.toList());
//
// // 检查订单 item必须要有一个 item
// if (CollectionUtils.isEmpty(effectiveOrderItems)) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_ITEM_ONLY_ONE.getCode());
// }
//
// // 更新订单 item
// orderItemMapper.updateByIds(
// orderItemIds,
// (OrderItemDO) new OrderItemDO()
// .setDeleted(DeletedStatusEnum.DELETED_YES.getValue())
// );
//
// // 更新订单 amount
//// Integer totalAmount = orderCommon.calculatedAmount(effectiveOrderItems);
// Integer totalAmount = -1; // TODO 芋艿需要修改下价格相关
// orderMapper.updateById(
// new OrderDO()
// .setId(orderId)
// .setPayAmount(totalAmount)
// );
// return CommonResult.success(null);
// }
//
// @Override
// public CommonResult confirmReceiving(Integer userId, Integer orderId) {
// OrderDO orderDO = orderMapper.selectById(orderId);
//
// // 是否该用户的订单
// if (!userId.equals(orderDO.getUserId())) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_USER_ORDER.getCode());
// }
//
// if (OrderStatusEnum.ALREADY_SHIPMENT.getValue() != orderDO.getStatus()) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_UNABLE_CONFIRM_ORDER.getCode());
// }
//
// // TODO FROM 芋艿 TO 小范更新的时候where 里面带下 status 避免并发的问题
// orderMapper.updateById(
// new OrderDO()
// .setId(orderId)
// .setReceiverTime(new Date())
// .setStatus(OrderStatusEnum.COMPLETED.getValue())
//
// );
//
// orderItemMapper.updateByOrderId(
// orderId,
// new OrderItemDO()
// .setStatus(OrderStatusEnum.COMPLETED.getValue())
// .setReceiverTime(new Date())
// );
// return CommonResult.success(null);
// }
//
// @Override
// public CommonResult updateLogistics(OrderLogisticsUpdateDTO orderLogisticsDTO) {
// OrderLogisticsDO orderLogisticsDO = OrderLogisticsConvert.INSTANCE.convert(orderLogisticsDTO);
// orderLogisticsMapper.updateById(orderLogisticsDO);
// return CommonResult.success(null);
// }
//
// @Override
// public CommonResult deleteOrder(Integer id) {
// // 删除订单操作一般用于 用户端删除是否存在检查可以过掉
// orderMapper.updateById((OrderDO) new OrderDO()
// .setId(id)
// .setDeleted(DeletedStatusEnum.DELETED_YES.getValue())
// );
// return CommonResult.success(null);
// }
//
// @Override
// public String updatePaySuccess(String orderId, Integer payAmount) {
// OrderDO order = orderMapper.selectById(Integer.valueOf(orderId));
// if (order == null) { // 订单不存在
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode()).getMessage();
// }
// if (!order.getStatus().equals(OrderStatusEnum.WAITING_PAYMENT.getValue())) { // 状态不处于等待支付
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_STATUS_NOT_WAITING_PAYMENT.getCode()).getMessage();
// }
// if (!order.getPresentPrice().equals(payAmount)) { // 支付金额不正确
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_PAY_AMOUNT_ERROR.getCode()).getMessage();
// }
// // 更新 OrderDO 状态为已支付等待发货
// OrderDO updateOrderObj = new OrderDO()
// .setStatus(OrderStatusEnum.WAIT_SHIPMENT.getValue())
// .setPayAmount(payAmount)
// .setPaymentTime(new Date());
// int updateCount = orderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), updateOrderObj);
// if (updateCount <= 0) {
// return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_STATUS_NOT_WAITING_PAYMENT.getCode()).getMessage();
// }
// // TODO FROM 芋艿 to 小范把更新 OrderItem 给补全
// return "success";
// }
//
// @Override
// public CommonResult listenerConfirmGoods() {
// return null;
// }
//
// @Override
// public CommonResult listenerExchangeGoods() {
// return null;
// }
}

View File

@ -1,25 +0,0 @@
spring:
# 数据源配置项
datasource:
url: jdbc:mysql://s1.iocoder.cn:3306/mall_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 3WLiVUBEwTbvAfsh
#mongodb
data:
mongodb:
uri: mongodb://localhost/order-comment
# MyBatis Plus 配置项
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: cn.iocoder.mall.order.biz.dataobject

View File

@ -1,129 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.order.biz.dao.cart.CartMapper">
<sql id="FIELDS">
id, status, delete_time, selected, user_id,
spu_id, sku_id, quantity, order_id, order_create_time,
create_time
</sql>
<select id="selectById" parameterType="Integer" resultType="CartItemDO">
SELECT
<include refid="FIELDS" />
FROM cart_item
WHERE id = #{id}
-- AND deleted = 0
</select>
<select id="selectByIds" resultType="CartItemDO">
SELECT
<include refid="FIELDS" />
FROM cart_item
WHERE id IN
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
#{id}
</foreach>
-- AND deleted = 0
</select>
<select id="selectByUserIdAndSkuIdAndStatus" resultType="CartItemDO">
SELECT
<include refid="FIELDS" />
FROM cart_item
WHERE user_id = #{userId}
AND sku_id = #{skuId}
AND status = #{status}
-- AND deleted = 0
LIMIT 1
</select>
<select id="selectByUserIdAndStatusAndSelected" resultType="CartItemDO">
SELECT
<include refid="FIELDS" />
FROM cart_item
WHERE user_id = #{userId}
AND status = #{status}
<if test="selected != null">
AND selected = #{selected}
</if>
-- AND deleted = 0
</select>
<select id="selectQuantitySumByUserIdAndStatus" resultType="Integer">
SELECT
SUM(quantity)
FROM cart_item
WHERE user_id = #{userId}
AND status = #{status}
-- AND deleted = 0
</select>
<insert id="insert" parameterType="CartItemDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO cart_item (
status, delete_time, selected, user_id,
spu_id, sku_id, quantity, order_id, order_create_time,
create_time
) VALUES (
#{status}, #{deleteTime}, #{selected}, #{userId},
#{spuId}, #{skuId}, #{quantity}, #{orderId}, #{orderCreateTime},
#{createTime}
)
</insert>
<update id="update" parameterType="CartItemDO">
UPDATE cart_item
<set>
<if test="status != null">
status = #{status},
</if>
<if test="deleteTime != null">
delete_time = #{deleteTime},
</if>
<if test="selected != null">
selected = #{selected},
</if>
<if test="quantity != null">
quantity = #{quantity},
</if>
<if test="orderId != null">
order_id = #{orderId},
</if>
<if test="orderCreateTime != null">
order_create_time = #{orderCreateTime},
</if>
<if test="price != null">
price = #{price},
</if>
<if test="quantity != null">
quantity = #{quantity},
</if>
</set>
WHERE id = #{id}
</update>
<update id="updateQuantity" parameterType="CartItemDO">
UPDATE cart_item
SET quantity = quantity + #{quantityIncr}
WHERE id = #{id}
</update>
<update id="updateListByUserIdAndSkuId">
UPDATE cart_item
<set>
<if test="selected != null">
selected = #{selected},
</if>
<if test="status != null">
status = #{status},
</if>
</set>
WHERE user_id = #{userId}
AND sku_id IN
<foreach item="skuId" collection="skuIds" separator="," open="(" close=")" index="">
#{skuId}
</foreach>
-- AND deleted = 0
</update>
</mapper>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.order.biz.dao.order.OrderCancelMapper">
<sql id="FIELDS">
id, order_id, order_no, reason, other_reason,
create_time, update_time
</sql>
<!--
插入数据
-->
<insert id="insert" parameterType="OrderCancelDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO `order_cancel` (
order_id, order_no, reason, other_reason,
create_time, update_time
) VALUES (
#{orderId}, #{orderNo}, #{reason}, #{otherReason},
#{createTime}, #{updateTime}
)
</insert>
</mapper>

View File

@ -1,172 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.order.biz.dao.order.OrderItemMapper">
<sql id="FIELDS">
id, order_id, order_no, sku_id, sku_name, sku_image, order_logistics_id,
quantity, origin_price, buy_price, present_price, buy_total, discount_total, present_total,
payment_time, delivery_time, receiver_time, closing_time,
has_return_exchange, delivery_type, status,
create_time, update_time, deleted
</sql>
<!--
插入数据
-->
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO `order_item` (
order_id, order_no, sku_id, sku_name, sku_image, order_logistics_id,
quantity, origin_price, buy_price, present_price, buy_total, discount_total, present_total,
payment_time, delivery_time, receiver_time, closing_time,
has_return_exchange, delivery_type, status,
create_time, update_time, deleted
) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.orderId}, #{item.orderNo}, #{item.skuId}, #{item.skuName}, #{item.skuImage}, #{item.orderLogisticsId},
#{item.quantity}, #{item.originPrice}, #{item.buyPrice}, #{item.presentPrice}, #{item.buyTotal}, #{item.discountTotal}, #{item.presentTotal},
#{item.paymentTime}, #{item.deliveryTime}, #{item.receiverTime}, #{item.closingTime},
#{item.hasReturnExchange}, #{item.deliveryType}, #{item.status},
#{item.createTime}, #{item.updateTime}, #{item.deleted})
</foreach>
</insert>
<!--
更新 - 可更新的字段
-->
<sql id="updateFieldSql" >
<set>
<if test="orderItemDO.orderId != null">
, order_id = #{orderItemDO.orderId}
</if>
<if test="orderItemDO.orderNo != null">
, order_no = #{orderItemDO.orderNo}
</if>
<if test="orderItemDO.orderLogisticsId != null">
, order_logistics_id = #{orderItemDO.orderLogisticsId}
</if>
<if test="orderItemDO.skuId != null">
, sku_id = #{orderItemDO.skuId}
</if>
<if test="orderItemDO.skuName != null">
, sku_name = #{orderItemDO.skuName}
</if>
<if test="orderItemDO.skuImage != null">
, sku_image = #{orderItemDO.skuImage}
</if>
<if test="orderItemDO.quantity != null">
, quantity = #{orderItemDO.quantity}
</if>
<!-- TODO 芋艿 需要改 -->
<!-- <if test="orderItemDO.price != null">-->
<!-- , price = #{orderItemDO.price}-->
<!-- </if>-->
<!-- <if test="orderItemDO.payAmount != null">-->
<!-- , pay_amount = #{orderItemDO.payAmount}-->
<!-- </if>-->
<if test="orderItemDO.paymentTime != null">
, payment_time = #{orderItemDO.paymentTime}
</if>
<if test="orderItemDO.deliveryTime != null">
, delivery_time = #{orderItemDO.deliveryTime}
</if>
<if test="orderItemDO.receiverTime != null">
, receiver_time = #{orderItemDO.receiverTime}
</if>
<if test="orderItemDO.closingTime != null">
, closing_time = #{orderItemDO.closingTime}
</if>
<if test="orderItemDO.hasReturnExchange != null">
, has_return_exchange = #{orderItemDO.hasReturnExchange}
</if>
<if test="orderItemDO.status != null">
, status = #{orderItemDO.status}
</if>
<if test="orderItemDO.deliveryType != null">
, delivery_type = #{orderItemDO.deliveryType}
</if>
<if test="orderItemDO.deleted != null">
, `deleted` = #{orderItemDO.deleted}
</if>
<if test="orderItemDO.createTime != null">
, create_time = #{orderItemDO.createTime}
</if>
<if test="orderItemDO.updateTime != null">
, update_time = #{orderItemDO.updateTime}
</if>
</set>
</sql>
<!--
更新 - 根据 id 更新
-->
<update id="updateById" parameterType="OrderDO">
UPDATE `order_item`
<include refid="updateFieldSql" />
WHERE id = #{orderItemDO.id}
</update>
<!--
更新 - 根据 ids 更新
-->
<update id="updateByIds">
UPDATE `order_item`
<include refid="updateFieldSql" />
WHERE id IN
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</update>
<!--
更新 - 根据 orderId
-->
<update id="updateByOrderId">
UPDATE `order_item`
<include refid="updateFieldSql" />
WHERE order_id = #{orderId}
</update>
<!--
获取 - 根据 ids 查询
-->
<select id="selectByIds" resultType="cn.iocoder.mall.order.biz.dataobject.OrderItemDO">
SELECT
<include refid="FIELDS" />
FROM order_item
WHERE `id` IN
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
<!--
查询 - 根据 orderId 下的 item
-->
<select id="selectByDeletedAndOrderId" resultType="cn.iocoder.mall.order.biz.dataobject.OrderItemDO">
SELECT * FROM `order_item`
WHERE 1=1
<if test="deleted != null">
AND deleted = #{deleted}
</if>
<if test="orderId != null">
AND order_id = #{orderId}
</if>
</select>
<!--
查询 - 根据 orderIds 和 status
-->
<select id="selectByDeletedAndOrderIds" resultType="cn.iocoder.mall.order.biz.dataobject.OrderItemDO">
SELECT
<include refid="FIELDS" />
FROM `order_item`
WHERE `deleted` = #{deleted}
AND `order_id`
IN
<foreach collection="orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</select>
</mapper>

View File

@ -1,141 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.order.biz.dao.order.OrderMapper">
<sql id="FIELDS">
id, user_id, order_no, buy_price, discount_price, logistics_price, present_price, pay_amount,
payment_time, delivery_time, receiver_time, closing_time,
has_return_exchange,
status, remark, create_time, update_time, `deleted`
</sql>
<sql id="updateFieldSql" >
<set>
<if test="orderNo != null">
, order_no = #{orderNo}
</if>
<if test="buyPrice != null">
, buy_price = #{buyPrice}
</if>
<if test="discountPrice != null">
, discount_price = #{discountPrice}
</if>
<if test="logisticsPrice != null">
, logistics_price = #{logisticsPrice}
</if>
<if test="logisticsPrice != null">
, logistics_price = #{logisticsPrice}
</if>
<if test="presentPrice != null">
, present_price = #{presentPrice}
</if>
<if test="payAmount != null">
, pay_amount = #{payAmount}
</if>
<if test="deliveryTime != null">
, delivery_time = #{deliveryTime}
</if>
<if test="paymentTime != null">
, payment_time = #{paymentTime}
</if>
<if test="receiverTime != null">
, receiver_time = #{receiverTime}
</if>
<if test="closingTime != null">
, closing_time = #{closingTime}
</if>
<if test="hasReturnExchange != null">
, has_return_exchange = #{hasReturnExchange}
</if>
<if test="status != null">
, status = #{status}
</if>
<if test="remark != null">
, remark = #{remark}
</if>
<if test="deleted != null">
, `deleted` = #{deleted}
</if>
<if test="createTime != null">
, create_time = #{createTime}
</if>
<if test="updateTime != null">
, update_time = #{updateTime}
</if>
</set>
</sql>
<update id="updateById" parameterType="OrderDO">
UPDATE `orders`
<include refid="updateFieldSql" />
WHERE id = #{id}
</update>
<update id="updateByIdAndStatus">
UPDATE `orders`
<set>
<if test="updateObj.payAmount != null">
, pay_amount = #{updateObj.payAmount}
</if>
<if test="updateObj.paymentTime != null">
, payment_time = #{updateObj.paymentTime}
</if>
<if test="updateObj.status != null">
, status = #{updateObj.status}
</if>
</set>
WHERE id = #{id}
AND status = #{status}
</update>
<select id="selectById" resultType="cn.iocoder.mall.order.biz.dataobject.OrderDO">
SELECT
<include refid="FIELDS" />
FROM `orders`
WHERE id = #{id}
</select>
<sql id="selectWhere">
<if test="status != null">
AND `status` = #{status}
</if>
<if test="userId != null">
AND `user_id` = #{userId}
</if>
<if test="id != null">
AND `id` = #{id}
</if>
<if test="orderNo != null">
AND `order_no` = #{orderNo}
</if>
<if test="hasReturnExchange != null">
AND `has_return_exchange` = #{hasReturnExchange}
</if>
<if test="startCreateTime != null and endCreateTime != null">
AND `create_time` &gt;= #{startCreateTime}
AND `create_time` &lt;= #{endCreateTime}
</if>
</sql>
<select id="selectPageCount" resultType="java.lang.Integer">
SELECT
COUNT(*)
FROM `orders`
<where>
<include refid="selectWhere" />
</where>
</select>
<select id="selectPage" resultType="cn.iocoder.mall.order.biz.dataobject.OrderDO">
SELECT
<include refid="FIELDS" />
FROM `orders`
<where>
<include refid="selectWhere" />
</where>
LIMIT ${pageNo * pageSize}, ${pageSize}
</select>
</mapper>

View File

@ -1,58 +0,0 @@
package cn.iocoder.mall.order.rest.request.users;
import java.io.Serializable;
import java.util.List;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 订单创建
*
* @author Sin
* @time 2019-03-16 14:42
*/
@Data
@Accessors(chain = true)
public class OrderCreateRequest implements Serializable {
/**
* 收件手机号
*/
@NotNull(message = "用户地址id不能为空!")
private Integer userAddressId;
/**
* 优惠劵编号
*/
private Integer couponCardId;
/**
* 备注
*/
private String remark;
///
/// order item
@NotNull()
@Size(max = 1000, min = 1, message = "用户订单中没有商品!")
private List<OrderItem> orderItems;
@Data
@Accessors(chain = true)
public static class OrderItem {
/**
* 商品编号
*/
@NotNull
private Integer skuId;
/**
* 数量
*/
@NotNull
@Max(value = 1000)
private Integer quantity;
}
}

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>order</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-service-api02</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>product-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>promotion-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,41 +0,0 @@
package cn.iocoder.mall.order.api.constant;
/**
* 物流信息
*
* @author Sin
* @time 2019-03-30 22:33
*/
public enum LogisticsEnum {
LOGISTICS_1(1, "顺丰快递"),
LOGISTICS_2(2, "圆通快递"),
LOGISTICS_3(3, "申通快递"),
LOGISTICS_4(4, "韵答快递"),
LOGISTICS_5(5, "天天快递"),
LOGISTICS_6(6, "EMS中国邮政"),
;
/**
* 状态值
*/
private Integer value;
/**
* 状态名
*/
private String name;
LogisticsEnum(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.mall.order.api.constant;
/**
* 订单 - status
*
* @author Sin
* @time 2019-03-16 14:06
*/
public enum OrderStatusEnum {
WAITING_PAYMENT(1, "等待付款"),
WAIT_SHIPMENT(2, "等待发货"),
ALREADY_SHIPMENT(3, "已发货"),
COMPLETED(4, "已完成"),
CLOSED(5, "已关闭");
/**
* 状态值
*/
private Integer value;
/**
* 状态名
*/
private String name;
OrderStatusEnum(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -1,64 +0,0 @@
package cn.iocoder.mall.order.api.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* 订单创建
*
* @author Sin
* @time 2019-03-16 14:42
*/
@Data
@Accessors(chain = true)
public class OrderCreateDTO implements Serializable {
/**
* 用户id
*/
private Integer userId;
/**
* 用户地址
*/
private Integer userAddressId;
/**
* 优惠劵编号
*/
private Integer couponCardId;
/**
* 备注
*/
private String remark;
/**
* ip信息
*/
private String ip;
///
/// order item
private List<OrderItem> orderItems;
@Data
@Accessors(chain = true)
public static class OrderItem {
/**
* 商品编号
*/
@NotNull
private Integer skuId;
/**
* 数量
*/
@NotNull
@Max(value = 1000)
private Integer quantity;
}
}

View File

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>onemall</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order</artifactId>
<packaging>pom</packaging>
<modules>
<!-- <module>order-biz</module>-->
<!-- <module>order-biz-api</module>-->
<module>order-rest</module>
<module>order-service-api02</module>
<module>order-service-impl</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-dependencies</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -28,7 +28,7 @@
<module>product-service-project</module>
<module>promotion-service-project</module>
<module>search-service-project</module>
<module>order-service-project</module>
<module>trade-service-project</module>
</modules>
<packaging>pom</packaging>

View File

@ -69,7 +69,7 @@
<dependency>
<!-- 订单服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>order-service-api</artifactId>
<artifactId>trade-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>

View File

@ -0,0 +1,21 @@
package cn.iocoder.mall.shopweb.client.trade;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.tradeservice.rpc.order.TradeOrderRpc;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderCreateReqDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
@Service
public class TradeOrderClient {
@DubboReference(version = "${dubbo.consumer.TradeOrderRpc.version}")
private TradeOrderRpc tradeOrderRpc;
public Integer createTradeOrder(TradeOrderCreateReqDTO createReqDTO) {
CommonResult<Integer> createTradeOrderResult = tradeOrderRpc.createTradeOrder(createReqDTO);
createTradeOrderResult.checkError();
return createTradeOrderResult.getData();
}
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.mall.shopweb.client.user;
import cn.iocoder.mall.userservice.rpc.address.UserAddressRpc;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
@Service
public class UserAddressClient {
@DubboReference(version = "${dubbo.consumer.UserAddressRpc.version}")
private UserAddressRpc userAddressRpc;
}

View File

@ -1,11 +0,0 @@
### /order/confirm-create-order-info 基于商品,确认创建订单
GET {{shop-api-base-url}}/order/confirm-create-order-info?skuId=33&quantity=1
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{user-access-token}}
### /order/confirm-create-order-info-from-cart 基于购物车,确认创建订单
GET {{shop-api-base-url}}/order/confirm-create-order-info-from-cart
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{user-access-token}}
###

View File

@ -1,49 +0,0 @@
package cn.iocoder.mall.shopweb.controller.order;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder;
import cn.iocoder.mall.shopweb.controller.order.vo.order.OrderConfirmCreateInfoRespVO;
import cn.iocoder.mall.shopweb.manager.order.OrderManager;
import cn.iocoder.security.annotations.RequiresAuthenticate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static cn.iocoder.common.framework.vo.CommonResult.success;
@Api(tags = "订单 API")
@RestController
@RequestMapping("/order")
@Validated
public class OrderController {
@Autowired
private OrderManager orderManager;
@GetMapping("confirm-create-order-info")
@ApiOperation("基于商品,确认创建订单")
@ApiImplicitParams({
@ApiImplicitParam(name = "skuId", required = true, value = "商品 SKU 编号", example = "1024"),
@ApiImplicitParam(name = "quantity", required = true, value = "购买数量", example = "2"),
@ApiImplicitParam(name = "couponCardId", value = "优惠劵编号", example = "1"),
})
@RequiresAuthenticate
public CommonResult<OrderConfirmCreateInfoRespVO> getOrderConfirmCreateInfo(@RequestParam("skuId") Integer skuId,
@RequestParam("quantity") Integer quantity,
@RequestParam(value = "couponCardId", required = false) Integer couponCardId) {
return success(orderManager.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId));
}
@GetMapping("confirm-create-order-info-from-cart")
@ApiOperation("基于购物车,确认创建订单")
@ApiImplicitParam(name = "couponCardId", value = "优惠劵编号", example = "1")
@RequiresAuthenticate
public CommonResult<OrderConfirmCreateInfoRespVO> getOrderConfirmCreateInfoFromCart(@RequestParam(value = "couponCardId", required = false) Integer couponCardId) {
return success(orderManager.getOrderConfirmCreateInfoFromCart(UserSecurityContextHolder.getUserId(), couponCardId));
}
}

View File

@ -2,7 +2,7 @@ package cn.iocoder.mall.shopweb.controller.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.shopweb.controller.product.vo.category.ProductCategoryRespVO;
import cn.iocoder.mall.shopweb.manager.product.ProductCategoryManager;
import cn.iocoder.mall.shopweb.service.product.ProductCategoryManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

View File

@ -3,7 +3,7 @@ package cn.iocoder.mall.shopweb.controller.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder;
import cn.iocoder.mall.shopweb.controller.product.vo.sku.ProductSkuCalcPriceRespVO;
import cn.iocoder.mall.shopweb.manager.product.ProductSkuManager;
import cn.iocoder.mall.shopweb.service.product.ProductSkuManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

View File

@ -6,7 +6,7 @@ import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuDetailRes
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuPageReqVO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuRespVO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuSearchConditionRespVO;
import cn.iocoder.mall.shopweb.manager.product.ProductSpuManager;
import cn.iocoder.mall.shopweb.service.product.ProductSpuManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

View File

@ -2,7 +2,7 @@ package cn.iocoder.mall.shopweb.controller.promotion;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.shopweb.controller.promotion.vo.brand.BannerRespVO;
import cn.iocoder.mall.shopweb.manager.promotion.BannerManager;
import cn.iocoder.mall.shopweb.service.promotion.BannerManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -5,7 +5,7 @@ import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder;
import cn.iocoder.mall.shopweb.controller.promotion.vo.coupon.card.CouponCardPageReqVO;
import cn.iocoder.mall.shopweb.controller.promotion.vo.coupon.card.CouponCardRespVO;
import cn.iocoder.mall.shopweb.manager.promotion.CouponCardManager;
import cn.iocoder.mall.shopweb.service.promotion.CouponCardManager;
import cn.iocoder.security.annotations.RequiresAuthenticate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;

View File

@ -2,7 +2,7 @@ package cn.iocoder.mall.shopweb.controller.promotion;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.shopweb.controller.promotion.vo.coupon.template.CouponTemplateRespVO;
import cn.iocoder.mall.shopweb.manager.promotion.CouponTemplateManager;
import cn.iocoder.mall.shopweb.service.promotion.CouponTemplateManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

View File

@ -2,7 +2,7 @@ package cn.iocoder.mall.shopweb.controller.promotion;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuRespVO;
import cn.iocoder.mall.shopweb.manager.promotion.ProductRecommendManager;
import cn.iocoder.mall.shopweb.service.promotion.ProductRecommendManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -1,9 +1,9 @@
package cn.iocoder.mall.shopweb.controller.order;
package cn.iocoder.mall.shopweb.controller.trade;
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.CartManager;
import cn.iocoder.mall.shopweb.controller.trade.vo.cart.CartDetailVO;
import cn.iocoder.mall.shopweb.service.trade.CartManager;
import cn.iocoder.security.annotations.RequiresAuthenticate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;

View File

@ -0,0 +1,18 @@
### /trade-order/confirm-create-order-info 基于商品,确认创建订单
GET {{shop-api-base-url}}/trade-order/confirm-create-order-info?skuId=33&quantity=1
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{user-access-token}}
### /trade-order/confirm-create-order-info-from-cart 基于购物车,确认创建订单
GET {{shop-api-base-url}}/trade-order/confirm-create-order-info-from-cart
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{user-access-token}}
### /trade-order/confirm-create-order-info-from-cart 基于商品,创建订单
POST {{shop-api-base-url}}/trade-order/create
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{user-access-token}}
userAddressId=19&remark=我是备注&orderItems[0].skuId=3&orderItems[0].quantity=1
###

View File

@ -0,0 +1,72 @@
package cn.iocoder.mall.shopweb.controller.trade;
import cn.iocoder.common.framework.util.HttpUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder;
import cn.iocoder.mall.shopweb.controller.trade.vo.order.TradeOrderConfirmCreateInfoRespVO;
import cn.iocoder.mall.shopweb.controller.trade.vo.order.TradeOrderCreateFromCartReqVO;
import cn.iocoder.mall.shopweb.controller.trade.vo.order.TradeOrderCreateReqVO;
import cn.iocoder.mall.shopweb.service.trade.TradeOrderService;
import cn.iocoder.security.annotations.RequiresAuthenticate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import static cn.iocoder.common.framework.vo.CommonResult.success;
@Api(tags = "交易订单 API")
@RestController
@RequestMapping("/trade-order")
@Validated
public class TradeOrderController {
@Autowired
private TradeOrderService tradeOrderService;
@GetMapping("confirm-create-order-info")
@ApiOperation("基于商品,确认创建订单")
@ApiImplicitParams({
@ApiImplicitParam(name = "skuId", required = true, value = "商品 SKU 编号", example = "1024"),
@ApiImplicitParam(name = "quantity", required = true, value = "购买数量", example = "2"),
@ApiImplicitParam(name = "couponCardId", value = "优惠劵编号", example = "1"),
})
@RequiresAuthenticate
public CommonResult<TradeOrderConfirmCreateInfoRespVO> getTradeOrderConfirmCreateInfo(
@RequestParam("skuId") Integer skuId,
@RequestParam("quantity") Integer quantity,
@RequestParam(value = "couponCardId", required = false) Integer couponCardId) {
return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId));
}
@GetMapping("confirm-create-order-info-from-cart")
@ApiOperation("基于购物车,确认创建订单")
@ApiImplicitParam(name = "couponCardId", value = "优惠劵编号", example = "1")
@RequiresAuthenticate
public CommonResult<TradeOrderConfirmCreateInfoRespVO> getTradeOrderConfirmCreateInfoFromCart(
@RequestParam(value = "couponCardId", required = false) Integer couponCardId) {
return success(tradeOrderService.getOrderConfirmCreateInfoFromCart(UserSecurityContextHolder.getUserId(), couponCardId));
}
@PostMapping("create")
@ApiOperation("基于商品,创建订单")
@RequiresAuthenticate
public CommonResult<Integer> createTradeOrder(TradeOrderCreateReqVO createReqVO,
HttpServletRequest servletRequest) {
return success(tradeOrderService.createTradeOrder(UserSecurityContextHolder.getUserId(),
HttpUtil.getIp(servletRequest), createReqVO));
}
@GetMapping("create-from-cart")
@ApiOperation("基于购物车,创建订单")
@RequiresAuthenticate
public CommonResult<Integer> createTradeOrder(TradeOrderCreateFromCartReqVO createReqVO) {
return null;
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.shopweb.controller.order.vo.cart;
package cn.iocoder.mall.shopweb.controller.trade.vo.cart;
import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO;
import cn.iocoder.mall.shopweb.controller.product.vo.attr.ProductAttrKeyValueRespVO;

View File

@ -1,8 +1,8 @@
package cn.iocoder.mall.shopweb.controller.order.vo.order;
package cn.iocoder.mall.shopweb.controller.trade.vo.order;
import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.card.CouponCardAvailableRespDTO;
import cn.iocoder.mall.shopweb.controller.order.vo.cart.CartDetailVO;
import cn.iocoder.mall.shopweb.controller.trade.vo.cart.CartDetailVO;
import cn.iocoder.mall.shopweb.controller.product.vo.attr.ProductAttrKeyValueRespVO;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@ -13,7 +13,7 @@ import java.util.List;
@ApiModel(value = "订单确认创建信息 Response VO") // TODO 芋艿swagger 文档完善
@Data
@Accessors(chain = true) // TODO 芋艿 CartDetailVOProductSkuCalcPriceRespVO 有点重复后续要优化下
public class OrderConfirmCreateInfoRespVO {
public class TradeOrderConfirmCreateInfoRespVO {
/**
* 商品分组数组

View File

@ -0,0 +1,23 @@
package cn.iocoder.mall.shopweb.controller.trade.vo.order;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
@ApiModel(value = "创建交易订单 VO基于购物车")
@Data
@Accessors(chain = true)
public class TradeOrderCreateFromCartReqVO {
@ApiModelProperty(name = "收件地址编号", required = true, example = "1")
@NotNull(message = "用户地址不能为空")
private Integer userAddressId;
@ApiModelProperty(name = "优惠劵编号", example = "1024")
private Integer couponCardId;
@ApiModelProperty(name = "备注", example = "1024")
private String remark;
}

View File

@ -0,0 +1,45 @@
package cn.iocoder.mall.shopweb.controller.trade.vo.order;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel(value = "创建交易订单 VO基于商品")
@Data
@Accessors(chain = true)
public class TradeOrderCreateReqVO {
@ApiModelProperty(name = "收件地址编号", required = true, example = "1")
@NotNull(message = "收件地址不能为空")
private Integer userAddressId;
@ApiModelProperty(name = "优惠劵编号", example = "1024")
private Integer couponCardId;
@ApiModelProperty(name = "备注", example = "1024")
private String remark;
/**
* 订单商品项列表
*/
@NotNull(message = "必须选择购买的商品")
private List<OrderItem> orderItems;
@ApiModel(value = "订单商品项")
@Data
@Accessors(chain = true)
public static class OrderItem {
@ApiModelProperty(name = "商品 SKU 编号", required = true, example = "111")
@NotNull(message = "商品 SKU 编号不能为空")
private Integer skuId;
@ApiModelProperty(name = "商品 SKU 购买数量", required = true, example = "1024")
@NotNull(message = "商品 SKU 购买数量不能为空")
@Min(value = 1, message = "商品 SKU 购买数量必须大于 0")
private Integer quantity;
}
}

View File

@ -1,9 +1,9 @@
package cn.iocoder.mall.shopweb.convert.order;
package cn.iocoder.mall.shopweb.convert.trade;
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 cn.iocoder.mall.shopweb.controller.trade.vo.cart.CartDetailVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

View File

@ -1,8 +1,10 @@
package cn.iocoder.mall.shopweb.convert.order;
package cn.iocoder.mall.shopweb.convert.trade;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.card.CouponCardAvailableListReqDTO;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO;
import cn.iocoder.mall.shopweb.controller.order.vo.order.OrderConfirmCreateInfoRespVO;
import cn.iocoder.mall.shopweb.controller.trade.vo.order.TradeOrderConfirmCreateInfoRespVO;
import cn.iocoder.mall.shopweb.controller.trade.vo.order.TradeOrderCreateReqVO;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderCreateReqDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@ -11,11 +13,11 @@ import java.util.List;
import java.util.stream.Collectors;
@Mapper
public interface OrderConvert {
public interface TradeOrderConvert {
OrderConvert INSTANCE = Mappers.getMapper(OrderConvert.class);
TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class);
OrderConfirmCreateInfoRespVO.Fee convert(PriceProductCalcRespDTO.Fee bean);
TradeOrderConfirmCreateInfoRespVO.Fee convert(PriceProductCalcRespDTO.Fee bean);
default List<CouponCardAvailableListReqDTO.Item> convertList(List<PriceProductCalcRespDTO.ItemGroup> itemGroups) {
List<CouponCardAvailableListReqDTO.Item> items = new ArrayList<>();
@ -30,4 +32,6 @@ public interface OrderConvert {
return items;
}
TradeOrderCreateReqDTO convert(TradeOrderCreateReqVO bean);
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.shopweb.manager.product;
package cn.iocoder.mall.shopweb.service.product;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.vo.CommonResult;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.shopweb.manager.product;
package cn.iocoder.mall.shopweb.service.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.promotion.api.rpc.activity.PromotionActivityRpc;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.shopweb.manager.product;
package cn.iocoder.mall.shopweb.service.product;
import cn.iocoder.common.framework.util.CollectionUtils;
import cn.iocoder.common.framework.vo.CommonResult;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.shopweb.manager.promotion;
package cn.iocoder.mall.shopweb.service.promotion;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.vo.CommonResult;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.shopweb.manager.promotion;
package cn.iocoder.mall.shopweb.service.promotion;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.shopweb.manager.promotion;
package cn.iocoder.mall.shopweb.service.promotion;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.promotion.api.rpc.coupon.CouponTemplateRpc;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.shopweb.manager.promotion;
package cn.iocoder.mall.shopweb.service.promotion;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.util.CollectionUtils;

View File

@ -1,9 +1,9 @@
package cn.iocoder.mall.shopweb.manager.order;
package cn.iocoder.mall.shopweb.service.trade;
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.*;
import cn.iocoder.mall.tradeservice.rpc.cart.CartRpc;
import cn.iocoder.mall.tradeservice.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;
@ -14,8 +14,8 @@ import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO;
import cn.iocoder.mall.promotion.api.rpc.price.PriceRpc;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcReqDTO;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO;
import cn.iocoder.mall.shopweb.controller.order.vo.cart.CartDetailVO;
import cn.iocoder.mall.shopweb.convert.order.CartConvert;
import cn.iocoder.mall.shopweb.controller.trade.vo.cart.CartDetailVO;
import cn.iocoder.mall.shopweb.convert.trade.CartConvert;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

View File

@ -1,12 +1,16 @@
package cn.iocoder.mall.shopweb.manager.order;
package cn.iocoder.mall.shopweb.service.trade;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
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.CartItemListReqDTO;
import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemRespDTO;
import cn.iocoder.mall.shopweb.client.trade.TradeOrderClient;
import cn.iocoder.mall.shopweb.controller.trade.vo.order.TradeOrderConfirmCreateInfoRespVO;
import cn.iocoder.mall.shopweb.controller.trade.vo.order.TradeOrderCreateReqVO;
import cn.iocoder.mall.shopweb.convert.trade.TradeOrderConvert;
import cn.iocoder.mall.tradeservice.rpc.cart.CartRpc;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.CartItemListReqDTO;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.CartItemRespDTO;
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;
@ -20,10 +24,9 @@ import cn.iocoder.mall.promotion.api.rpc.coupon.dto.card.CouponCardAvailableResp
import cn.iocoder.mall.promotion.api.rpc.price.PriceRpc;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcReqDTO;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO;
import cn.iocoder.mall.shopweb.controller.order.vo.order.OrderConfirmCreateInfoRespVO;
import cn.iocoder.mall.shopweb.convert.order.CartConvert;
import cn.iocoder.mall.shopweb.convert.order.OrderConvert;
import cn.iocoder.mall.shopweb.convert.trade.CartConvert;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -34,11 +37,11 @@ import static cn.iocoder.mall.shopweb.enums.ShopWebErrorCodeConstants.ORDER_PROD
import static cn.iocoder.mall.shopweb.enums.ShopWebErrorCodeConstants.ORDER_PRODUCT_SKU_QUANTITY_NOT_ENOUGH;
/**
* Order Manager
* 交易订单 Service
*/
@Service
@Validated
public class OrderManager {
public class TradeOrderService {
@DubboReference(version = "${dubbo.consumer.PriceRpc.version}")
private PriceRpc priceRpc;
@ -51,22 +54,25 @@ public class OrderManager {
@DubboReference(version = "${dubbo.consumer.CouponCardRpc.version}")
private CouponCardRpc couponCardRpc;
public OrderConfirmCreateInfoRespVO getOrderConfirmCreateInfo(Integer userId, Integer skuId, Integer quantity, Integer couponCardId) {
@Autowired
private TradeOrderClient tradeOrderClient;
public TradeOrderConfirmCreateInfoRespVO getOrderConfirmCreateInfo(Integer userId, Integer skuId, Integer quantity, Integer couponCardId) {
Map<Integer, Integer> skuMap = new HashMap<>();
skuMap.put(skuId, quantity);
return this.getOrderConfirmCreateInfo0(userId, skuMap, couponCardId);
}
public OrderConfirmCreateInfoRespVO getOrderConfirmCreateInfoFromCart(Integer userId, Integer couponCardId) {
public TradeOrderConfirmCreateInfoRespVO getOrderConfirmCreateInfoFromCart(Integer userId, Integer couponCardId) {
// 获得购物车的商品
CommonResult<List<CartItemRespDTO>> listCartItemsResult = cartRpc.listCartItems(
new CartItemListReqDTO().setUserId(userId).setSelected(true));
listCartItemsResult.checkError();
// 购物车为空时构造空的 OrderConfirmCreateInfoRespVO 返回
if (CollectionUtils.isEmpty(listCartItemsResult.getData())) {
OrderConfirmCreateInfoRespVO result = new OrderConfirmCreateInfoRespVO();
TradeOrderConfirmCreateInfoRespVO result = new TradeOrderConfirmCreateInfoRespVO();
result.setItemGroups(Collections.emptyList());
result.setFee(new OrderConfirmCreateInfoRespVO.Fee(0, 0, 0, 0));
result.setFee(new TradeOrderConfirmCreateInfoRespVO.Fee(0, 0, 0, 0));
return result;
}
// 计算商品价格
@ -75,7 +81,7 @@ public class OrderManager {
return this.getOrderConfirmCreateInfo0(userId, skuMap, couponCardId);
}
private OrderConfirmCreateInfoRespVO getOrderConfirmCreateInfo0(Integer userId, Map<Integer, Integer> skuMap, Integer couponCardId) {
private TradeOrderConfirmCreateInfoRespVO getOrderConfirmCreateInfo0(Integer userId, Map<Integer, Integer> skuMap, Integer couponCardId) {
// 校验商品都存在并且库存足够
this.checkProductSkus(skuMap);
// 获得商品 SKU 信息
@ -89,11 +95,11 @@ public class OrderManager {
// 获得促销活动信息
Map<Integer, PromotionActivityRespDTO> promotionActivityMap = this.getPromotionActivityMap(calcProductPriceResult.getData());
// 拼接结果
OrderConfirmCreateInfoRespVO createInfoRespVO = new OrderConfirmCreateInfoRespVO();
createInfoRespVO.setFee(OrderConvert.INSTANCE.convert(calcProductPriceResult.getData().getFee()));
TradeOrderConfirmCreateInfoRespVO createInfoRespVO = new TradeOrderConfirmCreateInfoRespVO();
createInfoRespVO.setFee(TradeOrderConvert.INSTANCE.convert(calcProductPriceResult.getData().getFee()));
createInfoRespVO.setItemGroups(new ArrayList<>(calcProductPriceResult.getData().getItemGroups().size()));
for (PriceProductCalcRespDTO.ItemGroup itemGroupDTO : calcProductPriceResult.getData().getItemGroups()) {
OrderConfirmCreateInfoRespVO.ItemGroup itemGroupVO = new OrderConfirmCreateInfoRespVO.ItemGroup();
TradeOrderConfirmCreateInfoRespVO.ItemGroup itemGroupVO = new TradeOrderConfirmCreateInfoRespVO.ItemGroup();
createInfoRespVO.getItemGroups().add(itemGroupVO);
// 活动信息
if (itemGroupDTO.getActivityId() != null) {
@ -108,7 +114,7 @@ public class OrderManager {
// 查询可用优惠劵信息
CommonResult<List<CouponCardAvailableRespDTO>> listAvailableCouponCardsResult = couponCardRpc.listAvailableCouponCards(
new CouponCardAvailableListReqDTO().setUserId(userId)
.setItems(OrderConvert.INSTANCE.convertList(calcProductPriceResult.getData().getItemGroups())));
.setItems(TradeOrderConvert.INSTANCE.convertList(calcProductPriceResult.getData().getItemGroups())));
listAvailableCouponCardsResult.checkError();
createInfoRespVO.setCouponCards(listAvailableCouponCardsResult.getData());
return createInfoRespVO;
@ -157,4 +163,9 @@ public class OrderManager {
return CollectionUtils.convertMap(listPromotionActivitiesResult.getData(), PromotionActivityRespDTO::getId);
}
public Integer createTradeOrder(Integer userId, String ip, TradeOrderCreateReqVO createReqVO) {
return tradeOrderClient.createTradeOrder(TradeOrderConvert.INSTANCE.convert(createReqVO)
.setUserId(userId).setIp(ip));
}
}

View File

@ -6,6 +6,9 @@ spring:
discovery:
server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址
namespace: dev # Nacos 命名空间
# Spring 主应用配置
main:
lazy-initialization: true # 开启延迟加载,保证本地开发的性能
# Dubbo 配置项
dubbo:

View File

@ -53,6 +53,8 @@ dubbo:
version: 1.0.0
ProductRecommendRpc:
version: 1.0.0
TradeOrderRpc:
version: 1.0.0
# Swagger 配置项
swagger:

View File

@ -9,11 +9,12 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-service-project</artifactId>
<artifactId>trade-service-project</artifactId>
<packaging>pom</packaging>
<modules>
<module>order-service-api</module>
<module>order-service-app</module>
<module>trade-service-api</module>
<module>trade-service-app</module>
<module>trade-service-integration-test</module>
</modules>
<dependencyManagement>
@ -30,7 +31,7 @@
<!-- 自身项目 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>order-service-api</artifactId>
<artifactId>trade-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@ -3,13 +3,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>order-service-project</artifactId>
<artifactId>trade-service-project</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-service-api</artifactId>
<artifactId>trade-service-api</artifactId>
<dependencies>
<dependency>

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.enums;
package cn.iocoder.mall.tradeservice.enums;
import cn.iocoder.common.framework.exception.ErrorCode;

View File

@ -0,0 +1,41 @@
package cn.iocoder.mall.tradeservice.enums.aftersale;
import lombok.Getter;
/**
* 售后订单的状态枚举
*
* 整体流程 https://www.processon.com/view/link/5fbdf47f07912946156305d7
*
* 1. 在退款的情况下需要 1 个来回
* 2. 在退货退款的情况下需要 2 个来回额外增加一个买家退货的过程
* 3. 在换货的情况下需要 3 个来回额外增加一个买家退货 + 卖家发货的过程
*/
@Getter
public enum AfterSaleOrderStatusEnum {
WAIT_SELLER_AGREE(10, "售后申请待商家处理"),
WAIT_BUYER_RETURN_GOODS(20, "商家同意售后申请,待买家处理"),
SELLER_REFUSE_BUYER(30, "商家不同意售后申请,待买家处理"),
WAIT_SELLER_CONFIRM_GOODS(40, "买家已退货,待商家确认收货"),
WAIT_BUYER_CONFIRM_GOODS(50, "商家已发货,待买家确认收货"),
SELLER_REFUSE_RETURN_GOODS(60, "商家拒绝收货,待买家处理"),
SUCCESS(70, "售后成功"),
CLOSED(80, "售后失败"),
;
/**
* 类型
*/
private final Integer status;
/**
* 描述
*/
private final String desc;
AfterSaleOrderStatusEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.mall.tradeservice.enums.aftersale;
import lombok.Getter;
/**
* 售后单的类型枚举
*/
@Getter
public enum AfterSaleTypeEnum {
IN_SALE(10, "售中退款"),
AFTER_SALE(20, "售后退款");
/**
* 类型
*/
private final Integer type;
/**
* 描述
*/
private final String desc;
AfterSaleTypeEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.mall.tradeservice.enums.aftersale;
import lombok.Getter;
/**
* 售后单的方式枚举
*/
@Getter
public enum AfterSaleWayEnum {
REFUND(10, "退款"),
RETURN_AND_REFUND(20, "退货退款"),
EXCHANGE(30, "换货");
/**
* 方式
*/
private final Integer way;
/**
* 描述
*/
private final String desc;
AfterSaleWayEnum(Integer way, String desc) {
this.way = way;
this.desc = desc;
}
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.mall.tradeservice.enums.logistics;
import lombok.Getter;
/**
* 物流的配送类型
*/
@Getter
public enum LogisticsDeliveryTypeEnum {
/**
* 无需快递
*/
NULL(0),
/**
* 传统快递
*/
EXPRESS(1);
private final Integer deliveryType;
LogisticsDeliveryTypeEnum(Integer deliveryType) {
this.deliveryType = deliveryType;
}
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.mall.tradeservice.enums.order;
import lombok.Getter;
/**
* 交易订单的售后状态的枚举
*/
@Getter
public enum TradeOrderAfterSaleStatusEnum {
NULL(0, ""),
IN_PROCESS(10, "售后中"),
END(10, "售后结束");
/**
* 状态
*/
private final Integer status;
/**
* 描述
*/
private final String desc;
TradeOrderAfterSaleStatusEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
}

View File

@ -0,0 +1,35 @@
package cn.iocoder.mall.tradeservice.enums.order;
import lombok.Getter;
/**
* 交易订单 - 状态蜜桔
*
* @author Sin
* @time 2019-03-16 14:06
*/
@Getter
public enum TradeOrderStatusEnum {
WAITING_PAYMENT(10, "等待付款"),
WAIT_SHIPMENT(20, "等待发货"),
ALREADY_SHIPMENT(30, "已发货"),
COMPLETED(40, "已完成"),
CLOSED(50, "已关闭");
/**
* 状态值
*/
private final Integer value;
/**
* 状态名
*/
private final String name;
TradeOrderStatusEnum(int value, String name) {
this.value = value;
this.name = name;
}
}

View File

@ -1,7 +1,7 @@
package cn.iocoder.mall.orderservice.rpc.cart;
package cn.iocoder.mall.tradeservice.rpc.cart;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.orderservice.rpc.cart.dto.*;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.*;
import java.util.List;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.rpc.cart.dto;
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.rpc.cart.dto;
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.rpc.cart.dto;
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.rpc.cart.dto;
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.rpc.cart.dto;
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.rpc.cart.dto;
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -0,0 +1,19 @@
package cn.iocoder.mall.tradeservice.rpc.order;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderCreateReqDTO;
/**
* 交易订单 Rpc 接口
*/
public interface TradeOrderRpc {
/**
* 创建交易订单
*
* @param createReqDTO 订单信息
* @return 订单编号
*/
CommonResult<Integer> createTradeOrder(TradeOrderCreateReqDTO createReqDTO);
}

View File

@ -0,0 +1,69 @@
package cn.iocoder.mall.tradeservice.rpc.order.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* 交易订单创建 Request DTO
*
* @author Sin
* @time 2019-03-16 14:42
*/
@Data
@Accessors(chain = true)
public class TradeOrderCreateReqDTO implements Serializable {
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Integer userId;
/**
* 用户 IP
*/
@NotNull(message = "用户 IP 不能为空")
private String ip;
/**
* 收件地址编号
*/
@NotNull(message = "用户地址不能为空")
private Integer userAddressId;
/**
* 优惠劵编号
*/
private Integer couponCardId;
/**
* 备注
*/
private String remark;
/**
* 订单商品项列表
*/
@NotNull(message = "必须选择购买的商品")
private List<OrderItem> orderItems;
@Data
@Accessors(chain = true)
public static class OrderItem implements Serializable {
/**
* 商品编号
*/
@NotNull(message = "商品 SKU 编号不能为空")
private Integer skuId;
/**
* 数量
*/
@NotNull(message = "商品 SKU 购买数量不能为空")
@Min(value = 1, message = "商品 SKU 购买数量必须大于 0")
private Integer quantity;
}
}

View File

@ -3,13 +3,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>order-service-project</artifactId>
<artifactId>trade-service-project</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-service-app</artifactId>
<artifactId>trade-service-app</artifactId>
<dependencies>
<!-- RPC 相关 -->
<dependency>
@ -24,6 +24,13 @@
<version>${project.version}</version>
</dependency>
<dependency>
<!-- 用户服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- 商品服务 -->
<groupId>cn.iocoder.mall</groupId>
@ -34,7 +41,14 @@
<dependency>
<!-- 订单服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>order-service-api</artifactId>
<artifactId>trade-service-api</artifactId>
</dependency>
<dependency>
<!-- 营销服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>promotion-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Web 相关 -->
@ -102,6 +116,13 @@
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<!-- Test 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -1,13 +1,13 @@
package cn.iocoder.mall.orderservice;
package cn.iocoder.mall.tradeservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrderServiceApplication {
public class TradeServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
SpringApplication.run(TradeServiceApplication.class, args);
}
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.mall.tradeservice.client.product;
import cn.iocoder.common.framework.util.CollectionUtils;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.productservice.rpc.sku.ProductSkuRpc;
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO;
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@Service
public class ProductSkuClient {
@DubboReference(version = "${dubbo.consumer.ProductSkuRpc.version}")
private ProductSkuRpc productSkuRpc;
public List<ProductSkuRespDTO> listProductSkus(Collection<Integer> productSkuIds, String... fields) {
if (CollectionUtils.isEmpty(productSkuIds)) {
return Collections.emptyList();
}
CommonResult<List<ProductSkuRespDTO>> listProductSkusResult = productSkuRpc.listProductSkus(
new ProductSkuListQueryReqDTO().setProductSkuIds(productSkuIds).setFields(Arrays.asList(fields)));
listProductSkusResult.checkError();
return listProductSkusResult.getData();
}
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.mall.tradeservice.client.promotion;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.promotion.api.rpc.coupon.CouponCardRpc;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.card.CouponCardUseReqDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
@Service
public class CouponCardClient {
@DubboReference(version = "${dubbo.consumer.CouponCardRpc.version}")
private CouponCardRpc couponCardRpc;
public void useCouponCard(Integer userId, Integer couponCardId) {
CommonResult<Boolean> useCouponCardResult = couponCardRpc.useCouponCard(new CouponCardUseReqDTO()
.setUserId(userId).setCouponCardId(couponCardId));
useCouponCardResult.checkError();
}
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.mall.tradeservice.client.promotion;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.promotion.api.rpc.price.PriceRpc;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcReqDTO;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class PriceClient {
@DubboReference(version = "${dubbo.consumer.PriceRpc.version}")
private PriceRpc priceRpc;
/**
* 计算商品们的价格
*
* @param userId 用户编号
* @param items 商品 SKU 集合
* @param couponCardId 优惠劵编号允许为空
* @return 价格
*/
public PriceProductCalcRespDTO calcProductPrice(Integer userId, List<PriceProductCalcReqDTO.Item> items,
Integer couponCardId) {
CommonResult<PriceProductCalcRespDTO> calcProductPriceResult = priceRpc.calcProductPrice(
new PriceProductCalcReqDTO().setUserId(userId).setItems(items).setCouponCardId(couponCardId));
calcProductPriceResult.checkError();
return calcProductPriceResult.getData();
}
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.mall.tradeservice.client.user;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.userservice.rpc.address.UserAddressRpc;
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressRespDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import java.util.Objects;
@Service
public class UserAddressClient {
@DubboReference(version = "${dubbo.consumer.UserAddressRpc.version}")
private UserAddressRpc userAddressRpc;
public UserAddressRespDTO getUserAddress(Integer userAddressId, Integer userId) {
CommonResult<UserAddressRespDTO> getUserAddressResult = userAddressRpc.getUserAddress(userAddressId);
getUserAddressResult.checkError();
if (getUserAddressResult.getData() == null) {
return null;
}
// 如果用户编号不匹配则返回 null
return Objects.equals(getUserAddressResult.getData().getUserId(), userId) ?
getUserAddressResult.getData() : null;
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.config;
package cn.iocoder.mall.tradeservice.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.config;
package cn.iocoder.mall.tradeservice.config;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
@ -9,7 +9,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@MapperScan("cn.iocoder.mall.orderservice.dal.mysql.mapper") // 扫描对应的 Mapper 接口
@MapperScan("cn.iocoder.mall.tradeservice.dal.mysql.mapper") // 扫描对应的 Mapper 接口
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理
public class DatabaseConfiguration {

View File

@ -1,12 +1,12 @@
package cn.iocoder.mall.orderservice.convert.cart;
package cn.iocoder.mall.tradeservice.convert.cart;
import cn.iocoder.mall.orderservice.dal.mysql.dataobject.cart.CartItemDO;
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.service.cart.bo.CartItemAddBO;
import cn.iocoder.mall.orderservice.service.cart.bo.CartItemBO;
import cn.iocoder.mall.orderservice.service.cart.bo.CartItemListQueryBO;
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart.CartItemDO;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.CartItemAddReqDTO;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.CartItemListReqDTO;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.CartItemRespDTO;
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemAddBO;
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemBO;
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemListQueryBO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

View File

@ -0,0 +1,160 @@
package cn.iocoder.mall.tradeservice.dal.mysql.dataobject.aftersale;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.order.TradeOrderDO;
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.order.TradeOrderItemDO;
import cn.iocoder.mall.tradeservice.enums.aftersale.AfterSaleTypeEnum;
import cn.iocoder.mall.tradeservice.enums.aftersale.AfterSaleWayEnum;
import cn.iocoder.mall.tradeservice.enums.logistics.LogisticsDeliveryTypeEnum;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 售后订单用于处理 {@link TradeOrderDO} 交易订单的退货换流程
*
* TODO 超时机制
* TODO 用户买家和商家每一个步骤都需要记录协商记录多设计一个表
*/
@TableName(value = "after_sale_order")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class AfterSaleOrderDO extends DeletableDO {
/**
* 售后订单编号
*/
private Integer id;
/**
* 售后状态
*/
private Integer status;
/**
* 用户编号
*/
private Integer userId;
/**
* 用户手机
*/
private String userMobile;
/**
* 售后类型
*
* 枚举 {@link AfterSaleTypeEnum}
*/
private Integer type;
/**
* 售后方式
*
* 枚举 {@link AfterSaleWayEnum}
*/
private Integer way;
/**
* 货物状态是否收到货
*/
private Boolean logisticsReceived;
/**
* 用户售后原因
*
* TODO 不同情况下的退款原因不同
*/
private Integer reasonType;
/**
* 用户售后说明
*/
private String reasonMemo;
/**
* 用户售后凭证图片的地址数组
*
* 数组以逗号分隔
*/
private String reasonPicUrls;
/**
* 商家拒绝理由
*/
private String rejectReasonMemo;
// ========== 交易订单相关 ==========
/**
* 交易订单编号
*
* 外键 {@link TradeOrderDO#getId()}
*/
private Integer tradeOrderId;
/**
* 交易订单项编号
*
* 外键 {@link TradeOrderItemDO#getId()}
*/
private Integer tradeOrderItemId;
/**
* 商品 SKU 编号
*/
private Integer skuId;
/**
* 商品数量
*/
private Integer quantity;
// ========== 退款相关 ==========
/**
* 退款金额单位
*/
private Integer refundPrice;
// ========== 退货相关 ==========
/**
* 退货地址即商家的收件地址
*/
private String returnDetailAddress;
/**
* 退货物流公司编号
*
* 使用 DataDict 数据字典 EXPRESS
*/
private String returnLogisticsExpressId;
/**
* 退货物流单号
*/
private String returnLogisticsExpressNo;
/**
* 退货物流说明
*/
private String returnLogisticsReasonMemo;
/**
* 退货物流凭证图片的地址数组
*
* 数组以逗号分隔
*/
private String returnLogisticsPicUrls;
/**
* 退货物流的填写时间
*/
private Date returnLogisticsDate;
// ========== 换货相关 ==========
/**
* 换货物流的配送方式
* 这里指的是商家重新给用户买家发货
*
* 枚举 {@link LogisticsDeliveryTypeEnum}
*/
private Integer exchangeLogisticsDeliveryType;
/**
* 换货物流公司编号
*/
private Integer exchangeLogisticsExpressId;
/**
* 换货物流公司单号
*/
private String exchangeLogisticsExpressNo;
/**
* 换货物流的填写时间
*/
private Date exchangeLogisticsDate;
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.orderservice.dal.mysql.dataobject.cart;
package cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;

Some files were not shown because too many files have changed in this diff Show More