迁移购物车模块
parent
d06e51ba21
commit
3914b32637
|
@ -64,6 +64,7 @@ public class ErrorCodeAutoGenerator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
// TODO 芋艿:校验是否重复了;
|
||||||
ErrorCode errorCode = (ErrorCode) field.get(errorCodeConstantsClazz);
|
ErrorCode errorCode = (ErrorCode) field.get(errorCodeConstantsClazz);
|
||||||
autoGenerateDTOs.add(new ErrorCodeAutoGenerateDTO().setGroup(group)
|
autoGenerateDTOs.add(new ErrorCodeAutoGenerateDTO().setGroup(group)
|
||||||
.setCode(errorCode.getCode()).setMessage(errorCode.getMessage()));
|
.setCode(errorCode.getCode()).setMessage(errorCode.getMessage()));
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?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-service-project</artifactId>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>order-service-api</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>common-framework</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 工具类相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,51 @@
|
||||||
|
package cn.iocoder.mall.orderservice.enums;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.exception.ErrorCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单错误码
|
||||||
|
* <p>
|
||||||
|
* 错误码区间 [1-008-000-000 ~ 1-008-000-000]
|
||||||
|
*
|
||||||
|
* @author Sin
|
||||||
|
* @time 2019-03-23 11:23
|
||||||
|
*/
|
||||||
|
public interface OrderErrorCodeConstants {
|
||||||
|
|
||||||
|
// order
|
||||||
|
ErrorCode ORDER_NOT_EXISTENT = new ErrorCode(1008000000, "获取订单不存在!");
|
||||||
|
ErrorCode ORDER_GET_SKU_FAIL = new ErrorCode(1008000001, "获取商品失败!)");
|
||||||
|
ErrorCode ORDER_GET_SKU_NOT_EXISTENT = new ErrorCode(1008000002, "获取的商品不存在!");
|
||||||
|
ErrorCode ORDER_PAY_AMOUNT_NOT_NEGATIVE = new ErrorCode(1008000003, "支付金额不能为负数!");
|
||||||
|
ErrorCode ORDER_STATUS_NOT_CANCEL = new ErrorCode(1008000004, "订单状态不能取消!)");
|
||||||
|
ErrorCode ORDER_DELIVERY_INCORRECT_DATA = new ErrorCode(1008000005, "订单发货数据不正确!");
|
||||||
|
ErrorCode ORDER_INSUFFICIENT_INVENTORY = new ErrorCode(1008000006, "库存不足!");
|
||||||
|
ErrorCode ORDER_GOODS_AMOUNT_INCORRECT = new ErrorCode(1008000007, "商品金额非法!");
|
||||||
|
ErrorCode ORDER_GET_GOODS_INFO_INCORRECT = new ErrorCode(1008000008, "获取额商品信息不正确!");
|
||||||
|
ErrorCode ORDER_GET_USER_ADDRESS_FAIL = new ErrorCode(1008000009, "获取用户地址失败!");
|
||||||
|
ErrorCode ORDER_GET_PAY_FAIL = new ErrorCode(1008000010, "调用pay失败!");
|
||||||
|
ErrorCode ORDER_NOT_USER_ORDER = new ErrorCode(1008000011, "不是该用户的订单!");
|
||||||
|
ErrorCode ORDER_UNABLE_CONFIRM_ORDER = new ErrorCode(1008000012, "状态不对不能确认订单!");
|
||||||
|
ErrorCode ORDER_CREATE_CART_IS_EMPTY = new ErrorCode(1008000013, "购物车无选中的商品,无法创建订单");
|
||||||
|
ErrorCode ORDER_STATUS_NOT_WAITING_PAYMENT = new ErrorCode(1008000014, "订单不处于等待支付状态");
|
||||||
|
ErrorCode ORDER_PAY_AMOUNT_ERROR = new ErrorCode(1008000015, "订单金额不正确");
|
||||||
|
|
||||||
|
// order item
|
||||||
|
ErrorCode ORDER_ITEM_ONLY_ONE = new ErrorCode(1008000200, "订单Item只有一个!");
|
||||||
|
ErrorCode ORDER_ITEM_SOME_NOT_EXISTS = new ErrorCode(1008000201, "有不存在的商品!");
|
||||||
|
|
||||||
|
// 订单退货
|
||||||
|
ErrorCode ORDER_RETURN_NO_RETURN_APPLY = new ErrorCode(1008000400, "未退货申请");
|
||||||
|
ErrorCode ORDER_RETURN_NOT_EXISTENT = new ErrorCode(1008000401, "退货订单不存在");
|
||||||
|
ErrorCode ORDER_RETURN_REFUND_FAILED = new ErrorCode(1008000402, "退款失败");
|
||||||
|
|
||||||
|
// ========== 购物车 ==========
|
||||||
|
ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1008003000, "购物车项不存在");
|
||||||
|
ErrorCode CARD_ITEM_SKU_NOT_FOUND = new ErrorCode(1008003001, "商品不存在");
|
||||||
|
ErrorCode CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH = new ErrorCode(1008003002, "商品库存不足");
|
||||||
|
|
||||||
|
// 工具类服务 1008004000
|
||||||
|
ErrorCode DICT_SERVER_INVOKING_FAIL = new ErrorCode(1008004000, "字典服务调用失败!");
|
||||||
|
ErrorCode ORDER_LOGISTICS_INVOKING_FAIL = new ErrorCode(1008004001, "订单物流调用失败!");
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package cn.iocoder.mall.orderservice.rpc.cart;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
|
import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemAddReqDTO;
|
||||||
|
import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemUpdateQuantityReqDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车 Rpc 接口
|
||||||
|
*/
|
||||||
|
public interface CartRpc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加商品到购物车
|
||||||
|
*
|
||||||
|
* @param addReqDTO 添加商品信息
|
||||||
|
* @return 成功
|
||||||
|
*/
|
||||||
|
CommonResult<Boolean> addCartItem(CartItemAddReqDTO addReqDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新购物车商品数量
|
||||||
|
*
|
||||||
|
* @param updateQuantityReqDTO 更新商品数量
|
||||||
|
* @return 成功
|
||||||
|
*/
|
||||||
|
CommonResult<Boolean> updateCartItemSelected(CartItemUpdateQuantityReqDTO updateQuantityReqDTO);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cn.iocoder.mall.orderservice.rpc.cart.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车添加购物项 Request DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class CartItemAddReqDTO implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Integer userId;
|
||||||
|
/**
|
||||||
|
* 商品 SKU 编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "商品 SKU 编号不能为空")
|
||||||
|
private Integer skuId;
|
||||||
|
/**
|
||||||
|
* 数量
|
||||||
|
*/
|
||||||
|
@NotNull(message = "数量不能为空")
|
||||||
|
@Min(message = "数量必须大于 0", value = 1L)
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cn.iocoder.mall.orderservice.rpc.cart.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车更新数量 Request DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class CartItemUpdateQuantityReqDTO implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Integer userId;
|
||||||
|
/**
|
||||||
|
* 商品 SKU 编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "商品 SKU 编号不能为空")
|
||||||
|
private Integer skuId;
|
||||||
|
/**
|
||||||
|
* 数量
|
||||||
|
*/
|
||||||
|
@NotNull(message = "数量不能为空")
|
||||||
|
@Min(message = "数量必须大于 0", value = 1L)
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
<?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-service-project</artifactId>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>order-service-app</artifactId>
|
||||||
|
<dependencies>
|
||||||
|
<!-- RPC 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<!-- 系统服务 -->
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>system-service-api</artifactId>
|
||||||
|
<version>${project.version}</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>order-service-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Web 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId> <!-- 需要开启 Web 容器,因为 Actuator 需要使用到 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- MQ 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>mall-spring-boot-starter-rocketmq</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Registry 和 Config 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- DB 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</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>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 监控相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 工具类相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</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.aspectj</groupId>
|
||||||
|
<artifactId>aspectjweaver</artifactId>
|
||||||
|
<version>1.9.6</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<!-- 设置构建的 jar 包名 -->
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<!-- 使用 spring-boot-maven-plugin 插件打包 -->
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,13 @@
|
||||||
|
package cn.iocoder.mall.orderservice;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class OrderServiceApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(OrderServiceApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package cn.iocoder.mall.orderservice.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Aop 配置类
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
|
||||||
|
public class AopConfiguration {
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package cn.iocoder.mall.orderservice.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.orderservice.dal.mysql.mapper") // 扫描对应的 Mapper 接口
|
||||||
|
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理。
|
||||||
|
public class DatabaseConfiguration {
|
||||||
|
|
||||||
|
// 数据库连接池 Druid
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ISqlInjector sqlInjector() {
|
||||||
|
return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PaginationInterceptor paginationInterceptor() {
|
||||||
|
return new PaginationInterceptor(); // MyBatis Plus 分页插件
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package cn.iocoder.mall.orderservice.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.service.cart.bo.CartItemAddBO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface CartConvert {
|
||||||
|
|
||||||
|
CartConvert INSTANCE = Mappers.getMapper(CartConvert.class);
|
||||||
|
|
||||||
|
CartItemDO convert(CartItemAddBO bean);
|
||||||
|
|
||||||
|
CartItemAddBO convert(CartItemAddReqDTO bean);
|
||||||
|
|
||||||
|
}
|
|
@ -1,16 +1,19 @@
|
||||||
package cn.iocoder.mall.order.biz.dataobject;
|
package cn.iocoder.mall.orderservice.dal.mysql.dataobject.cart;
|
||||||
|
|
||||||
import cn.iocoder.mall.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
|
||||||
import java.util.Date;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 购物车的商品信息
|
* 购物车的商品信息 DO
|
||||||
*/
|
*/
|
||||||
|
@TableName("cart_item")
|
||||||
@Data
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class CartItemDO extends BaseDO {
|
public class CartItemDO extends DeletableDO {
|
||||||
|
|
||||||
// ========= 基础字段 BEGIN =========
|
// ========= 基础字段 BEGIN =========
|
||||||
|
|
||||||
|
@ -18,18 +21,6 @@ public class CartItemDO extends BaseDO {
|
||||||
* 编号,唯一自增。
|
* 编号,唯一自增。
|
||||||
*/
|
*/
|
||||||
private Integer id;
|
private Integer id;
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*
|
|
||||||
* 1-正常
|
|
||||||
* 2-主动删除
|
|
||||||
* 3-下单删除
|
|
||||||
*/
|
|
||||||
private Integer status;
|
|
||||||
/**
|
|
||||||
* 商品在购物车中的删除时间
|
|
||||||
*/
|
|
||||||
private Date deleteTime;
|
|
||||||
/**
|
/**
|
||||||
* 是否选中
|
* 是否选中
|
||||||
*/
|
*/
|
||||||
|
@ -66,19 +57,6 @@ public class CartItemDO extends BaseDO {
|
||||||
|
|
||||||
// ========= 商品信息 END =========
|
// ========= 商品信息 END =========
|
||||||
|
|
||||||
// ========= 交易信息 BEGIN =========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单编号
|
|
||||||
*/
|
|
||||||
private Integer orderId;
|
|
||||||
/**
|
|
||||||
* 订单创建时间
|
|
||||||
*/
|
|
||||||
private Date orderCreateTime;
|
|
||||||
|
|
||||||
// ========= 交易信息 BEGIN =========
|
|
||||||
|
|
||||||
// ========= 优惠信息 BEGIN =========
|
// ========= 优惠信息 BEGIN =========
|
||||||
|
|
||||||
// /**
|
// /**
|
|
@ -0,0 +1,32 @@
|
||||||
|
package cn.iocoder.mall.orderservice.dal.mysql.mapper.cart;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||||
|
import cn.iocoder.mall.orderservice.dal.mysql.dataobject.cart.CartItemDO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface CartItemMapper extends BaseMapper<CartItemDO> {
|
||||||
|
|
||||||
|
default CartItemDO selectByUserIdAndSkuId(Integer userId, Integer skuId) {
|
||||||
|
return selectOne(new QueryWrapper<CartItemDO>().eq("user_id", userId)
|
||||||
|
.eq("sku_id", skuId));
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<CartItemDO> selectListByUserIdAndSkuIds(Integer userId, Collection<Integer> skuIds) {
|
||||||
|
return selectList(new QueryWrapperX<CartItemDO>().eq("user_id", userId)
|
||||||
|
.inIfPresent("sku_id", skuIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void updateByIds(@Param("ids") Set<Integer> ids, @Param("updateObject") CartItemDO updateObject) {
|
||||||
|
// TODO 芋艿:batch update ,在 mybatis plus 做拓展,这里先临时处理
|
||||||
|
ids.forEach(id -> updateById(updateObject.setId(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package cn.iocoder.mall.orderservice.manager.cart;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||||
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
|
import cn.iocoder.mall.orderservice.convert.cart.CartConvert;
|
||||||
|
import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemAddReqDTO;
|
||||||
|
import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemUpdateQuantityReqDTO;
|
||||||
|
import cn.iocoder.mall.orderservice.service.cart.CartService;
|
||||||
|
import cn.iocoder.mall.productservice.rpc.sku.ProductSkuRpc;
|
||||||
|
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
|
||||||
|
import org.apache.dubbo.config.annotation.DubboReference;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import static cn.iocoder.mall.orderservice.enums.OrderErrorCodeConstants.CARD_ITEM_SKU_NOT_FOUND;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车 Manager
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CartManager {
|
||||||
|
|
||||||
|
@DubboReference(version = "${dubbo.consumer.ProductSkuRpc.version}")
|
||||||
|
private ProductSkuRpc productSkuRpc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CartService cartService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加商品到购物车
|
||||||
|
*
|
||||||
|
* @param addReqDTO 添加商品信息
|
||||||
|
*/
|
||||||
|
public void addCartItem(CartItemAddReqDTO addReqDTO) {
|
||||||
|
// 校验商品 SKU 是否合法
|
||||||
|
ProductSkuRespDTO skuDTO = this.checkProductSku(addReqDTO.getSkuId());
|
||||||
|
// 添加购物车项
|
||||||
|
cartService.addCartItem(CartConvert.INSTANCE.convert(addReqDTO), skuDTO.getQuantity());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新购物车商品数量
|
||||||
|
*
|
||||||
|
* @param updateQuantityReqDTO 更新商品数量
|
||||||
|
*/
|
||||||
|
public void updateCartItemSelected(CartItemUpdateQuantityReqDTO updateQuantityReqDTO) {
|
||||||
|
// 校验商品 SKU 是否合法
|
||||||
|
ProductSkuRespDTO skuDTO = this.checkProductSku(updateQuantityReqDTO.getSkuId());
|
||||||
|
// 更新购物车商品数量
|
||||||
|
cartService.updateCartItemQuantity(updateQuantityReqDTO.getUserId(), updateQuantityReqDTO.getSkuId(),
|
||||||
|
updateQuantityReqDTO.getQuantity(), skuDTO.getQuantity());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProductSkuRespDTO checkProductSku(Integer skuId) {
|
||||||
|
CommonResult<ProductSkuRespDTO> getProductSkuResult = productSkuRpc.getProductSku(skuId);
|
||||||
|
getProductSkuResult.checkError();
|
||||||
|
ProductSkuRespDTO skuDTO = getProductSkuResult.getData();
|
||||||
|
if (skuDTO == null || CommonStatusEnum.DISABLE.getValue().equals(skuDTO.getStatus())) {
|
||||||
|
throw ServiceExceptionUtil.exception(CARD_ITEM_SKU_NOT_FOUND);
|
||||||
|
}
|
||||||
|
return skuDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package cn.iocoder.mall.orderservice.manager;
|
|
@ -0,0 +1,28 @@
|
||||||
|
package cn.iocoder.mall.orderservice.rpc.cart;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
|
import cn.iocoder.mall.orderservice.manager.cart.CartManager;
|
||||||
|
import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemAddReqDTO;
|
||||||
|
import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemUpdateQuantityReqDTO;
|
||||||
|
import org.apache.dubbo.config.annotation.DubboService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
@DubboService
|
||||||
|
public class CartRpcImpl implements CartRpc {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CartManager cartManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> addCartItem(CartItemAddReqDTO addItemReqDTO) {
|
||||||
|
cartManager.addCartItem(addItemReqDTO);
|
||||||
|
return CommonResult.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> updateCartItemSelected(CartItemUpdateQuantityReqDTO updateQuantityReqDTO) {
|
||||||
|
cartManager.updateCartItemSelected(updateQuantityReqDTO);
|
||||||
|
return CommonResult.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package cn.iocoder.mall.orderservice.service.cart;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||||
|
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||||
|
import cn.iocoder.mall.orderservice.convert.cart.CartConvert;
|
||||||
|
import cn.iocoder.mall.orderservice.dal.mysql.dataobject.cart.CartItemDO;
|
||||||
|
import cn.iocoder.mall.orderservice.dal.mysql.mapper.cart.CartItemMapper;
|
||||||
|
import cn.iocoder.mall.orderservice.service.cart.bo.CartItemAddBO;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.mall.orderservice.enums.OrderErrorCodeConstants.CARD_ITEM_NOT_FOUND;
|
||||||
|
import static cn.iocoder.mall.orderservice.enums.OrderErrorCodeConstants.CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车 Service
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class CartService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CartItemMapper cartItemMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加商品到购物车
|
||||||
|
*
|
||||||
|
* @param addBO 添加商品信息
|
||||||
|
* @param skuQuantity 商品 SKU 的库存,主要用于库存校验
|
||||||
|
*/
|
||||||
|
public void addCartItem(@Valid CartItemAddBO addBO, Integer skuQuantity) {
|
||||||
|
// 查询 CartItemDO
|
||||||
|
CartItemDO itemDO = cartItemMapper.selectByUserIdAndSkuId(addBO.getUserId(), addBO.getSkuId());
|
||||||
|
// 存在,则进行数量更新
|
||||||
|
if (itemDO != null) {
|
||||||
|
if (addBO.getQuantity() + itemDO.getQuantity() > skuQuantity) {
|
||||||
|
// 校验库存
|
||||||
|
throw ServiceExceptionUtil.exception(CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
cartItemMapper.updateById(new CartItemDO().setId(itemDO.getId()).setSelected(true)
|
||||||
|
.setQuantity(addBO.getQuantity() + itemDO.getQuantity()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 不存在,则进行插入
|
||||||
|
if (addBO.getQuantity() > skuQuantity) {
|
||||||
|
// 校验库存
|
||||||
|
throw ServiceExceptionUtil.exception(CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
cartItemMapper.insert(CartConvert.INSTANCE.convert(addBO).setSelected(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新购物车商品数量
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param skuId 商品 SKU 编号
|
||||||
|
* @param quantity 数量
|
||||||
|
* @param skuQuantity 商品 SKU 的库存,主要用于库存校验
|
||||||
|
*/
|
||||||
|
public void updateCartItemQuantity(Integer userId, Integer skuId, Integer quantity, Integer skuQuantity) {
|
||||||
|
if (quantity > skuQuantity) {
|
||||||
|
// 校验库存
|
||||||
|
throw ServiceExceptionUtil.exception(CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
// 查询 CartItemDO
|
||||||
|
CartItemDO itemDO = cartItemMapper.selectByUserIdAndSkuId(userId, skuId);
|
||||||
|
if (itemDO == null) {
|
||||||
|
throw ServiceExceptionUtil.exception(CARD_ITEM_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 更新数量
|
||||||
|
cartItemMapper.updateById(new CartItemDO().setId(itemDO.getId()).setQuantity(quantity));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新购物车商品是否选中
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param skuIds 商品 SKU 编号数组
|
||||||
|
* @param selected 是否选中
|
||||||
|
*/
|
||||||
|
public void updateCartItemSelected(Integer userId, List<Integer> skuIds, Boolean selected) {
|
||||||
|
// 查询 CartItemDO 列表
|
||||||
|
List<CartItemDO> itemDOs = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds);
|
||||||
|
if (skuIds.size() != itemDOs.size()) {
|
||||||
|
throw ServiceExceptionUtil.exception(CARD_ITEM_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 更新选中
|
||||||
|
cartItemMapper.updateByIds(CollectionUtils.convertSet(itemDOs, CartItemDO::getId),
|
||||||
|
new CartItemDO().setSelected(selected));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车删除商品
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param skuIds 商品 SKU 编号的数组
|
||||||
|
*/
|
||||||
|
public void deleteList(Integer userId, List<Integer> skuIds) {
|
||||||
|
// 查询 CartItemDO 列表
|
||||||
|
List<CartItemDO> itemDOs = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds);
|
||||||
|
// 批量标记删除
|
||||||
|
cartItemMapper.deleteBatchIds(CollectionUtils.convertSet(itemDOs, CartItemDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package cn.iocoder.mall.orderservice.service.cart.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车添加购物项 Request DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors
|
||||||
|
public class CartItemAddBO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Integer userId;
|
||||||
|
/**
|
||||||
|
* 商品 SPU 编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "商品 SPU 编号不能为空")
|
||||||
|
private Integer spuId;
|
||||||
|
/**
|
||||||
|
* 商品 SKU 编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "商品 SKU 编号不能为空")
|
||||||
|
private Integer skuId;
|
||||||
|
/**
|
||||||
|
* 数量
|
||||||
|
*/
|
||||||
|
@NotNull(message = "数量不能为空")
|
||||||
|
@Min(message = "数量必须大于 0", value = 1L)
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
}
|
|
@ -1,17 +1,14 @@
|
||||||
package cn.iocoder.mall.order.biz.dataobject;
|
package cn.iocoder.mall.orderservice.service.cart.bo;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.dataobject.BaseDO;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 购物车的商品信息
|
* 购物车的商品信息 BO
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class CartItemDO extends BaseDO {
|
public class CartItemBO {
|
||||||
|
|
||||||
// ========= 基础字段 BEGIN =========
|
// ========= 基础字段 BEGIN =========
|
||||||
|
|
||||||
|
@ -19,18 +16,6 @@ public class CartItemDO extends BaseDO {
|
||||||
* 编号,唯一自增。
|
* 编号,唯一自增。
|
||||||
*/
|
*/
|
||||||
private Integer id;
|
private Integer id;
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*
|
|
||||||
* 1-正常
|
|
||||||
* 2-主动删除
|
|
||||||
* 3-下单删除
|
|
||||||
*/
|
|
||||||
private Integer status;
|
|
||||||
/**
|
|
||||||
* 商品在购物车中的删除时间
|
|
||||||
*/
|
|
||||||
private Date deleteTime;
|
|
||||||
/**
|
/**
|
||||||
* 是否选中
|
* 是否选中
|
||||||
*/
|
*/
|
||||||
|
@ -62,24 +47,8 @@ public class CartItemDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
private Integer quantity;
|
private Integer quantity;
|
||||||
|
|
||||||
// TODO 冗余字段
|
|
||||||
|
|
||||||
|
|
||||||
// ========= 商品信息 END =========
|
// ========= 商品信息 END =========
|
||||||
|
|
||||||
// ========= 交易信息 BEGIN =========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单编号
|
|
||||||
*/
|
|
||||||
private Integer orderId;
|
|
||||||
/**
|
|
||||||
* 订单创建时间
|
|
||||||
*/
|
|
||||||
private Date orderCreateTime;
|
|
||||||
|
|
||||||
// ========= 交易信息 BEGIN =========
|
|
||||||
|
|
||||||
// ========= 优惠信息 BEGIN =========
|
// ========= 优惠信息 BEGIN =========
|
||||||
|
|
||||||
// /**
|
// /**
|
|
@ -0,0 +1,21 @@
|
||||||
|
spring:
|
||||||
|
# 数据源配置项
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://400-infra.server.iocoder.cn:3306/mall_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: 3WLiVUBEwTbvAfsh
|
||||||
|
# Spring Cloud 配置项
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
# Spring Cloud Nacos Discovery 配置项
|
||||||
|
discovery:
|
||||||
|
server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址
|
||||||
|
namespace: dev # Nacos 命名空间
|
||||||
|
|
||||||
|
# Dubbo 配置项
|
||||||
|
dubbo:
|
||||||
|
# Dubbo 注册中心
|
||||||
|
registry:
|
||||||
|
# address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
|
||||||
|
address: nacos://400-infra.server.iocoder.cn:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
|
@ -0,0 +1,24 @@
|
||||||
|
spring:
|
||||||
|
# 数据源配置项
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://400-infra.server.iocoder.cn:3306/mall_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: 3WLiVUBEwTbvAfsh
|
||||||
|
# Spring Cloud 配置项
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
# Spring Cloud Nacos Discovery 配置项
|
||||||
|
discovery:
|
||||||
|
server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址
|
||||||
|
namespace: dev # Nacos 命名空间
|
||||||
|
|
||||||
|
# Dubbo 配置项
|
||||||
|
dubbo:
|
||||||
|
# Dubbo 注册中心
|
||||||
|
registry:
|
||||||
|
# address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
|
||||||
|
address: nacos://400-infra.server.iocoder.cn:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
||||||
|
# Dubbo 服务提供者的配置
|
||||||
|
provider:
|
||||||
|
tag: ${DUBBO_TAG} # Dubbo 路由分组
|
|
@ -0,0 +1,60 @@
|
||||||
|
spring:
|
||||||
|
# Application 的配置项
|
||||||
|
application:
|
||||||
|
name: order-service
|
||||||
|
# Profile 的配置项
|
||||||
|
profiles:
|
||||||
|
active: local
|
||||||
|
|
||||||
|
# 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.orderservice.dal.mysql.dataobject
|
||||||
|
|
||||||
|
# Dubbo 配置项
|
||||||
|
dubbo:
|
||||||
|
# Spring Cloud Alibaba Dubbo 专属配置
|
||||||
|
cloud:
|
||||||
|
subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用
|
||||||
|
# Dubbo 提供者的协议
|
||||||
|
protocol:
|
||||||
|
name: dubbo
|
||||||
|
port: -1
|
||||||
|
# Dubbo 提供服务的扫描基础包
|
||||||
|
scan:
|
||||||
|
base-packages: cn.iocoder.mall.orderservice.rpc
|
||||||
|
# Dubbo 服务提供者的配置
|
||||||
|
provider:
|
||||||
|
filter: -exception
|
||||||
|
validation: true # 开启 Provider 参数校验
|
||||||
|
version: 1.0.0 # 服务的版本号
|
||||||
|
# Dubbo 服务消费者的配置
|
||||||
|
consumer:
|
||||||
|
ErrorCodeRpc:
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
|
# RocketMQ 配置项
|
||||||
|
rocketmq:
|
||||||
|
name-server: 400-infra.server.iocoder.cn:9876
|
||||||
|
producer:
|
||||||
|
group: ${spring.application.name}-producer-group
|
||||||
|
|
||||||
|
# Actuator 监控配置项
|
||||||
|
management:
|
||||||
|
server.port: 38084 # 独立端口,避免被暴露出去
|
||||||
|
endpoints.web.exposure.include: '*' # 暴露所有监控端点
|
||||||
|
server.port: ${management.server.port} # 设置使用 Actuator 的服务器端口,因为 RPC 服务不需要 Web 端口
|
||||||
|
|
||||||
|
# Mall 配置项
|
||||||
|
mall:
|
||||||
|
# 错误码配置项对应 ErrorCodeProperties 配置类
|
||||||
|
error-code:
|
||||||
|
group: ${spring.application.name}
|
||||||
|
constants-class: cn.iocoder.mall.orderservice.enums.OrderErrorCodeConstants
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?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-service-project</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>order-service-api</module>
|
||||||
|
<module>order-service-app</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<!-- onemall 基础 bom 文件 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>mall-dependencies</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 自身项目 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>order-service-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
</project>
|
|
@ -4,9 +4,6 @@ import cn.iocoder.mall.order.biz.dataobject.CartItemDO;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface CartMapper {
|
public interface CartMapper {
|
||||||
//
|
//
|
||||||
|
|
|
@ -2,55 +2,10 @@ package cn.iocoder.mall.order.biz.service;
|
||||||
|
|
||||||
public interface CartService {
|
public interface CartService {
|
||||||
|
|
||||||
// // ========== 购物车 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);
|
// Boolean deleteList(Integer userId, List<Integer> skuIds);
|
||||||
//
|
//
|
||||||
// /**
|
|
||||||
// * 清空购物车
|
|
||||||
// *
|
|
||||||
// * @param userId 用户编号
|
|
||||||
// * @return 是否成功
|
|
||||||
// */
|
|
||||||
// Boolean deleteAll(Integer userId);
|
|
||||||
//
|
//
|
||||||
// /**
|
// /**
|
||||||
// * 查询用户在购物车中的商品数量
|
// * 查询用户在购物车中的商品数量
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package cn.iocoder.mall.order.api.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单退回 - 不存在
|
|
||||||
*
|
|
||||||
* @author Sin
|
|
||||||
* @time 2019/5/8 6:17 PM
|
|
||||||
*/
|
|
||||||
public class OrderReturnNonExistentException {
|
|
||||||
}
|
|
|
@ -9,7 +9,7 @@
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>order-service-api</artifactId>
|
<artifactId>order-service-api02</artifactId>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Mall 相关 -->
|
<!-- Mall 相关 -->
|
|
@ -1,46 +0,0 @@
|
||||||
package cn.iocoder.mall.order.biz.dao;
|
|
||||||
|
|
||||||
import cn.iocoder.mall.order.biz.dataobject.CartItemDO;
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@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);
|
|
||||||
|
|
||||||
}
|
|
|
@ -45,95 +45,6 @@ public class CartServiceImpl implements CartService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private CartMapper cartMapper;
|
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
|
@Override
|
||||||
public Integer count(Integer userId) {
|
public Integer count(Integer userId) {
|
||||||
return cartMapper.selectQuantitySumByUserIdAndStatus(userId, CartItemStatusEnum.ENABLE.getValue());
|
return cartMapper.selectQuantitySumByUserIdAndStatus(userId, CartItemStatusEnum.ENABLE.getValue());
|
||||||
|
|
|
@ -12,13 +12,11 @@
|
||||||
<artifactId>order</artifactId>
|
<artifactId>order</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<modules>
|
<modules>
|
||||||
<module>order-application</module>
|
<!-- <module>order-biz</module>-->
|
||||||
<module>order-biz</module>
|
<!-- <module>order-biz-api</module>-->
|
||||||
<module>order-biz-api</module>
|
|
||||||
<module>order-rest</module>
|
<module>order-rest</module>
|
||||||
<module>order-rpc</module>
|
<module>order-service-api02</module>
|
||||||
<module>order-rpc-api</module>
|
<module>order-service-impl</module>
|
||||||
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
|
5
pom.xml
5
pom.xml
|
@ -14,14 +14,12 @@
|
||||||
<artifactId>onemall</artifactId>
|
<artifactId>onemall</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<modules>
|
<modules>
|
||||||
<!-- <module>product</module>-->
|
<module>order</module>
|
||||||
<!-- <module>order</module>-->
|
|
||||||
<module>common</module>
|
<module>common</module>
|
||||||
<!-- <module>system</module>-->
|
<!-- <module>system</module>-->
|
||||||
<!-- <module>ops</module>-->
|
<!-- <module>ops</module>-->
|
||||||
<!-- <module>pay</module>-->
|
<!-- <module>pay</module>-->
|
||||||
<!-- <module>promotion</module>-->
|
<!-- <module>promotion</module>-->
|
||||||
<!-- <module>search</module>-->
|
|
||||||
<module>mall-dependencies</module>
|
<module>mall-dependencies</module>
|
||||||
<module>user-service-project</module>
|
<module>user-service-project</module>
|
||||||
<module>user-web-app</module>
|
<module>user-web-app</module>
|
||||||
|
@ -32,6 +30,7 @@
|
||||||
<module>product-service-project</module>
|
<module>product-service-project</module>
|
||||||
<!-- <module>promotion-service-project</module>-->
|
<!-- <module>promotion-service-project</module>-->
|
||||||
<module>search-service-project</module>
|
<module>search-service-project</module>
|
||||||
|
<module>order-service-project</module>
|
||||||
</modules>
|
</modules>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuListQueryBO;
|
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuListQueryBO;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -30,6 +31,7 @@ public class ProductSkuService {
|
||||||
productSkuMapper.insertList(skus);
|
productSkuMapper.insertList(skus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
public void updateProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> skuUpdateBOs) {
|
public void updateProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> skuUpdateBOs) {
|
||||||
List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuIdAndStatus(spuId,
|
List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuIdAndStatus(spuId,
|
||||||
CommonStatusEnum.ENABLE.getValue());
|
CommonStatusEnum.ENABLE.getValue());
|
||||||
|
|
Loading…
Reference in New Issue